{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "agents-kit",
  "homepage": "https://agents-ui.github.io/agents-kit",
  "items": [
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "example-voice-app",
      "type": "registry:block",
      "title": "Example Voice App",
      "description": "Talk and type in the same conversation, with one composer and shared context.",
      "dependencies": [
        "@radix-ui/react-avatar@^1.1.3",
        "@radix-ui/react-slot@^1.2.2",
        "@radix-ui/react-tooltip@^1.2.6",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "lucide-react@0.577.0",
        "marked@^15.0.7",
        "motion@12.26.2",
        "next-themes@^0.4.4",
        "radix-ui@1.6.7",
        "react-aria-components@^1.21.1",
        "react-markdown@^10.1.0",
        "remark-breaks@^4.0.0",
        "remark-gfm@^4.0.1",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6",
        "use-stick-to-bottom@^1.1.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/examples/voice-app.tsx",
          "target": "@components/examples/voice-app.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { ConversationAppExample } from \"./conversation-app\"\n\nexport function VoiceAppExample() {\n  return (\n    <ConversationAppExample\n      initialVoice\n      className=\"h-[760px] overflow-hidden rounded-[14px] border\"\n    />\n  )\n}\n"
        },
        {
          "path": "components/examples/conversation-app.tsx",
          "target": "@components/examples/conversation-app.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  ChatContainerContent,\n  ChatContainerRoot,\n} from \"@/components/prompt-kit/chat-container\"\nimport { Loader } from \"@/components/prompt-kit/loader\"\nimport { Message, MessageContent } from \"@/components/prompt-kit/message\"\nimport {\n  PromptInput,\n  PromptInputAction,\n  PromptInputActions,\n  PromptInputTextarea,\n} from \"@/components/prompt-kit/prompt-input\"\nimport { PromptSuggestion } from \"@/components/prompt-kit/prompt-suggestion\"\nimport { Button } from \"@/components/ui/button\"\nimport { ThemeToggle } from \"@/components/ui/theme-toggle\"\nimport { AgentTrackToggle } from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport { Shdr21 } from \"@/components/voice-agents/orbkit/shdr-21\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  ArrowUp,\n  AudioLines,\n  FileText,\n  Paperclip,\n  Square,\n  X,\n} from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\nimport {\n  researchAnswer,\n  researchProjects,\n  type ResearchNote,\n} from \"./research-workflow\"\n\ntype Turn = {\n  id: number\n  role: \"user\" | \"assistant\"\n  text: string\n  input: \"text\" | \"voice\"\n}\nconst starters = [\n  \"Summarize the dock interviews\",\n  \"What should the team change first?\",\n]\nconst sampleSpokenQuestion = \"What is slowing down the dock handoff?\"\n\n/** Composition of kit components with shared text and voice demo state. */\nexport function ConversationAppExample({\n  initialVoice = false,\n  className,\n}: {\n  initialVoice?: boolean\n  className?: string\n} = {}) {\n  const [voice, setVoice] = useState(initialVoice)\n  const [phase, setPhase] = useState<\"idle\" | \"thinking\" | \"speaking\">(\"idle\")\n  const [draft, setDraft] = useState(\"\")\n  const [turns, setTurns] = useState<Turn[]>([])\n  const [muted, setMuted] = useState(false)\n  const [concise, setConcise] = useState(true)\n  const [attachment, setAttachment] = useState<ResearchNote | null>(null)\n  const [notice, setNotice] = useState(\"\")\n  const sequence = useRef(0)\n  const attachmentVersion = useRef(0)\n  const replyTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n  const settleTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n  const fileInput = useRef<HTMLInputElement>(null)\n  const composer = useRef<HTMLDivElement>(null)\n  const reduce = useReducedMotion()\n  const centered = !voice && turns.length === 0\n  const thinking = phase === \"thinking\"\n\n  const clearTimers = () => {\n    if (replyTimer.current) clearTimeout(replyTimer.current)\n    if (settleTimer.current) clearTimeout(settleTimer.current)\n    replyTimer.current = null\n    settleTimer.current = null\n  }\n  useEffect(() => clearTimers, [])\n\n  const send = (text: string, input: Turn[\"input\"] = \"text\") => {\n    if (!text.trim() || thinking || (input === \"voice\" && muted)) return\n    clearTimers()\n    const answer = researchAnswer(\n      text,\n      attachment ? [attachment] : researchProjects[0].notes,\n      concise\n    )\n    const turn: Turn = {\n      id: ++sequence.current,\n      role: \"user\",\n      text: text.trim(),\n      input,\n    }\n    setTurns((current) => [...current, turn])\n    if (input === \"text\") setDraft(\"\")\n    setNotice(\"\")\n    setPhase(\"thinking\")\n    replyTimer.current = setTimeout(() => {\n      const reply: Turn = {\n        id: ++sequence.current,\n        role: \"assistant\",\n        text: answer,\n        input,\n      }\n      setTurns((current) => [...current, reply])\n      setPhase(\"speaking\")\n      replyTimer.current = null\n      settleTimer.current = setTimeout(() => {\n        setPhase(\"idle\")\n        settleTimer.current = null\n      }, 1800)\n    }, 900)\n  }\n  const toggleVoice = () => {\n    setVoice((current) => !current)\n    setNotice(\"\")\n    requestAnimationFrame(() =>\n      composer.current?.querySelector(\"textarea\")?.focus()\n    )\n  }\n  const stop = () => {\n    clearTimers()\n    setPhase(\"idle\")\n    setNotice(\"Response stopped. You can continue the conversation.\")\n  }\n  const reset = () => {\n    clearTimers()\n    setTurns([])\n    setDraft(\"\")\n    setVoice(initialVoice)\n    setPhase(\"idle\")\n    setMuted(false)\n    setConcise(true)\n    attachmentVersion.current += 1\n    setAttachment(null)\n    setNotice(\"\")\n  }\n  const attach = async (file?: File) => {\n    if (!file) return\n    const version = ++attachmentVersion.current\n    if (!/\\.(txt|md|csv)$/i.test(file.name) || file.size > 64 * 1024) {\n      setNotice(\"Choose a text, Markdown, or CSV note under 64 KB.\")\n      return\n    }\n    try {\n      const text = await file.text()\n      if (version !== attachmentVersion.current) return\n      setAttachment({ id: file.name, title: file.name, text })\n      setNotice(\"\")\n    } catch {\n      if (version === attachmentVersion.current)\n        setNotice(\"That note could not be read. Try another file.\")\n    }\n  }\n  const stateLabel = thinking\n    ? \"Thinking\"\n    : phase === \"speaking\"\n      ? \"Speaking\"\n      : muted\n        ? \"Microphone muted\"\n        : \"Listening\"\n\n  return (\n    <section\n      aria-label=\"Fieldwork conversation\"\n      data-conversation-preview\n      data-app-example={initialVoice ? \"voice\" : \"chat\"}\n      className={cn(\n        \"bg-background text-foreground flex h-dvh min-h-[560px] flex-col\",\n        className\n      )}\n    >\n      <header className=\"border-border flex h-16 shrink-0 items-center justify-between gap-3 border-b px-4 sm:px-8\">\n        <div className=\"min-w-0\">\n          <p className=\"text-sm font-medium\">Fieldwork assistant</p>\n          <p className=\"text-muted-foreground truncate text-xs\">\n            Agents Kit · Conversation example\n          </p>\n        </div>\n        <div className=\"flex shrink-0 items-center gap-2\">\n          <Button\n            variant=\"ghost\"\n            size=\"sm\"\n            onClick={reset}\n            className=\"text-muted-foreground text-xs\"\n          >\n            Reset preview\n          </Button>\n          <ThemeToggle />\n        </div>\n      </header>\n\n      <div className=\"relative mx-auto flex min-h-0 w-full max-w-3xl flex-1 flex-col px-4 sm:px-6\">\n        <ChatContainerRoot data-transcript className=\"min-h-0 flex-1\">\n          <ChatContainerContent className=\"gap-6 px-1 pt-8 pb-8 sm:px-2\">\n            {turns.map((turn) => (\n              <Message\n                key={turn.id}\n                data-turn={turn.id}\n                data-input={turn.input}\n                className={cn(turn.role === \"user\" && \"justify-end\")}\n              >\n                <div\n                  className={cn(\n                    \"min-w-0\",\n                    turn.role === \"user\" ? \"max-w-[90%]\" : \"w-full\"\n                  )}\n                >\n                  <p className=\"text-muted-foreground mb-1.5 flex items-center gap-1.5 text-xs\">\n                    {turn.role === \"user\" ? \"You\" : \"Fieldwork assistant\"}\n                    {turn.input === \"voice\" && turn.role === \"user\" && (\n                      <>\n                        <AudioLines className=\"size-3\" aria-hidden />\n                        Voice\n                      </>\n                    )}\n                  </p>\n                  <MessageContent\n                    className={cn(\n                      \"max-w-none text-sm leading-6 whitespace-pre-wrap\",\n                      turn.role === \"assistant\"\n                        ? \"bg-transparent p-0\"\n                        : \"px-3 py-2.5\"\n                    )}\n                  >\n                    {turn.text}\n                  </MessageContent>\n                </div>\n              </Message>\n            ))}\n            {thinking && (\n              <div\n                role=\"status\"\n                className=\"text-muted-foreground flex items-center gap-2 text-xs\"\n              >\n                <Loader variant=\"typing\" size=\"sm\" />\n                Reading the notes…\n              </div>\n            )}\n          </ChatContainerContent>\n        </ChatContainerRoot>\n\n        <motion.div\n          ref={composer}\n          layout=\"position\"\n          data-composer-position\n          transition={{ duration: reduce ? 0 : 0.3, ease: [0.2, 0, 0, 1] }}\n          className={cn(\n            \"relative w-full shrink-0 pb-4\",\n            centered && \"absolute inset-x-0 bottom-[38%] px-4 sm:px-6\"\n          )}\n        >\n          {centered && (\n            <div className=\"mb-6\">\n              <h1 className=\"text-2xl leading-8 font-normal tracking-tight\">\n                Work with your field notes\n              </h1>\n              <p className=\"text-muted-foreground mt-2 text-sm\">\n                Ask a question, talk it through, or add a source.\n              </p>\n            </div>\n          )}\n          <AnimatePresence initial={false}>\n            {voice && (\n              <motion.div\n                key=\"voice\"\n                initial={{ opacity: 0, y: reduce ? 0 : 6 }}\n                animate={{ opacity: 1, y: 0 }}\n                exit={{ opacity: 0 }}\n                transition={{ duration: reduce ? 0 : 0.15 }}\n                className=\"mb-4 flex items-center gap-4 px-1\"\n              >\n                <div data-voice-orb className=\"size-20 shrink-0\">\n                  <Shdr21\n                    size={80}\n                    state={phase}\n                    maxDpr={2}\n                    pauseOffscreen\n                    ariaLabel={`${stateLabel} voice orb`}\n                  />\n                </div>\n                <div className=\"min-w-0\">\n                  <p role=\"status\" className=\"text-sm font-medium\">\n                    {stateLabel}\n                  </p>\n                  <p className=\"text-muted-foreground mt-1 text-xs leading-5\">\n                    Voice and typing share this conversation.\n                  </p>\n                </div>\n              </motion.div>\n            )}\n          </AnimatePresence>\n\n          <PromptInput\n            data-composer\n            value={draft}\n            onValueChange={setDraft}\n            onSubmit={() => send(draft)}\n            isLoading={thinking}\n            maxHeight={144}\n            className=\"bg-card focus-within:ring-ring rounded-xl p-2 focus-within:ring-1\"\n          >\n            {attachment && (\n              <div className=\"bg-secondary mb-2 flex w-fit max-w-full items-center gap-2 rounded-md px-2 py-1 text-xs\">\n                <FileText className=\"size-3.5 shrink-0\" aria-hidden />\n                <span className=\"truncate\">{attachment.title}</span>\n                <Button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  className=\"size-6\"\n                  aria-label=\"Remove context note\"\n                  onClick={() => {\n                    attachmentVersion.current += 1\n                    setAttachment(null)\n                  }}\n                >\n                  <X className=\"size-3\" />\n                </Button>\n              </div>\n            )}\n            <PromptInputTextarea\n              data-conversation-input\n              aria-label=\"Message\"\n              placeholder={\n                voice\n                  ? \"Keep typing while voice is on…\"\n                  : \"Ask about your field notes…\"\n              }\n              className=\"min-h-12 px-2 py-2 text-base sm:text-sm\"\n            />\n            <PromptInputActions className=\"justify-between gap-2 pt-1\">\n              <div className=\"flex min-w-0 items-center gap-1\">\n                <PromptInputAction tooltip=\"Add a text, Markdown, or CSV note\">\n                  <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    aria-label=\"Add context note\"\n                    onClick={() => fileInput.current?.click()}\n                  >\n                    <Paperclip />\n                  </Button>\n                </PromptInputAction>\n                <PromptInputAction\n                  tooltip={\n                    concise ? \"Use a detailed answer\" : \"Use a concise answer\"\n                  }\n                >\n                  <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    aria-label=\"Concise answers\"\n                    aria-pressed={concise}\n                    onClick={() => setConcise((value) => !value)}\n                    className=\"text-muted-foreground text-xs\"\n                  >\n                    {concise ? \"Concise\" : \"Detailed\"}\n                  </Button>\n                </PromptInputAction>\n              </div>\n              <div className=\"flex shrink-0 items-center gap-2\">\n                {voice && (\n                  <PromptInputAction\n                    tooltip={muted ? \"Unmute microphone\" : \"Mute microphone\"}\n                  >\n                    <AgentTrackToggle\n                      source=\"microphone\"\n                      pressed={!muted}\n                      onPressedChange={(enabled) => setMuted(!enabled)}\n                      aria-label={\n                        muted ? \"Unmute microphone\" : \"Mute microphone\"\n                      }\n                    />\n                  </PromptInputAction>\n                )}\n                <PromptInputAction\n                  tooltip={voice ? \"Return to typing\" : \"Start voice mode\"}\n                >\n                  <Button\n                    type=\"button\"\n                    variant={voice ? \"secondary\" : \"outline\"}\n                    size=\"icon\"\n                    aria-label={voice ? \"Exit voice mode\" : \"Enter voice mode\"}\n                    onClick={toggleVoice}\n                  >\n                    {voice ? <X /> : <AudioLines />}\n                  </Button>\n                </PromptInputAction>\n                <PromptInputAction\n                  tooltip={thinking ? \"Stop response\" : \"Send message\"}\n                >\n                  <Button\n                    type=\"button\"\n                    size=\"icon\"\n                    disabled={!thinking && !draft.trim()}\n                    aria-label={thinking ? \"Stop response\" : \"Send message\"}\n                    onClick={thinking ? stop : () => send(draft)}\n                  >\n                    {thinking ? (\n                      <Square className=\"size-3.5 fill-current\" />\n                    ) : (\n                      <ArrowUp />\n                    )}\n                  </Button>\n                </PromptInputAction>\n              </div>\n            </PromptInputActions>\n          </PromptInput>\n          <input\n            ref={fileInput}\n            type=\"file\"\n            accept=\".txt,.md,.csv\"\n            className=\"sr-only\"\n            aria-label=\"Context note file\"\n            onChange={(event) => {\n              void attach(event.currentTarget.files?.[0])\n              event.currentTarget.value = \"\"\n            }}\n          />\n          {notice && (\n            <p role=\"status\" className=\"text-muted-foreground mt-3 text-xs\">\n              {notice}\n            </p>\n          )}\n          {centered && (\n            <div className=\"mt-4 flex flex-wrap gap-2\">\n              {starters.map((text) => (\n                <PromptSuggestion\n                  key={text}\n                  size=\"sm\"\n                  className=\"h-auto min-h-8 rounded-lg text-xs font-normal whitespace-normal\"\n                  onClick={() => send(text)}\n                >\n                  {text}\n                </PromptSuggestion>\n              ))}\n            </div>\n          )}\n          {voice && (\n            <div className=\"mt-3 flex justify-end\">\n              <Button\n                variant=\"link\"\n                size=\"sm\"\n                disabled={muted || thinking}\n                onClick={() => send(sampleSpokenQuestion, \"voice\")}\n                className=\"text-muted-foreground h-7 px-0 text-xs\"\n              >\n                Try a sample voice turn\n              </Button>\n            </div>\n          )}\n        </motion.div>\n      </div>\n      <footer className=\"text-muted-foreground border-border flex shrink-0 flex-wrap items-center justify-between gap-2 border-t px-4 py-3 text-[11px] sm:px-8\">\n        <span>Interactive demo · sample replies · no microphone recording</span>\n        <details className=\"relative\">\n          <summary className=\"cursor-pointer\">Components used</summary>\n          <div className=\"bg-popover text-popover-foreground absolute right-0 bottom-full z-20 mb-3 w-64 rounded-lg border p-4 text-xs shadow-sm\">\n            <p className=\"mb-2 font-medium\">Composed from Agents Kit</p>\n            <ul className=\"space-y-2\">\n              <li>\n                Prompt Kit: input, messages, scrolling, suggestions, loader\n              </li>\n              <li>LiveKit: microphone toggle</li>\n              <li>OrbKit: Nimbus</li>\n              <li>Shared buttons and theme tokens</li>\n            </ul>\n          </div>\n        </details>\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/prompt-kit/chat-container.tsx",
          "target": "@components/prompt-kit/chat-container.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { StickToBottom } from \"use-stick-to-bottom\"\n\nexport type ChatContainerRootProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport type ChatContainerContentProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport type ChatContainerScrollAnchorProps = {\n  className?: string\n  ref?: React.RefObject<HTMLDivElement>\n} & React.HTMLAttributes<HTMLDivElement>\n\nfunction ChatContainerRoot({\n  children,\n  className,\n  ...props\n}: ChatContainerRootProps) {\n  return (\n    <StickToBottom\n      className={cn(\"flex overflow-y-auto\", className)}\n      resize=\"smooth\"\n      initial=\"instant\"\n      role=\"log\"\n      {...props}\n    >\n      {children}\n    </StickToBottom>\n  )\n}\n\nfunction ChatContainerContent({\n  children,\n  className,\n  ...props\n}: ChatContainerContentProps) {\n  return (\n    <StickToBottom.Content\n      className={cn(\"flex w-full flex-col\", className)}\n      {...props}\n    >\n      {children}\n    </StickToBottom.Content>\n  )\n}\n\nfunction ChatContainerScrollAnchor({\n  className,\n  ...props\n}: ChatContainerScrollAnchorProps) {\n  return (\n    <div\n      className={cn(\"h-px w-full shrink-0 scroll-mt-4\", className)}\n      aria-hidden=\"true\"\n      {...props}\n    />\n  )\n}\n\nexport { ChatContainerRoot, ChatContainerContent, ChatContainerScrollAnchor }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/prompt-kit/loader.tsx",
          "target": "@components/prompt-kit/loader.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React from \"react\"\n\nexport interface LoaderProps {\n  variant?:\n    | \"circular\"\n    | \"classic\"\n    | \"pulse\"\n    | \"pulse-dot\"\n    | \"dots\"\n    | \"typing\"\n    | \"wave\"\n    | \"bars\"\n    | \"terminal\"\n    | \"text-blink\"\n    | \"text-shimmer\"\n    | \"loading-dots\"\n  size?: \"sm\" | \"md\" | \"lg\"\n  text?: string\n  className?: string\n}\n\nexport function CircularLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"border-primary animate-spin rounded-full border-2 border-t-transparent\",\n        sizeClasses[size],\n        className\n      )}\n    >\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function ClassicLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  const barSizes = {\n    sm: { height: \"6px\", width: \"1.5px\" },\n    md: { height: \"8px\", width: \"2px\" },\n    lg: { height: \"10px\", width: \"2.5px\" },\n  }\n\n  return (\n    <div className={cn(\"relative\", sizeClasses[size], className)}>\n      <div className=\"absolute h-full w-full\">\n        {[...Array(12)].map((_, i) => (\n          <div\n            key={i}\n            className=\"bg-primary absolute animate-[spinner-fade_1.2s_linear_infinite] rounded-full\"\n            style={{\n              top: \"0\",\n              left: \"50%\",\n              marginLeft:\n                size === \"sm\" ? \"-0.75px\" : size === \"lg\" ? \"-1.25px\" : \"-1px\",\n              transformOrigin: `${size === \"sm\" ? \"0.75px\" : size === \"lg\" ? \"1.25px\" : \"1px\"} ${size === \"sm\" ? \"10px\" : size === \"lg\" ? \"14px\" : \"12px\"}`,\n              transform: `rotate(${i * 30}deg)`,\n              opacity: 0,\n              animationDelay: `${i * 0.1}s`,\n              height: barSizes[size].height,\n              width: barSizes[size].width,\n            }}\n          />\n        ))}\n      </div>\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function PulseLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  return (\n    <div className={cn(\"relative\", sizeClasses[size], className)}>\n      <div className=\"border-primary absolute inset-0 animate-[thin-pulse_1.5s_ease-in-out_infinite] rounded-full border-2\" />\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function PulseDotLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-1\",\n    md: \"size-2\",\n    lg: \"size-3\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"bg-primary animate-[pulse-dot_1.2s_ease-in-out_infinite] rounded-full\",\n        sizeClasses[size],\n        className\n      )}\n    >\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function DotsLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const dotSizes = {\n    sm: \"h-1.5 w-1.5\",\n    md: \"h-2 w-2\",\n    lg: \"h-2.5 w-2.5\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[bounce-dots_1.4s_ease-in-out_infinite] rounded-full\",\n            dotSizes[size]\n          )}\n          style={{\n            animationDelay: `${i * 160}ms`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TypingLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const dotSizes = {\n    sm: \"h-1 w-1\",\n    md: \"h-1.5 w-1.5\",\n    lg: \"h-2 w-2\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[typing_1s_infinite] rounded-full\",\n            dotSizes[size]\n          )}\n          style={{\n            animationDelay: `${i * 250}ms`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function WaveLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const barWidths = {\n    sm: \"w-0.5\",\n    md: \"w-0.5\",\n    lg: \"w-1\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  const heights = {\n    sm: [\"6px\", \"9px\", \"12px\", \"9px\", \"6px\"],\n    md: [\"8px\", \"12px\", \"16px\", \"12px\", \"8px\"],\n    lg: [\"10px\", \"15px\", \"20px\", \"15px\", \"10px\"],\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center gap-0.5\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(5)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[wave_1s_ease-in-out_infinite] rounded-full\",\n            barWidths[size]\n          )}\n          style={{\n            animationDelay: `${i * 100}ms`,\n            height: heights[size][i],\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function BarsLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const barWidths = {\n    sm: \"w-1\",\n    md: \"w-1.5\",\n    lg: \"w-2\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4 gap-1\",\n    md: \"h-5 gap-1.5\",\n    lg: \"h-6 gap-2\",\n  }\n\n  return (\n    <div className={cn(\"flex\", containerSizes[size], className)}>\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary h-full animate-[wave-bars_1.2s_ease-in-out_infinite]\",\n            barWidths[size]\n          )}\n          style={{\n            animationDelay: `${i * 0.2}s`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TerminalLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const cursorSizes = {\n    sm: \"h-3 w-1.5\",\n    md: \"h-4 w-2\",\n    lg: \"h-5 w-2.5\",\n  }\n\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      <span className={cn(\"text-primary font-mono\", textSizes[size])}>\n        {\">\"}\n      </span>\n      <div\n        className={cn(\n          \"bg-primary animate-[blink_1s_step-end_infinite]\",\n          cursorSizes[size]\n        )}\n      />\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TextBlinkLoader({\n  text = \"Thinking\",\n  className,\n  size = \"md\",\n}: {\n  text?: string\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"animate-[text-blink_2s_ease-in-out_infinite] font-medium\",\n        textSizes[size],\n        className\n      )}\n    >\n      {text}\n    </div>\n  )\n}\n\nexport function TextShimmerLoader({\n  text = \"Thinking\",\n  className,\n  size = \"md\",\n}: {\n  text?: string\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"bg-[linear-gradient(to_right,var(--muted-foreground)_40%,var(--foreground)_60%,var(--muted-foreground)_80%)]\",\n        \"bg-size-[200%_auto] bg-clip-text font-medium text-transparent\",\n        \"animate-[shimmer_4s_infinite_linear]\",\n        textSizes[size],\n        className\n      )}\n    >\n      {text}\n    </div>\n  )\n}\n\nexport function TextDotsLoader({\n  className,\n  text = \"Thinking\",\n  size = \"md\",\n}: {\n  className?: string\n  text?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\"inline-flex items-center\", className)}\n    >\n      <span className={cn(\"text-primary font-medium\", textSizes[size])}>\n        {text}\n      </span>\n      <span className=\"inline-flex\">\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.2s]\">\n          .\n        </span>\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.4s]\">\n          .\n        </span>\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.6s]\">\n          .\n        </span>\n      </span>\n    </div>\n  )\n}\n\nfunction Loader({\n  variant = \"circular\",\n  size = \"md\",\n  text,\n  className,\n}: LoaderProps) {\n  switch (variant) {\n    case \"circular\":\n      return <CircularLoader size={size} className={className} />\n    case \"classic\":\n      return <ClassicLoader size={size} className={className} />\n    case \"pulse\":\n      return <PulseLoader size={size} className={className} />\n    case \"pulse-dot\":\n      return <PulseDotLoader size={size} className={className} />\n    case \"dots\":\n      return <DotsLoader size={size} className={className} />\n    case \"typing\":\n      return <TypingLoader size={size} className={className} />\n    case \"wave\":\n      return <WaveLoader size={size} className={className} />\n    case \"bars\":\n      return <BarsLoader size={size} className={className} />\n    case \"terminal\":\n      return <TerminalLoader size={size} className={className} />\n    case \"text-blink\":\n      return <TextBlinkLoader text={text} size={size} className={className} />\n    case \"text-shimmer\":\n      return <TextShimmerLoader text={text} size={size} className={className} />\n    case \"loading-dots\":\n      return <TextDotsLoader text={text} size={size} className={className} />\n    default:\n      return <CircularLoader size={size} className={className} />\n  }\n}\n\nexport { Loader }\n"
        },
        {
          "path": "components/prompt-kit/message.tsx",
          "target": "@components/prompt-kit/message.tsx",
          "type": "registry:component",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport { Markdown } from \"./markdown\"\n\nexport type MessageProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nconst Message = ({ children, className, ...props }: MessageProps) => (\n  <div className={cn(\"flex gap-3\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type MessageAvatarProps = {\n  src: string\n  alt: string\n  fallback?: string\n  delayMs?: number\n  className?: string\n}\n\nconst MessageAvatar = ({\n  src,\n  alt,\n  fallback,\n  delayMs,\n  className,\n}: MessageAvatarProps) => {\n  return (\n    <Avatar className={cn(\"h-8 w-8 shrink-0\", className)}>\n      <AvatarImage src={src} alt={alt} />\n      {fallback && (\n        <AvatarFallback delayMs={delayMs}>{fallback}</AvatarFallback>\n      )}\n    </Avatar>\n  )\n}\n\nexport type MessageContentProps = {\n  children: React.ReactNode\n  markdown?: boolean\n  className?: string\n} & React.ComponentProps<typeof Markdown> &\n  React.HTMLProps<HTMLDivElement>\n\nconst MessageContent = ({\n  children,\n  markdown = false,\n  className,\n  ...props\n}: MessageContentProps) => {\n  const classNames = cn(\n    \"prose prose-sm dark:prose-invert rounded-lg bg-secondary p-2 text-foreground break-words whitespace-normal\",\n    className\n  )\n\n  return markdown ? (\n    <Markdown className={classNames} {...props}>\n      {children as string}\n    </Markdown>\n  ) : (\n    <div className={classNames} {...props}>\n      {children}\n    </div>\n  )\n}\n\nexport type MessageActionsProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nconst MessageActions = ({\n  children,\n  className,\n  ...props\n}: MessageActionsProps) => (\n  <div\n    className={cn(\"text-muted-foreground flex items-center gap-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type MessageActionProps = {\n  className?: string\n  tooltip: React.ReactNode\n  children: React.ReactNode\n  side?: \"top\" | \"bottom\" | \"left\" | \"right\"\n} & React.ComponentProps<typeof Tooltip>\n\nconst MessageAction = ({\n  tooltip,\n  children,\n  className,\n  side = \"top\",\n  ...props\n}: MessageActionProps) => {\n  return (\n    <TooltipProvider>\n      <Tooltip {...props}>\n        <TooltipTrigger asChild>{children}</TooltipTrigger>\n        <TooltipContent side={side} className={className}>\n          {tooltip}\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n\nexport { Message, MessageAvatar, MessageContent, MessageActions, MessageAction }\n"
        },
        {
          "path": "components/ui/avatar.tsx",
          "target": "@components/ui/avatar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Avatar({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n  return (\n    <AvatarPrimitive.Root\n      data-slot=\"avatar\"\n      className={cn(\n        \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarImage({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n  return (\n    <AvatarPrimitive.Image\n      data-slot=\"avatar-image\"\n      className={cn(\"aspect-square size-full\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarFallback({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n  return (\n    <AvatarPrimitive.Fallback\n      data-slot=\"avatar-fallback\"\n      className={cn(\n        \"bg-muted flex size-full items-center justify-center rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Avatar, AvatarImage, AvatarFallback }\n"
        },
        {
          "path": "components/ui/tooltip.tsx",
          "target": "@components/ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 4,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-gray-900 text-gray-50 dark:bg-gray-50 dark:text-gray-900 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-w-sm rounded-md px-3 py-1.5 text-xs\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"fill-gray-900 dark:fill-gray-50 z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "components/prompt-kit/markdown.tsx",
          "target": "@components/prompt-kit/markdown.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { marked } from \"marked\"\nimport { memo, useId, useMemo } from \"react\"\nimport ReactMarkdown, { Components } from \"react-markdown\"\nimport remarkBreaks from \"remark-breaks\"\nimport remarkGfm from \"remark-gfm\"\nimport { CodeBlock, CodeBlockCode } from \"./code-block\"\n\nexport type MarkdownProps = {\n  children: string\n  id?: string\n  className?: string\n  components?: Partial<Components>\n}\n\nfunction parseMarkdownIntoBlocks(markdown: string): string[] {\n  const tokens = marked.lexer(markdown)\n  return tokens.map((token) => token.raw)\n}\n\nfunction extractLanguage(className?: string): string {\n  if (!className) return \"plaintext\"\n  const match = className.match(/language-(\\w+)/)\n  return match ? match[1] : \"plaintext\"\n}\n\nconst INITIAL_COMPONENTS: Partial<Components> = {\n  code: function CodeComponent({ className, children, ...props }) {\n    const isInline =\n      !props.node?.position?.start.line ||\n      props.node?.position?.start.line === props.node?.position?.end.line\n\n    if (isInline) {\n      return (\n        <span\n          className={cn(\n            \"bg-primary-foreground rounded-sm px-1 font-mono text-sm\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </span>\n      )\n    }\n\n    const language = extractLanguage(className)\n\n    return (\n      <CodeBlock className={className}>\n        <CodeBlockCode code={children as string} language={language} />\n      </CodeBlock>\n    )\n  },\n  pre: function PreComponent({ children }) {\n    return <>{children}</>\n  },\n}\n\nconst MemoizedMarkdownBlock = memo(\n  function MarkdownBlock({\n    content,\n    components = INITIAL_COMPONENTS,\n  }: {\n    content: string\n    components?: Partial<Components>\n  }) {\n    return (\n      <ReactMarkdown\n        remarkPlugins={[remarkGfm, remarkBreaks]}\n        components={components}\n      >\n        {content}\n      </ReactMarkdown>\n    )\n  },\n  function propsAreEqual(prevProps, nextProps) {\n    return prevProps.content === nextProps.content\n  }\n)\n\nMemoizedMarkdownBlock.displayName = \"MemoizedMarkdownBlock\"\n\nfunction MarkdownComponent({\n  children,\n  id,\n  className,\n  components = INITIAL_COMPONENTS,\n}: MarkdownProps) {\n  const generatedId = useId()\n  const blockId = id ?? generatedId\n  const blocks = useMemo(() => parseMarkdownIntoBlocks(children), [children])\n\n  return (\n    <div className={className}>\n      {blocks.map((block, index) => (\n        <MemoizedMarkdownBlock\n          key={`${blockId}-block-${index}`}\n          content={block}\n          components={components}\n        />\n      ))}\n    </div>\n  )\n}\n\nconst Markdown = memo(MarkdownComponent)\nMarkdown.displayName = \"Markdown\"\n\nexport { Markdown }\n"
        },
        {
          "path": "components/prompt-kit/code-block.tsx",
          "target": "@components/prompt-kit/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React, { useEffect, useState } from \"react\"\nimport { codeToHtml } from \"shiki\"\n\nexport type CodeBlockProps = {\n  children?: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlock({ children, className, ...props }: CodeBlockProps) {\n  return (\n    <div\n      className={cn(\n        \"not-prose flex w-full flex-col overflow-clip border\",\n        \"border-border bg-card text-card-foreground rounded-xl\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type CodeBlockCodeProps = {\n  code: string\n  language?: string\n  theme?: string\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlockCode({\n  code,\n  language = \"tsx\",\n  theme = \"github-light\",\n  className,\n  ...props\n}: CodeBlockCodeProps) {\n  const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)\n\n  useEffect(() => {\n    async function highlight() {\n      if (!code) {\n        setHighlightedHtml(\"<pre><code></code></pre>\")\n        return\n      }\n\n      const html = await codeToHtml(code, { lang: language, theme })\n      setHighlightedHtml(html)\n    }\n    highlight()\n  }, [code, language, theme])\n\n  const classNames = cn(\n    \"w-full overflow-x-auto text-[13px] [&>pre]:px-4 [&>pre]:py-4\",\n    className\n  )\n\n  // SSR fallback: render plain code if not hydrated yet\n  return highlightedHtml ? (\n    <div\n      data-code-theme={theme}\n      className={classNames}\n      dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n      {...props}\n    />\n  ) : (\n    <div data-code-theme={theme} className={classNames} {...props}>\n      <pre>\n        <code>{code}</code>\n      </pre>\n    </div>\n  )\n}\n\nexport type CodeBlockGroupProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction CodeBlockGroup({\n  children,\n  className,\n  ...props\n}: CodeBlockGroupProps) {\n  return (\n    <div\n      className={cn(\"flex items-center justify-between\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport { CodeBlockGroup, CodeBlockCode, CodeBlock }\n"
        },
        {
          "path": "components/prompt-kit/prompt-input.tsx",
          "target": "@components/prompt-kit/prompt-input.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Textarea } from \"@/components/ui/textarea\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport React, {\n  createContext,\n  useContext,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\"\n\ntype PromptInputContextType = {\n  isLoading: boolean\n  value: string\n  setValue: (value: string) => void\n  maxHeight: number | string\n  onSubmit?: () => void\n  disabled?: boolean\n  textareaRef: React.RefObject<HTMLTextAreaElement | null>\n}\n\nconst PromptInputContext = createContext<PromptInputContextType>({\n  isLoading: false,\n  value: \"\",\n  setValue: () => {},\n  maxHeight: 240,\n  onSubmit: undefined,\n  disabled: false,\n  textareaRef: React.createRef<HTMLTextAreaElement>(),\n})\n\nfunction usePromptInput() {\n  return useContext(PromptInputContext)\n}\n\nexport type PromptInputProps = {\n  isLoading?: boolean\n  value?: string\n  onValueChange?: (value: string) => void\n  maxHeight?: number | string\n  onSubmit?: () => void\n  children: React.ReactNode\n  className?: string\n  disabled?: boolean\n} & React.ComponentProps<\"div\">\n\nfunction PromptInput({\n  className,\n  isLoading = false,\n  maxHeight = 240,\n  value,\n  onValueChange,\n  onSubmit,\n  children,\n  disabled = false,\n  onClick,\n  ...props\n}: PromptInputProps) {\n  const [internalValue, setInternalValue] = useState(value || \"\")\n  const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n  const handleChange = (newValue: string) => {\n    setInternalValue(newValue)\n    onValueChange?.(newValue)\n  }\n\n  const handleClick: React.MouseEventHandler<HTMLDivElement> = (event) => {\n    if (!disabled) textareaRef.current?.focus()\n    onClick?.(event)\n  }\n\n  return (\n    <TooltipProvider>\n      <PromptInputContext.Provider\n        value={{\n          isLoading,\n          value: value ?? internalValue,\n          setValue: onValueChange ?? handleChange,\n          maxHeight,\n          onSubmit,\n          disabled,\n          textareaRef,\n        }}\n      >\n        <div\n          onClick={handleClick}\n          className={cn(\n            \"border-input bg-background cursor-text rounded-3xl border p-2 shadow-xs\",\n            disabled && \"cursor-not-allowed opacity-60\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </div>\n      </PromptInputContext.Provider>\n    </TooltipProvider>\n  )\n}\n\nexport type PromptInputTextareaProps = {\n  disableAutosize?: boolean\n} & React.ComponentProps<typeof Textarea>\n\nfunction PromptInputTextarea({\n  className,\n  onKeyDown,\n  disableAutosize = false,\n  ...props\n}: PromptInputTextareaProps) {\n  const { value, setValue, maxHeight, onSubmit, disabled, textareaRef } =\n    usePromptInput()\n\n  const adjustHeight = (element: HTMLTextAreaElement | null) => {\n    if (!element || disableAutosize) return\n    element.style.height = \"auto\"\n    element.style.height =\n      typeof maxHeight === \"number\"\n        ? `${Math.min(element.scrollHeight, maxHeight)}px`\n        : `min(${element.scrollHeight}px, ${maxHeight})`\n  }\n\n  const handleRef = (element: HTMLTextAreaElement | null) => {\n    textareaRef.current = element\n    adjustHeight(element)\n  }\n\n  useLayoutEffect(() => {\n    adjustHeight(textareaRef.current)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [value, maxHeight, disableAutosize])\n\n  const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n    adjustHeight(event.target)\n    setValue(event.target.value)\n  }\n\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n      e.preventDefault()\n      onSubmit?.()\n    }\n    onKeyDown?.(e)\n  }\n\n  return (\n    <Textarea\n      ref={handleRef}\n      value={value}\n      onChange={handleChange}\n      onKeyDown={handleKeyDown}\n      className={cn(\n        \"text-primary min-h-[44px] w-full resize-none border-none bg-transparent shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0\",\n        className\n      )}\n      rows={1}\n      disabled={disabled}\n      {...props}\n    />\n  )\n}\n\nexport type PromptInputActionsProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction PromptInputActions({\n  children,\n  className,\n  ...props\n}: PromptInputActionsProps) {\n  return (\n    <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n      {children}\n    </div>\n  )\n}\n\nexport type PromptInputActionProps = {\n  className?: string\n  tooltip: React.ReactNode\n  children: React.ReactNode\n  side?: \"top\" | \"bottom\" | \"left\" | \"right\"\n} & React.ComponentProps<typeof Tooltip>\n\nfunction PromptInputAction({\n  tooltip,\n  children,\n  className,\n  side = \"top\",\n  ...props\n}: PromptInputActionProps) {\n  const { disabled } = usePromptInput()\n\n  return (\n    <Tooltip {...props}>\n      <TooltipTrigger\n        asChild\n        disabled={disabled}\n        onClick={(event) => event.stopPropagation()}\n      >\n        {children}\n      </TooltipTrigger>\n      <TooltipContent side={side} className={className}>\n        {tooltip}\n      </TooltipContent>\n    </Tooltip>\n  )\n}\n\nexport {\n  PromptInput,\n  PromptInputTextarea,\n  PromptInputActions,\n  PromptInputAction,\n}\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "components/prompt-kit/prompt-suggestion.tsx",
          "target": "@components/prompt-kit/prompt-suggestion.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { VariantProps } from \"class-variance-authority\"\n\nexport type PromptSuggestionProps = {\n  children: React.ReactNode\n  variant?: VariantProps<typeof buttonVariants>[\"variant\"]\n  size?: VariantProps<typeof buttonVariants>[\"size\"]\n  className?: string\n  highlight?: string\n} & React.ButtonHTMLAttributes<HTMLButtonElement>\n\nfunction PromptSuggestion({\n  children,\n  variant,\n  size,\n  className,\n  highlight,\n  ...props\n}: PromptSuggestionProps) {\n  const isHighlightMode = highlight !== undefined && highlight.trim() !== \"\"\n  const content = typeof children === \"string\" ? children : \"\"\n\n  if (!isHighlightMode) {\n    return (\n      <Button\n        variant={variant || \"outline\"}\n        size={size || \"lg\"}\n        className={cn(\"rounded-full\", className)}\n        {...props}\n      >\n        {children}\n      </Button>\n    )\n  }\n\n  if (!content) {\n    return (\n      <Button\n        variant={variant || \"ghost\"}\n        size={size || \"sm\"}\n        className={cn(\n          \"w-full cursor-pointer justify-start rounded-xl py-2\",\n          \"hover:bg-accent\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n      </Button>\n    )\n  }\n\n  const trimmedHighlight = highlight.trim()\n  const contentLower = content.toLowerCase()\n  const highlightLower = trimmedHighlight.toLowerCase()\n  const shouldHighlight = contentLower.includes(highlightLower)\n\n  return (\n    <Button\n      variant={variant || \"ghost\"}\n      size={size || \"sm\"}\n      className={cn(\n        \"w-full cursor-pointer justify-start gap-0 rounded-xl py-2\",\n        \"hover:bg-accent\",\n        className\n      )}\n      {...props}\n    >\n      {shouldHighlight ? (\n        (() => {\n          const index = contentLower.indexOf(highlightLower)\n          if (index === -1)\n            return (\n              <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                {content}\n              </span>\n            )\n\n          const actualHighlightedText = content.substring(\n            index,\n            index + highlightLower.length\n          )\n\n          const before = content.substring(0, index)\n          const after = content.substring(index + actualHighlightedText.length)\n\n          return (\n            <>\n              {before && (\n                <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                  {before}\n                </span>\n              )}\n              <span className=\"text-primary font-medium whitespace-pre-wrap\">\n                {actualHighlightedText}\n              </span>\n              {after && (\n                <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                  {after}\n                </span>\n              )}\n            </>\n          )\n        })()\n      ) : (\n        <span className=\"text-muted-foreground whitespace-pre-wrap\">\n          {content}\n        </span>\n      )}\n    </Button>\n  )\n}\n\nexport { PromptSuggestion }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ui/theme-toggle.tsx",
          "target": "@components/ui/theme-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Moon, Sun } from \"lucide-react\"\nimport { useTheme } from \"next-themes\"\nimport { useEffect, useState } from \"react\"\n\nexport function ThemeToggle() {\n  const { resolvedTheme, setTheme } = useTheme()\n  const [mounted, setMounted] = useState(false)\n  useEffect(() => setMounted(true), [])\n  if (!mounted) return <span aria-hidden className=\"inline-block size-8\" />\n  const dark = resolvedTheme === \"dark\"\n  return (\n    <Button\n      variant=\"ghost\"\n      size=\"small\"\n      iconOnly\n      leadingIcon={dark ? Sun : Moon}\n      aria-label={dark ? \"Use light theme\" : \"Use dark theme\"}\n      onClick={() => setTheme(dark ? \"light\" : \"dark\")}\n    />\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-toggle.tsx",
          "target": "@components/voice-agents/livekit/agent-track-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Track } from \"livekit-client\"\nimport {\n  LoaderIcon,\n  MicIcon,\n  MicOffIcon,\n  MonitorOffIcon,\n  MonitorUpIcon,\n  VideoIcon,\n  VideoOffIcon,\n} from \"lucide-react\"\nimport { Fragment, useMemo, useState, type ComponentProps } from \"react\"\n\nexport const agentTrackToggleVariants = cva([\"size-9\"], {\n  variants: {\n    size: {\n      default: \"h-9 px-2 min-w-9\",\n      sm: \"h-8 px-1.5 min-w-8\",\n      lg: \"h-10 px-2.5 min-w-10\",\n    },\n    variant: {\n      default: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive\",\n        \"data-[state=off]:hover:bg-destructive/15\",\n        \"data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n        \"data-[state=on]:hover:bg-foreground/10\",\n      ],\n      outline: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive data-[state=off]:border-destructive/20\",\n        \"data-[state=off]:hover:bg-destructive/15 data-[state=off]:hover:text-destructive\",\n        \"data-[state=off]:focus:text-destructive\",\n        \"data-[state=off]:focus-visible:border-destructive data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:hover:bg-foreground/10 data-[state=on]:hover:border-foreground/12\",\n        \"dark:data-[state=on]:hover:bg-foreground/10\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n})\n\nfunction getSourceIcon(\n  source: Track.Source,\n  enabled: boolean,\n  pending = false\n) {\n  if (pending) {\n    return LoaderIcon\n  }\n\n  switch (source) {\n    case Track.Source.Microphone:\n      return enabled ? MicIcon : MicOffIcon\n    case Track.Source.Camera:\n      return enabled ? VideoIcon : VideoOffIcon\n    case Track.Source.ScreenShare:\n      return enabled ? MonitorUpIcon : MonitorOffIcon\n    default:\n      return Fragment\n  }\n}\n\n/**\n * Props for the AgentTrackToggle component.\n */\nexport type AgentTrackToggleProps = VariantProps<\n  typeof agentTrackToggleVariants\n> &\n  ComponentProps<\"button\"> & {\n    /**\n     * The size of the toggle.\n     */\n    size?: \"sm\" | \"default\" | \"lg\"\n    /**\n     * The variant of the toggle.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\"\n    /**\n     * The track source to toggle (Microphone, Camera, or ScreenShare).\n     */\n    source: \"camera\" | \"microphone\" | \"screen_share\"\n    /**\n     * Whether the toggle is in a pending/loading state.\n     * When true, displays a loading spinner icon.\n     * @defaultValue false\n     */\n    pending?: boolean\n    /**\n     * Whether the toggle is currently pressed/enabled.\n     * @defaultValue false\n     */\n    pressed?: boolean\n    /**\n     * The default pressed state when uncontrolled.\n     * @defaultValue false\n     */\n    defaultPressed?: boolean\n    /**\n     * Callback fired when the pressed state changes.\n     */\n    onPressedChange?: (pressed: boolean) => void\n  }\n\n/**\n * A toggle button for controlling track publishing state.\n * Displays appropriate icons based on the track source and state.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentTrackToggle\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n * />\n * ```\n */\nexport function AgentTrackToggle({\n  size = \"default\",\n  variant = \"default\",\n  source,\n  pending = false,\n  pressed,\n  defaultPressed = false,\n  className,\n  onPressedChange,\n  ...props\n}: AgentTrackToggleProps) {\n  const [uncontrolledPressed, setUncontrolledPressed] = useState(\n    defaultPressed ?? false\n  )\n  const isControlled = pressed !== undefined\n  const resolvedPressed = useMemo(\n    () => (isControlled ? pressed : uncontrolledPressed) ?? false,\n    [isControlled, pressed, uncontrolledPressed]\n  )\n  const IconComponent = getSourceIcon(\n    source as Track.Source,\n    resolvedPressed,\n    pending\n  )\n  const handlePressedChange = (nextPressed: boolean) => {\n    if (!isControlled) {\n      setUncontrolledPressed(nextPressed)\n    }\n    onPressedChange?.(nextPressed)\n  }\n\n  return (\n    <Toggle\n      size={size}\n      variant={variant}\n      pressed={isControlled ? pressed : undefined}\n      defaultPressed={isControlled ? undefined : defaultPressed}\n      aria-label={`Toggle ${source}`}\n      onPressedChange={handlePressedChange}\n      className={cn(\n        agentTrackToggleVariants({\n          size,\n          variant: variant ?? \"default\",\n          className,\n        })\n      )}\n      {...props}\n    >\n      <IconComponent className={cn(pending && \"animate-spin\")} />\n      {props.children}\n    </Toggle>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/toggle.tsx",
          "target": "@components/voice-agents/livekit/_ui/toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline:\n          \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-9 min-w-9 px-2\",\n        sm: \"h-8 min-w-8 px-1.5\",\n        lg: \"h-10 min-w-10 px-2.5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n  VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      className={cn(toggleVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
        },
        {
          "path": "components/voice-agents/orbkit/shdr-21.tsx",
          "target": "@components/voice-agents/orbkit/shdr-21.tsx",
          "type": "registry:component",
          "content": "/*\n * Deliberately not a `\"use client\"` module — see the note in `shdr-11.tsx`.\n *\n * Note for editors: the shader lives in a template literal, so its comments\n * must not contain backticks.\n */\nimport { ShaderOrb, type OrbVariant, type ShaderOrbProps } from \"./core\"\n\n/* ----------------------------------------------------------------------------\n   SHDR-21 — light diffusing through a cloud.\n\n   A real volumetric integration rather than a surface. The march walks a\n   density field bounded by a sphere and, at every step, does three things:\n\n     TRANSMITTANCE  how much of the background still gets through, tracked as\n                    T *= exp(-density * dt * absorb). Beer-Lambert.\n     SHADOW         a short second march toward the light, so the far side of a\n                    dense clump is dimmer than the lit side. This is the whole\n                    reason the orb reads as volume and not as a flat glow.\n     IN-SCATTER     light added at this step, weighted by density, by the shadow\n                    term, and by a Henyey-Greenstein phase function.\n\n   The phase function is what makes it feel like light rather than paint. It\n   biases scattering forward, so the limb facing the light blooms and the rest\n   stays soft — the same reason a cloud is blinding when you look toward the sun\n   through it and merely bright otherwise.\n\n   Alpha is 1 - T, which is exactly what the volume occludes, so this one needs\n   no radial fade to hide the canvas edge: density falls to zero at the sphere\n   boundary and the alpha goes with it.\n---------------------------------------------------------------------------- */\n\n/*\n * Step counts are `#define`s: ES 1.0 requires constant loop bounds. The march\n * is STEPS * (1 + LIGHT_STEPS) density evaluations, so LIGHT_STEPS is the\n * expensive knob — 4 is enough for readable self-shadowing.\n */\nconst NIMBUS_FRAG = `\n#define STEPS 56\n#define LIGHT_STEPS 4\n#define DENSITY_OCT 4\n#define AA 1\n\nconst float PI = 3.14159265359;\n\n// Volume-reactive values, resolved once per fragment in main().\nfloat nimbusPower;\nfloat nimbusDensity;\n\n/*\n  Density inside the sphere.\n\n  The radial term falls to zero at the boundary, which both bounds the volume\n  and gives the soft edge for free. The cos-warp folds the sample point a few\n  times — the same cheap turbulence the other orbs use — and the threshold\n  carves that into clumps rather than an even fog.\n*/\nfloat density(vec3 p, float animTime) {\n  float shell = 1.0 - length(p) / uP_radius;\n  if (shell <= 0.0) return 0.0;\n\n  vec3 q = p * uP_scale;\n  float f = 1.0;\n  for (int k = 0; k < DENSITY_OCT; k++) {\n    q += cos(q.yzx * f + animTime * uP_churn) / f;\n    f *= 1.8;\n  }\n\n  float n = (sin(q.x) + sin(q.y) + sin(q.z)) / 3.0 * 0.5 + 0.5;\n  // smoothstep against the threshold is the clump control: high threshold\n  // leaves sparse wisps, low fills the sphere with even fog\n  float clump = smoothstep(uP_threshold, 1.0, n);\n  return clump * pow(shell, uP_edgeSoft) * nimbusDensity;\n}\n\n/*\n  Henyey-Greenstein: g > 0 biases scattering forward, which is what gives the\n  bloom on the limb facing the light.\n\n  The physical form carries a 1/(4*PI) normalisation. It is dropped here and\n  folded into uP_power instead — kept in, the whole term sits around 0.02 and\n  the orb renders black unless power is pushed into the hundreds, which makes\n  the slider useless.\n*/\nfloat phaseHG(float c, float g) {\n  float g2 = g * g;\n  return (1.0 - g2) / pow(max(1.0 + g2 - 2.0 * g * c, 0.0001), 1.5);\n}\n\nvec4 nimbusRender(vec2 fragCoord) {\n  float animTime = uP_speed; // integrated clock\n\n  vec2 uv = (2.0 * fragCoord - uRes) / min(uRes.x, uRes.y);\n  vec3 ro = vec3(0.0, 0.0, -uP_camDist);\n  vec3 rd = normalize(vec3(uv, uP_focal));\n\n  /*\n    Light direction, slowly orbiting so the shading is never static.\n\n    The z term is kept POSITIVE — the camera looks along +z, so a light also\n    pointing along +z sits behind the cloud. That is the back-lit case, where\n    dot(rd, L) approaches 1 and the forward-scattering phase blooms. Put the\n    light on the camera's side instead and every ray samples the phase function\n    on its back-scatter tail, where it is roughly ten times smaller, and the orb\n    goes muddy.\n  */\n  vec3 L = normalize(vec3(\n    cos(animTime * uP_lightSpin) * 0.7,\n    0.45,\n    sin(animTime * uP_lightSpin) * 0.35 + 0.65\n  ));\n\n  float phase = phaseHG(dot(rd, L), uP_aniso);\n\n  // Start the march at the sphere's front face instead of the camera — every\n  // step before that contributes nothing, and at 56 steps they are expensive.\n  float toCentre = uP_camDist;\n  float tStart = max(toCentre - uP_radius, 0.0);\n  float span = 2.0 * uP_radius;\n  float dt = span / float(STEPS);\n\n  float T = 1.0;\n  vec3 scattered = vec3(0.0);\n\n  for (int i = 0; i < STEPS; i++) {\n    float t = tStart + (float(i) + 0.5) * dt;\n    vec3 p = ro + rd * t;\n\n    float dn = density(p, animTime);\n    if (dn > 0.001) {\n      // short march toward the light for self-shadowing\n      float shadow = 1.0;\n      float lstep = uP_radius / float(LIGHT_STEPS);\n      for (int k = 1; k <= LIGHT_STEPS; k++) {\n        vec3 lp = p + L * (float(k) - 0.5) * lstep;\n        shadow *= exp(-density(lp, animTime) * lstep * uP_shadowAbsorb);\n      }\n\n      /*\n        In-scattered light: warm where lit, cool where the volume shadows\n        itself.\n\n        The shadow term appears ONCE, inside the mix. Multiplying by it again\n        as a factor — the obvious-looking thing to write — scales the shadowed\n        end of the mix toward zero, so the cool colour is always multiplied\n        away and the cloud comes out monochrome beige however it is tinted.\n        uP_shadowLift is how much light still reaches the shadowed side.\n      */\n      vec3 lit = mix(uC_shadow * uP_shadowLift, uC_light, shadow);\n      scattered += T * dn * dt * lit * phase * nimbusPower;\n\n      T *= exp(-dn * dt * uP_absorb);\n      if (T < 0.01) break;\n    }\n  }\n\n  // a soft ambient body so the unlit side is not pure black\n  float body = 1.0 - T;\n  scattered += uC_shadow * body * uP_ambient;\n\n  return vec4(scattered, body);\n}\n\nvoid main() {\n  /*\n    Agent output turns the light up; user input thickens the cloud. Both are\n    AMPLITUDES. Churn is deliberately NOT volume-scaled: it multiplies the\n    accumulated clock into a phase (animTime * churn), so scaling it by the\n    live volume would turn every volume wobble into a phase jump the size of\n    the whole clock — the cloud scrambles chaotically on each state change\n    instead of gliding, and gets worse the longer the page is open.\n  */\n  nimbusPower = uP_power * (0.7 + 0.9 * uOutput);\n  nimbusDensity = uP_density * (1.0 + 0.35 * uInput);\n\n  vec4 acc = vec4(0.0);\n#if AA > 1\n  for (int mx = 0; mx < AA; mx++) {\n    for (int my = 0; my < AA; my++) {\n      vec2 offset = vec2(float(mx), float(my)) / float(AA) - 0.5;\n      acc += nimbusRender(gl_FragCoord.xy + offset);\n    }\n  }\n  acc /= float(AA * AA);\n#else\n  acc = nimbusRender(gl_FragCoord.xy);\n#endif\n\n  vec3 col = tanh3(acc.rgb * uP_exposure);\n  float a = clamp(acc.a * uP_alphaGain, 0.0, 1.0);\n\n  // Emitted/scattered light, so rgb is already premultiplied — do NOT multiply\n  // by alpha again (see the same note in shdr-31).\n  gl_FragColor = vec4(col, a);\n}\n`\n\nexport const shdr21Orb: OrbVariant = {\n  key: \"shdr-21\",\n  label: \"SHDR-21\",\n  note: \"light diffusing through a cloud\",\n  frag: NIMBUS_FRAG,\n  params: [\n    {\n      key: \"speed\",\n      label: \"Anim speed\",\n      min: 0.015,\n      max: 10,\n      step: 0.05,\n      default: 10,\n      integrate: true,\n    },\n    {\n      key: \"camDist\",\n      label: \"Camera distance\",\n      min: 0.5,\n      max: 40,\n      step: 0.2,\n      default: 4.4,\n    },\n    { key: \"focal\", label: \"Lens\", min: 0.3, max: 15, step: 0.1, default: 1.8 },\n    {\n      key: \"radius\",\n      label: \"Cloud radius\",\n      min: 0.15,\n      max: 10,\n      step: 0.05,\n      default: 2,\n    },\n    {\n      key: \"scale\",\n      label: \"Cloud scale\",\n      min: 0.1,\n      max: 15,\n      step: 0.1,\n      default: 0.8,\n    },\n    { key: \"churn\", label: \"Churn\", min: 0, max: 5, step: 0.03, default: 0.3 },\n    {\n      key: \"threshold\",\n      label: \"Clumping\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.075,\n    },\n    {\n      key: \"edgeSoft\",\n      label: \"Edge softness\",\n      min: 0.1,\n      max: 10,\n      step: 0.05,\n      default: 0.8,\n    },\n    {\n      key: \"density\",\n      label: \"Density\",\n      min: 0.03,\n      max: 20,\n      step: 0.1,\n      default: 3.2,\n    },\n    {\n      key: \"absorb\",\n      label: \"Absorption\",\n      min: 0.03,\n      max: 15,\n      step: 0.1,\n      default: 1.4,\n    },\n    {\n      key: \"shadowAbsorb\",\n      label: \"Shadow depth\",\n      min: 0,\n      max: 20,\n      step: 0.1,\n      default: 2.4,\n    },\n    {\n      key: \"shadowLift\",\n      label: \"Shadow lift\",\n      min: 0,\n      max: 5,\n      step: 0.03,\n      default: 0.55,\n    },\n    {\n      key: \"aniso\",\n      label: \"Forward scatter\",\n      min: -0.9,\n      max: 0.9,\n      step: 0.01,\n      default: 0.45,\n    },\n    {\n      key: \"lightSpin\",\n      label: \"Light orbit\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.12,\n    },\n    {\n      key: \"power\",\n      label: \"Light power\",\n      min: 0.03,\n      max: 40,\n      step: 0.2,\n      default: 1.9,\n    },\n    {\n      key: \"ambient\",\n      label: \"Ambient\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.12,\n    },\n    {\n      key: \"exposure\",\n      label: \"Exposure\",\n      min: 0.03,\n      max: 10,\n      step: 0.05,\n      default: 1,\n    },\n    {\n      key: \"alphaGain\",\n      label: \"Alpha gain\",\n      min: 0.05,\n      max: 10,\n      step: 0.05,\n      default: 1.5,\n    },\n  ],\n  /*\n   * The engine uploads these as uC_<key> vec3 uniforms. Warm light against a\n   * cool shadow is what reads as depth — a single-hue cloud looks flat however\n   * well it is shadowed.\n   */\n  colors: [\n    { key: \"light\", label: \"Light\", default: \"#ffd7a3\" },\n    { key: \"shadow\", label: \"Shadow\", default: \"#3a4a8c\" },\n  ],\n  statePresets: {\n    /*\n      Every state shares the same speed, geometry and cloud shape — only the\n      AMBIENCE and the palette move, so switching state relights the cloud\n      instead of restaging it. The engine glides params and cross-fades\n      colours on one shared easing, so the change reads as a mood shift.\n    */\n    idle: {\n      ambient: 0.12,\n      power: 1.9,\n      shadowLift: 0.55,\n    },\n    thinking: {\n      ambient: 0.22,\n      power: 2.15,\n      shadowLift: 0.65,\n    },\n    speaking: {\n      ambient: 0.46,\n      power: 3.1,\n      shadowLift: 0.95,\n    },\n  },\n  /*\n    The palette carries the rest of the state read: a warm lamp over cool\n    shadow at rest, shifting violet while it thinks, and burning hot while\n    speaking.\n  */\n  stateColors: {\n    idle: { light: \"#ffd7a3\", shadow: \"#3a4a8c\" },\n    thinking: { light: \"#e6d4ff\", shadow: \"#3b3f96\" },\n    speaking: { light: \"#ffb066\", shadow: \"#7a2f6e\" },\n  },\n}\n\nexport type Shdr21Props = Omit<ShaderOrbProps, \"variant\">\n\nexport function Shdr21({ size = 280, ...rest }: Shdr21Props) {\n  return <ShaderOrb variant={shdr21Orb} size={size} {...rest} />\n}\n\nexport default Shdr21\n"
        },
        {
          "path": "components/voice-agents/orbkit/core.tsx",
          "target": "@components/voice-agents/orbkit/core.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport React, {\n  useEffect,\n  useRef,\n  useState,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/* ----------------------------------------------------------------------------\n   Orbkit core — raw WebGL shader orb runtime. No dependencies.\n\n   An orb is a full-screen triangle rendered into a transparent canvas by a\n   fragment shader. Every orb declares a parameter schema (sliders + colors);\n   the values are uploaded as uniforms each frame from a ref, so a controls\n   panel can tune them live without ever remounting the canvas (a remount would\n   drop the WebGL context).\n\n   Animation model: every state synthesizes two volume signals — input (user\n   speech energy) and output (agent speech energy) — smooths them, and the\n   shaders react to those. The flow clock's speed itself follows the output\n   volume, so orbs visibly quicken when the agent is talking.\n---------------------------------------------------------------------------- */\n\nexport type OrbState = \"idle\" | \"thinking\" | \"speaking\"\n\nexport const ORB_STATES = [\"idle\", \"thinking\", \"speaking\"] as const\n\nfunction clamp01(n: number) {\n  return Math.min(1, Math.max(0, n))\n}\n\n/** Per-state [input, output] volume synthesis. */\n/**\n * Transition rate shared by params, colours and the flow-speed multiplier.\n * They must move together: if the rate multiplier eases faster than the look,\n * a state change spins the orb up before it has finished cross-fading, which\n * reads as a lurch.\n *\n * This drives a critically damped spring rather than the exponential ease it\n * used to. An exponential's velocity is highest at the instant the target\n * changes, so every state change began with a jolt — and for params that are\n * spatial frequencies (Corona's warpFreq travels 5.25 -> 19.5 between states)\n * that jolt sweeps the field through its intermediate frequencies at maximum\n * rate, which is what read as the transition \"scrambling\".\n *\n * A spring starts at rest and accelerates, so the sweep is spread across the\n * transition instead of front-loaded. Measured on that warpFreq move it is a\n * 20% lower peak rate of change (20.3/s vs 25.3/s) AND it arrives sooner —\n * 1.50s to within 2% against the exponential's 2.18s, since an exponential\n * only ever asymptotes toward its target.\n */\nconst PARAM_EASE = 4\n\n/*\n  One step of a critically damped spring, implicit (semi-implicit Euler would\n  blow up at the frame times a backgrounded tab produces). Returns nothing and\n  writes through the scratch pair so the hot loop allocates nothing.\n*/\nconst springOut = { x: 0, v: 0 }\nfunction springStep(\n  x: number,\n  v: number,\n  target: number,\n  dt: number,\n  omega: number\n) {\n  const f = 1 + 2 * dt * omega\n  const oo = omega * omega\n  const hoo = dt * oo\n  const hhoo = dt * hoo\n  const detInv = 1 / (f + hhoo)\n  springOut.x = (f * x + dt * v + hhoo * target) * detInv\n  springOut.v = (v + hoo * (target - x)) * detInv\n}\n\nfunction targetVolumes(state: OrbState, t: number): [number, number] {\n  switch (state) {\n    case \"idle\":\n      return [0, 0.3]\n    case \"speaking\":\n      return [\n        clamp01(0.65 + Math.sin(t * 4.8) * 0.22),\n        clamp01(0.75 + Math.sin(t * 3.6) * 0.22),\n      ]\n    case \"thinking\": {\n      const base = 0.38 + 0.07 * Math.sin(t * 0.7)\n      const wander = 0.05 * Math.sin(t * 2.1) * Math.sin(t * 0.37 + 1.2)\n      return [\n        clamp01(base + wander),\n        clamp01(0.48 + 0.12 * Math.sin(t * 1.05 + 0.6)),\n      ]\n    }\n  }\n}\n\n/* ------------------------------ param schema ------------------------------- */\n\nexport interface OrbParamDef {\n  key: string\n  label: string\n  min: number\n  max: number\n  step: number\n  default: number\n  /**\n   * Rate params. The engine integrates them into a clock\n   * (`clock += dt * value * volumeSpeed`) and uploads the clock instead of the\n   * raw value, so changing the rate never jumps the phase — the motion speeds\n   * up or slows down rather than snapping to a new position.\n   */\n  integrate?: boolean\n}\n\nexport interface OrbColorDef {\n  key: string\n  label: string\n  /** hex, e.g. `#ff8b73` */\n  default: string\n}\n\nexport interface OrbVariant {\n  key: string\n  label: string\n  note: string\n  /** GLSL fragment shader body. Uniform declarations are generated for you. */\n  frag: string\n  params: OrbParamDef[]\n  colors: OrbColorDef[]\n  /**\n   * Per-state parameter targets. The engine glides each param toward the\n   * active state's preset. Params passed explicitly via the `params` prop\n   * always win over the preset.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /**\n   * Per-state colour targets, the colour counterpart of `statePresets`.\n   * Kept a separate map because presets are numeric and colours are hex\n   * strings — a union would lose type safety on both. Colours glide in RGB\n   * on the same easing as params, so a state change cross-fades rather\n   * than cutting. Colours passed explicitly via the `colors` prop always\n   * win, exactly as with params.\n   */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n}\n\nexport type OrbParamValues = Partial<Record<string, number>>\nexport type OrbColorValues = Partial<Record<string, string>>\n\n/** Every param and color at its schema default. */\nexport function defaultValuesFor(variant: OrbVariant): {\n  params: Record<string, number>\n  colors: Record<string, string>\n} {\n  return {\n    params: Object.fromEntries(variant.params.map((p) => [p.key, p.default])),\n    colors: Object.fromEntries(variant.colors.map((c) => [c.key, c.default])),\n  }\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace(\"#\", \"\").trim()\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]\n  const n = parseInt(h, 16)\n  if (h.length !== 6 || Number.isNaN(n)) return [1, 1, 1]\n  return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255]\n}\n\n/* ------------------------------- GLSL shared ------------------------------- */\n\nconst VERT = `\nattribute vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\n/**\n * Prelude prepended to every orb fragment shader: uniforms, value noise, fbm,\n * and the centered aspect-corrected UV helper.\n */\nexport const ORB_GLSL_HELPERS = `\nprecision highp float;\nuniform vec2 uRes;\nuniform float uTime;   // slow ambient clock (half real-time)\nuniform float uAnim;   // flow clock — its speed follows the output volume\nuniform float uInput;  // input volume 0..1: user speech energy\nuniform float uOutput; // output volume 0..1: agent speech energy\n\nfloat hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); }\nfloat noise(vec2 p) {\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);\n  return mix(\n    mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),\n    mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x),\n    f.y\n  );\n}\nfloat fbm(vec2 p) {\n  float v = 0.0;\n  float a = 0.5;\n  for (int i = 0; i < 5; i++) {\n    v += a * noise(p);\n    p = p * 2.03 + vec2(11.7, 7.3);\n    a *= 0.5;\n  }\n  return v;\n}\nvec2 orbUV() { return (2.0 * gl_FragCoord.xy - uRes) / min(uRes.x, uRes.y); }\n\n// GLSL ES 1.0 has no tanh() — it arrived in ES 3.0. Shader-golf listings lean\n// on it as a tone-mapper, so it ships here. Clamped against exp() overflow;\n// accurate for the non-negative accumulators those shaders produce.\nvec3 tanh3(vec3 x) {\n  x = clamp(x, -10.0, 10.0);\n  vec3 e = exp(2.0 * x);\n  return (e - 1.0) / (e + 1.0);\n}\n\n`\n\nfunction paramUniformDecls(variant: OrbVariant): string {\n  return [\n    ...variant.params.map((p) => `uniform float uP_${p.key};`),\n    ...variant.colors.map((c) => `uniform vec3 uC_${c.key};`),\n  ].join(\"\\n\")\n}\n\n/* ------------------------------- engine ------------------------------------ */\n\n/**\n * Per-canvas context-lifecycle controller. Created on first mount of a canvas\n * and kept for the element's whole life — the router can hide a page and show\n * the same DOM again, and React re-runs effects on the same canvas, so the\n * lost/restored listeners must outlive any single effect run: an uncanceled\n * webglcontextlost event marks the context permanently unrestorable.\n */\ninterface CanvasContextController {\n  /** Whether a mounted orb currently wants this context alive. */\n  desired: boolean\n  /** Builds a render generation; returns its teardown. Rebound per effect run. */\n  start: (() => () => void) | null\n  /** Teardown of the live generation, if one is running. */\n  stopGen: (() => void) | null\n}\n\nconst canvasControllers = new WeakMap<\n  HTMLCanvasElement,\n  CanvasContextController\n>()\n\nfunction compile(\n  gl: WebGLRenderingContext,\n  type: number,\n  src: string\n): WebGLShader | null {\n  const shader = gl.createShader(type)\n  if (!shader) return null\n  gl.shaderSource(shader, src)\n  gl.compileShader(shader)\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    console.error(\"[orbkit] shader compile error:\", gl.getShaderInfoLog(shader))\n    gl.deleteShader(shader)\n    return null\n  }\n  return shader\n}\n\n/* ----------------------------------------------------------------------------\n   Wrappers — optional decoration drawn around, under and over the orb.\n\n   A wrapper is pure CSS/SVG, never a shader: the orb keeps its own canvas and\n   the decoration is composited on top of it by the browser. That keeps the\n   whole set free for any orb (no per-variant shader work), costs nothing on\n   the GPU budget the shaders are already spending, and means swapping one\n   wrapper for another at runtime never touches the WebGL context. Turning a\n   wrapper on or off does, since that is what moves the canvas into or out of\n   the wrapper element — see the effect's `wrapped` dependency.\n\n   Layout: a wrapped orb becomes a square box, and the canvas is absolutely\n   positioned inside it with the spec's `inset`. The FOOTPRINT is unchanged —\n   `size` is still the outer diameter — so dropping a wrapper onto an existing\n   orb reflows nothing; the orb itself just shrinks to leave the ring room.\n\n   Colour: every layer that isn't physically light or shadow paints in\n   `currentColor`, so a wrapper picks up the surrounding text colour and reads\n   correctly on light and dark pages with no configuration. `wrapperColor`\n   sets that colour when you want something other than the inherited one.\n---------------------------------------------------------------------------- */\n\nexport const ORB_WRAPPERS = [\n  \"none\",\n  \"glass\",\n  \"ring\",\n  \"dotted\",\n  \"ticks\",\n  \"reticle\",\n  \"grid\",\n  \"halftone\",\n  \"scanlines\",\n] as const\n\nexport type OrbWrapper = (typeof ORB_WRAPPERS)[number]\n\n/*\n  Keyframes for the animated wrappers, shipped inside the component so an orb\n  stays a single self-contained file with nothing to add to a global\n  stylesheet. React 19 hoists a <style href precedence> into <head> and\n  de-duplicates it, so a page full of wrapped orbs emits this exactly once;\n  older React renders it inline, which is redundant but harmless.\n\n  Reduced motion parks all of it. The shader runtime already honours the same\n  preference for the orb itself (see the reduce-motion branch in the render\n  loop), and a ring that keeps spinning around a frozen orb would be the worse\n  half of the two still moving.\n*/\nconst WRAPPER_STYLE_HREF = \"orbkit-wrapper\"\nconst WRAPPER_CSS = `\n@keyframes orbkit-w-spin { to { transform: rotate(360deg); } }\n@keyframes orbkit-w-roll { from { transform: translateY(-110%); } to { transform: translateY(360%); } }\n@media (prefers-reduced-motion: reduce) {\n  .orbkit-w-anim { animation: none !important; }\n}\n`\n\ninterface WrapperSpec {\n  /**\n   * How far the canvas sits inside the box, in percent, leaving the\n   * decoration room. Applied as explicit width/height rather than as `inset`:\n   * a canvas is a REPLACED element, so an absolutely positioned one with\n   * `left` and `right` both set does not stretch between them — it keeps its\n   * intrinsic size and the over-constrained edge is dropped. The orb would\n   * then be drawn into a canvas the size of the page.\n   */\n  inset: number\n  /**\n   * Soft circular mask on the canvas. Only the wrappers that read as a\n   * CONTAINER set one — a bubble has to hold the orb, whereas a bezel sits\n   * beside it and clipping the halo there would just amputate the glow.\n   */\n  mask?: string\n  /** Cast by the assembly as a whole, on the outer box. */\n  shadow?: string\n\n  /** True when the spec uses one of the keyframes above. */\n  animated?: boolean\n  /** Painted beneath the canvas. */\n  under?: ReactNode\n  /** Painted over it. */\n  over?: ReactNode\n}\n\nconst DISC: CSSProperties = { borderRadius: \"50%\" }\n\n/** One absolutely-positioned decoration layer, filling the wrapper box. */\nfunction Layer({\n  inset = 0,\n  style,\n  className,\n}: {\n  inset?: number | string\n  style: CSSProperties\n  className?: string\n}) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={className}\n      style={{ position: \"absolute\", inset, pointerEvents: \"none\", ...style }}\n    />\n  )\n}\n\n/**\n * A free-floating highlight — glass's specular and its bounce. These do not go\n * through `Layer` because they are placed with `left`/`top`/`width`, and a\n * style object that sets those on top of `Layer`'s `inset` shorthand is mixing\n * shorthand and longhand for the same property: React warns about it, and the\n * result depends on key order rather than on anything you would want to rely\n * on.\n */\nfunction Highlight({ style }: { style: CSSProperties }) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      style={{\n        position: \"absolute\",\n        borderRadius: \"50%\",\n        pointerEvents: \"none\",\n        ...style,\n      }}\n    />\n  )\n}\n\n/**\n * The mask that makes a wrapper HOLD the orb: cuts the canvas back to the\n * bubble and stops a hairline short of the rim, so the orb never quite touches\n * the glass.\n *\n * The percentage has to be derived rather than written down. `closest-side`\n * measures the CANVAS, and a wrapper with a negative inset draws its canvas\n * LARGER than the bubble — at -7 the canvas is 114% of the box, so the rim\n * sits at 100/1.14 = 87.7% of the canvas's own radius, not at 100%.\n *\n * The gap is real pixels rather than a share of the size: it reads as the same\n * band at 120px and at 900px, which a percentage would not.\n */\nconst RIM_GAP_PX = 4\n\nfunction rimMask(inset: number): string {\n  const rim = (100 / (1 - (2 * inset) / 100)).toFixed(2)\n  // Feathered over the final pixel, so the cut is not a razor edge.\n  const solid = RIM_GAP_PX + 0.5\n  const clear = RIM_GAP_PX - 0.5\n  return `radial-gradient(circle closest-side, #000 calc(${rim}% - ${solid}px), rgba(0,0,0,0) calc(${rim}% - ${clear}px))`\n}\n\n/** Both spellings, since Safari still wants the prefix for mask-image. */\nfunction masked(image: string): CSSProperties {\n  return { WebkitMaskImage: image, maskImage: image }\n}\n\nconst svgLayer: CSSProperties = {\n  position: \"absolute\",\n  inset: 0,\n  width: \"100%\",\n  height: \"100%\",\n  pointerEvents: \"none\",\n  overflow: \"visible\",\n}\n\n/** Glass's overfill, shared by its inset and the mask derived from it. */\nconst GLASS_INSET = -4\n\nconst WRAPPER_SPECS: Record<Exclude<OrbWrapper, \"none\">, WrapperSpec> = {\n  /*\n    glass — a blown bubble with the orb suspended inside it.\n\n    Five layers in the order light actually arrives: the body brightening\n    toward the key light, the Fresnel ring where a sphere's edge turns almost\n    edge-on and reflects nearly everything, the rim itself, the window\n    reflection, and the bounce coming back up off whatever the bubble is\n    sitting on. All of it is white and black rather than `currentColor` —\n    glass has no colour of its own, only the light it moves around.\n  */\n  glass: {\n    /*\n      Negative on purpose. An orb's shader does not necessarily paint to the\n      edge of its canvas — most draw a sphere with transparent margin around\n      it — so a canvas sized to the bubble leaves a dead ring between the orb\n      and the rim, which is not what a thing suspended in glass looks like.\n      Oversizing the canvas by 14% pushes the sphere out to the rim, and\n      `rimMask` cuts whatever overflows — a few pixels short of the glass, so\n      the orb sits just inside it rather than welded to it. Orbs that already fill\n      their canvas lose a few percent off the limb, which is the same crop the\n      reference bubble makes.\n    */\n    inset: GLASS_INSET,\n    mask: rimMask(GLASS_INSET),\n    shadow: \"0 24px 48px -26px rgba(0,0,0,0.55)\",\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(ellipse 80% 70% at 28% 20%, rgba(255,255,255,0.16), rgba(255,255,255,0.03) 45%, rgba(255,255,255,0) 72%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(255,255,255,0) 0%, rgba(255,255,255,0.0) 55%, rgba(255,255,255,0.05) 99.5%, rgba(255,255,255,0) 100%)\",\n            overflow: \"hidden\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow: \"3px 6px 10px #ffffff20 inset\",\n          }}\n        />\n        {/*\n          The shell's own darkening, just inside the rim. Invisible on a dark\n          page — it is black over black — and doing all the work on a light\n          one, where the white highlights below have nothing to stand out\n          against and the bubble would otherwise read as a bare drop shadow.\n        */}\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(0,0,0,0) 78%, rgba(0,0,0,0.05) 93%, rgba(0,0,0,0.02) 100%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow:\n              \"inset 0 6px 12px -7px rgba(255,255,255,0.05), inset 0 -9px 16px -9px rgba(255,255,255,0.1), 0 0 0 1px rgba(0,0,0,0.07)\",\n          }}\n        />\n        <Highlight\n          style={{\n            left: \"15%\",\n            top: \"10%\",\n            width: \"38%\",\n            height: \"22%\",\n            transform: \"rotate(-25deg)\",\n            background:\n              \"radial-gradient(closest-side, rgba(255,255,255,0.9), rgba(255,255,255,0.3) 55%, rgba(255,255,255,0) 100%)\",\n            filter: \"blur(10px)\",\n          }}\n        />\n      </>\n    ),\n  },\n\n  /* ring — two hairlines and nothing else. The restrained one. */\n  ring: {\n    inset: 9,\n    over: (\n      <>\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.22 }}\n        />\n        <Layer\n          inset=\"5%\"\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.1 }}\n        />\n      </>\n    ),\n  },\n\n  /*\n    dotted — evenly spaced dots around the circumference, turning slowly.\n\n    Drawn as one dashed circle with round caps and a near-zero dash length, so\n    each dash collapses to a dot. `pathLength=\"64\"` renormalizes the path to 64\n    units first, which is what makes the count exact: the dash period is\n    literally 1/64th of the circle, so the pattern closes on itself with no\n    seam where the last gap would otherwise be short.\n  */\n  dotted: {\n    inset: 10,\n    animated: true,\n    over: (\n      <svg\n        aria-hidden=\"true\"\n        viewBox=\"0 0 100 100\"\n        className=\"orbkit-w-anim\"\n        style={{ ...svgLayer, animation: \"orbkit-w-spin 48s linear infinite\" }}\n      >\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"47\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.7\"\n          strokeLinecap=\"round\"\n          pathLength={64}\n          strokeDasharray=\"0.0001 0.9999\"\n          opacity={0.45}\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    ticks — an instrument bezel: a fine minor scale every 6 degrees with a\n    longer major tick every 30. Both are one repeating conic gradient masked\n    down to an annulus, so the tick count is set by the gradient's period and\n    the tick LENGTH by how far in the mask reaches.\n  */\n  ticks: {\n    inset: 12,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.32,\n            background:\n              \"repeating-conic-gradient(from -0.5deg, transparent 0deg 0.2deg, currentColor 0.4deg 0.6deg, transparent 0.8deg 6deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 88%, #000 90%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.6,\n            background:\n              \"repeating-conic-gradient(from -0.75deg, transparent 0deg 0.25deg, currentColor 0.5deg 1deg, transparent 1.25deg 30deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 80%, #000 82%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.12 }}\n        />\n      </>\n    ),\n  },\n\n  /* reticle — viewfinder furniture: corner brackets, cardinal ticks, a track. */\n  reticle: {\n    inset: 13,\n    over: (\n      <svg aria-hidden=\"true\" viewBox=\"0 0 100 100\" style={svgLayer}>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" opacity=\"0.5\">\n          <path d=\"M1 13 L1 1 L13 1\" />\n          <path d=\"M87 1 L99 1 L99 13\" />\n          <path d=\"M99 87 L99 99 L87 99\" />\n          <path d=\"M13 99 L1 99 L1 87\" />\n        </g>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.38\">\n          <path d=\"M50 1 L50 9\" />\n          <path d=\"M50 91 L50 99\" />\n          <path d=\"M1 50 L9 50\" />\n          <path d=\"M91 50 L99 50\" />\n        </g>\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"46\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"0.7\"\n          opacity=\"0.22\"\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    grid — a graticule laid over the orb and masked back to the disc, so the\n    mesh appears to be etched on the glass in front of it rather than drawn on\n    the page behind. The lines are 1px whatever the size; the SPACING is a\n    percentage, so the cell count holds from a gallery thumbnail to a\n    full-bleed hero.\n  */\n  grid: {\n    inset: 8,\n    /*\n      The ruling sits UNDER the canvas: graph paper the orb rests on, not a\n      mesh laid over its face. Drawn on top it crosshatched the shader — the\n      one thing the wrapper is meant to frame. The ring stays over, since it\n      only ever meets the transparent margin at the canvas edge.\n    */\n    under: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.18,\n          backgroundImage:\n            \"repeating-linear-gradient(to right, currentColor 0 1px, transparent 1px 12.5%), repeating-linear-gradient(to bottom, currentColor 0 1px, transparent 1px 12.5%)\",\n          ...masked(\n            \"radial-gradient(circle closest-side, #000 86%, rgba(0,0,0,0) 99%)\"\n          ),\n        }}\n      />\n    ),\n    over: (\n      <Layer\n        style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.2 }}\n      />\n    ),\n  },\n\n  /*\n    halftone — a print screen over the outer band of the orb. The mask keeps\n    the middle clear, so the dots read as the image breaking up toward its\n    edge instead of a texture pasted across the whole face.\n  */\n  halftone: {\n    inset: 6,\n    over: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.5,\n          backgroundImage: \"radial-gradient(currentColor 22%, transparent 24%)\",\n          backgroundSize: \"7px 7px\",\n          ...masked(\n            \"radial-gradient(circle closest-side, transparent 40%, #000 80%, #000 94%, rgba(0,0,0,0) 100%)\"\n          ),\n        }}\n      />\n    ),\n  },\n\n  /*\n    scanlines — a phosphor tube. Black lines rather than `currentColor`,\n    because scanlines are the UNLIT gaps between rows and stay dark whatever\n    the page is; the slow bright band rolling down is the vertical hold\n    drifting, which is the part that reads as a CRT rather than as stripes.\n  */\n  scanlines: {\n    inset: 0,\n    animated: true,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            backgroundImage:\n              \"repeating-linear-gradient(to bottom, rgba(0,0,0,0.45) 0 1px, rgba(0,0,0,0) 1px 3px)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, #000 84%, rgba(0,0,0,0) 100%)\"\n            ),\n          }}\n        />\n        <span\n          aria-hidden=\"true\"\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            borderRadius: \"50%\",\n            overflow: \"hidden\",\n            pointerEvents: \"none\",\n          }}\n        >\n          <span\n            className=\"orbkit-w-anim\"\n            style={{\n              position: \"absolute\",\n              left: 0,\n              right: 0,\n              top: 0,\n              height: \"30%\",\n              background:\n                \"linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,0.07) 50%, rgba(255,255,255,0) 100%)\",\n              animation: \"orbkit-w-roll 7s linear infinite\",\n            }}\n          />\n        </span>\n        <Layer\n          style={{ ...DISC, boxShadow: \"inset 0 0 40px -8px rgba(0,0,0,0.5)\" }}\n        />\n      </>\n    ),\n  },\n}\n\nexport interface ShaderOrbProps {\n  /** The orb definition: shader + param schema + state presets. */\n  variant: OrbVariant\n  /** Drives the synthesized volume signals. Defaults to `\"idle\"`. */\n  state?: OrbState\n  /** Rendered size in CSS pixels. Ignored when `className` sizes the canvas. */\n  size?: number\n  /** Explicit param overrides. Any key present here wins over the state preset. */\n  params?: OrbParamValues\n  /** Explicit color overrides, as hex strings. */\n  colors?: OrbColorValues\n  /**\n   * Per-state parameter targets, overriding the variant's own. Merged KEY BY\n   * KEY over what the orb already defines, so `{ thinking: { churn: 1.62 } }`\n   * retouches one param of one state and leaves every other param — and the\n   * other two states — exactly as the orb ships them.\n   *\n   * This is the prop form of the variant's `statePresets`, so you can retune\n   * an orb's states from the outside without forking its file. Values still\n   * glide, so switching states cross-fades into your targets. An explicit\n   * `params` value outranks this, the same way it outranks the variant.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /** The colour counterpart of `statePresets`, merged the same key-by-key way. */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n  /**\n   * Per-state volume drive, the third member of the same family. Use it to\n   * give each state its own energy; use `volumes` below instead when you have\n   * a real signal to feed in, such as live mic level.\n   */\n  stateVolumes?: Partial<Record<OrbState, { input?: number; output?: number }>>\n  /**\n   * Overrides the synthesized volume signals for the active state. The engine\n   * normally derives these from `state` — a slow breath at idle, a restless\n   * wander while thinking, speech-shaped peaks while speaking — and most\n   * shaders read them as their reactivity. Setting either channel here pins\n   * it instead, which is how the playground lets you dial each state's drive\n   * independently. Omit a channel to keep its synthesized motion.\n   */\n  volumes?: { input?: number; output?: number }\n  /** Freeze the animation on the current frame. */\n  paused?: boolean\n  /**\n   * Stop rendering while the orb is scrolled out of view. Defaults to `true` —\n   * a page full of orbs would otherwise run a WebGL loop per card.\n   */\n  pauseOffscreen?: boolean\n  /** Device-pixel-ratio ceiling. Defaults to `2`. */\n  maxDpr?: number\n  /**\n   * Decoration drawn around the orb — a glass bubble, a dotted bezel, a\n   * viewfinder. Defaults to `\"none\"`, which renders the bare canvas exactly as\n   * it always has, with no extra element in the tree.\n   *\n   * A wrapper never changes the orb's footprint: `size` stays the outer\n   * diameter and the canvas is inset inside it, so switching one on reflows\n   * nothing around it.\n   */\n  wrapper?: OrbWrapper\n  /**\n   * The colour a wrapper draws its lines and dots in. Defaults to\n   * `currentColor` — the inherited text colour — which is what makes the\n   * bezels legible on a light and a dark page without being told which one\n   * they are on. `glass` ignores it: glass has no colour of its own.\n   */\n  wrapperColor?: string\n  /** Applied to the outermost element — the wrapper when there is one. */\n  className?: string\n  /** Merged onto the outermost element's style. */\n  style?: CSSProperties\n  /** Accessible label. When omitted the orb is hidden from assistive tech. */\n  ariaLabel?: string\n}\n\nexport function ShaderOrb({\n  variant,\n  state = \"idle\",\n  size,\n  params,\n  colors,\n  statePresets,\n  stateColors,\n  stateVolumes,\n  volumes,\n  paused = false,\n  pauseOffscreen = true,\n  maxDpr = 2,\n  wrapper = \"none\",\n  wrapperColor,\n  className,\n  style,\n  ariaLabel,\n}: ShaderOrbProps) {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const spec = wrapper === \"none\" ? undefined : WRAPPER_SPECS[wrapper]\n  const wrapped = spec !== undefined\n\n  // Live refs: the render loop reads these every frame, so changing a param\n  // never re-runs the GL setup effect (which would drop the context). Synced in\n  // an effect rather than during render — a ref write during render is unsafe\n  // under concurrent rendering, and the loop picks the new value up on the very\n  // next frame anyway.\n  /*\n    Whether the canvas has drawn a frame yet, tracked per variant because a\n    variant swap mounts a brand new canvas (see the `key` below).\n\n    A mounted-but-never-drawn canvas is at the browser's mercy: rather than\n    the transparent rectangle you would expect, a page that mounts a dozen at\n    once gets white boxes — and in some browsers a broken-image placeholder —\n    for as long as the compositor has nothing to raster. That window is not\n    small here: every orb compiles a full fragment shader synchronously in its\n    own mount effect, so on the gallery grid the first canvases sit empty\n    while the last ones are still compiling. Holding each canvas invisible\n    until its own first frame lands is what makes the grid fade in cleanly\n    instead of flashing. One state change per orb, once, on mount.\n  */\n  const [paintedKey, setPaintedKey] = useState<string | null>(null)\n  const painted = paintedKey === variant.key\n\n  const stateRef = useRef<OrbState>(state)\n  const paramsRef = useRef<OrbParamValues | undefined>(params)\n  const colorsRef = useRef<OrbColorValues | undefined>(colors)\n  const statePresetsRef = useRef(statePresets)\n  const stateColorsRef = useRef(stateColors)\n  const stateVolumesRef = useRef(stateVolumes)\n  const volumesRef = useRef(volumes)\n  const pausedRef = useRef(paused)\n\n  useEffect(() => {\n    stateRef.current = state\n    paramsRef.current = params\n    colorsRef.current = colors\n    statePresetsRef.current = statePresets\n    stateColorsRef.current = stateColors\n    stateVolumesRef.current = stateVolumes\n    volumesRef.current = volumes\n    pausedRef.current = paused\n  }, [\n    state,\n    params,\n    colors,\n    statePresets,\n    stateColors,\n    stateVolumes,\n    volumes,\n    paused,\n  ])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    const gl = canvas.getContext(\"webgl\", {\n      alpha: true,\n      // No MSAA: the geometry is a single full-screen triangle, so there are no\n      // primitive edges to antialias — softness comes from the shaders. Leaving\n      // it on costs the multisample buffers plus a resolve every frame.\n      antialias: false,\n      premultipliedAlpha: true,\n    })\n    if (!gl) return\n\n    const loseExt = gl.getExtension(\"WEBGL_lose_context\")\n\n    /*\n      A \"generation\" is everything tied to a live context: program, buffers,\n      observers, render loop. Browsers cap live WebGL contexts per page and\n      evict the oldest past the cap, and an evicted orb's canvas stays blank\n      forever unless the app rebuilds — so generations tear down and rebuild on\n      the lost/restored events instead of assuming the context is immortal.\n    */\n    let announcedPaint = false\n\n    const startGeneration = (): (() => void) => {\n      if (gl.isContextLost()) return () => {}\n      // Every generation announces its own first frame: a context that was\n      // lost and restored has an empty drawing buffer and is hidden again\n      // (below), so it has to earn its reveal back.\n      announcedPaint = false\n\n      const vs = compile(gl, gl.VERTEX_SHADER, VERT)\n      const fs = compile(\n        gl,\n        gl.FRAGMENT_SHADER,\n        ORB_GLSL_HELPERS + paramUniformDecls(variant) + variant.frag\n      )\n      const releaseShaders = () => {\n        if (vs) gl.deleteShader(vs)\n        if (fs) gl.deleteShader(fs)\n      }\n      if (!vs || !fs) return releaseShaders\n\n      const prog = gl.createProgram()\n      if (!prog) return releaseShaders\n      gl.attachShader(prog, vs)\n      gl.attachShader(prog, fs)\n      gl.linkProgram(prog)\n      if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n        console.error(\n          \"[orbkit] program link error:\",\n          gl.getProgramInfoLog(prog)\n        )\n        gl.deleteProgram(prog)\n        return releaseShaders\n      }\n      gl.useProgram(prog)\n\n      const buf = gl.createBuffer()\n      gl.bindBuffer(gl.ARRAY_BUFFER, buf)\n      gl.bufferData(\n        gl.ARRAY_BUFFER,\n        new Float32Array([-1, -1, 3, -1, -1, 3]),\n        gl.STATIC_DRAW\n      )\n      const aPos = gl.getAttribLocation(prog, \"aPos\")\n      gl.enableVertexAttribArray(aPos)\n      gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0)\n\n      gl.enable(gl.BLEND)\n      gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n\n      const uRes = gl.getUniformLocation(prog, \"uRes\")\n      const uTime = gl.getUniformLocation(prog, \"uTime\")\n      const uAnim = gl.getUniformLocation(prog, \"uAnim\")\n      const uInput = gl.getUniformLocation(prog, \"uInput\")\n      const uOutput = gl.getUniformLocation(prog, \"uOutput\")\n\n      const paramLocs = variant.params.map((p) => ({\n        def: p,\n        loc: gl.getUniformLocation(prog, `uP_${p.key}`),\n      }))\n      const colorLocs = variant.colors.map((c) => ({\n        def: c,\n        loc: gl.getUniformLocation(prog, `uC_${c.key}`),\n      }))\n\n      /* --- sizing: track the element box, not a one-shot measurement ------- */\n      // Backing-store scale, stepped down by the adaptive-resolution logic in\n      // the loop when the GPU can't hold frame rate. CSS size never changes —\n      // the browser upscales, which these soft shaders absorb gracefully.\n      let resScale = 1\n      const resize = () => {\n        const dpr = Math.min(window.devicePixelRatio || 1, maxDpr) * resScale\n        const w = Math.max(1, Math.round(canvas.clientWidth * dpr))\n        const h = Math.max(1, Math.round(canvas.clientHeight * dpr))\n        if (canvas.width !== w || canvas.height !== h) {\n          canvas.width = w\n          canvas.height = h\n          gl.viewport(0, 0, w, h)\n        }\n        /*\n          Uploaded UNCONDITIONALLY, outside the size guard. A rebuilt\n          generation (React strict-mode remount, a restored context) links a\n          fresh program whose uRes starts at zero — and the canvas usually\n          already holds the right backing size, so an upload gated behind\n          the resize never ran. With uRes = 0, orbUV() divides by zero and\n          every fragment lands transparent: a healthy context, a bound\n          program, and a permanently blank orb.\n        */\n        gl.uniform2f(uRes, w, h)\n      }\n      resize()\n\n      const resizeObserver =\n        typeof ResizeObserver !== \"undefined\"\n          ? new ResizeObserver(resize)\n          : null\n      resizeObserver?.observe(canvas)\n\n      /* --- visibility: don't burn a render loop on an offscreen orb -------- */\n      let visible = !pauseOffscreen\n      const intersectionObserver =\n        pauseOffscreen && typeof IntersectionObserver !== \"undefined\"\n          ? new IntersectionObserver(\n              (entries) => {\n                visible = Boolean(entries[0]?.isIntersecting)\n                if (visible) {\n                  last = performance.now() / 1000\n                }\n              },\n              { rootMargin: \"150px 0px\", threshold: 0 }\n            )\n          : null\n      if (intersectionObserver) {\n        intersectionObserver.observe(canvas)\n      } else {\n        visible = true\n      }\n\n      const reduceMotion =\n        typeof window.matchMedia === \"function\" &&\n        window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n\n      /* --- driver state ---------------------------------------------------- */\n      let tSec = 0\n      // random phase so two orbs on the same page never look synchronized\n      let anim = Math.random() * 100\n      let speed = 0.1\n      const cur = { in: 0, out: 0.3 }\n      const presets = variant.statePresets\n      const paramCur: Record<string, number> = {}\n      const paramVel: Record<string, number> = {}\n      const paramClocks: Record<string, number> = {}\n      const colorCur: Record<string, [number, number, number]> = {}\n      const colorVel: Record<string, [number, number, number]> = {}\n      let speedVel = 0\n      const [initialIn, initialOut] = targetVolumes(stateRef.current, 0)\n      cur.in = initialIn\n      cur.out = initialOut\n      let last = performance.now() / 1000\n      let raf = 0\n      // smoothed frame time for the adaptive-resolution check\n      let frameEma = 1 / 60\n\n      const uploadAndDraw = (dt: number, snap = false) => {\n        // Synthesized from the state, unless a channel is pinned via\n        // `volumes`. Pinned values still glide on the same easing, so dialing\n        // one in the playground cross-fades rather than jumping.\n        const [tin, tout] = targetVolumes(stateRef.current, tSec)\n        // Same order as params and colours: direct prop, then the per-state\n        // map, then the engine's own synthesis.\n        const liveVolumes = volumesRef.current\n        const stateVolume = stateVolumesRef.current?.[stateRef.current]\n        const targetIn = liveVolumes?.input ?? stateVolume?.input ?? tin\n        const targetOut = liveVolumes?.output ?? stateVolume?.output ?? tout\n        const kVol = 1 - Math.exp(-dt * 12)\n        cur.in += (targetIn - cur.in) * kVol\n        cur.out += (targetOut - cur.out) * kVol\n\n        /*\n          Flow speed follows the output volume. It multiplies every integrated\n          clock's increment, so it is a RATE: easing it quickly makes the orb\n          visibly lurch — a state change would spin the orb up hard before the\n          params had finished gliding.\n\n          It is therefore eased on the same constant as the params below, so a\n          state change ramps its motion over the same half second that its look\n          takes to cross-fade. The steady-state values are unchanged, so a\n          speaking orb still flows faster than an idle one; only the transition\n          into that rate is gradual.\n        */\n        const targetSpeed = 0.1 + (1 - Math.pow(cur.out - 1, 2)) * 0.9\n        if (snap) {\n          speed = targetSpeed\n          speedVel = 0\n        } else {\n          springStep(speed, speedVel, targetSpeed, dt, PARAM_EASE)\n          speed = springOut.x\n          speedVel = springOut.v\n        }\n        anim += dt * speed\n\n        gl.uniform1f(uTime, tSec * 0.5)\n        gl.uniform1f(uAnim, anim)\n        gl.uniform1f(uInput, cur.in)\n        gl.uniform1f(uOutput, cur.out)\n\n        // Resolution order per param: explicit `params` → `statePresets`\n        // prop → the variant's own preset → schema default. The two middle\n        // steps are per-key, so overriding one param of one state leaves the\n        // rest of that state alone. Values glide rather than snap.\n        const liveParams = paramsRef.current\n        const statePreset = presets?.[stateRef.current]\n        const overridePreset = statePresetsRef.current?.[stateRef.current]\n\n        for (const { def, loc } of paramLocs) {\n          const explicit = liveParams?.[def.key]\n          const target =\n            typeof explicit === \"number\"\n              ? explicit\n              : (overridePreset?.[def.key] ??\n                statePreset?.[def.key] ??\n                def.default)\n          const curVal = paramCur[def.key] ?? target\n          let next: number\n          if (snap) {\n            next = target\n            paramVel[def.key] = 0\n          } else {\n            springStep(curVal, paramVel[def.key] ?? 0, target, dt, PARAM_EASE)\n            next = springOut.x\n            paramVel[def.key] = springOut.v\n          }\n          paramCur[def.key] = next\n\n          if (def.integrate) {\n            const clock =\n              (paramClocks[def.key] ??\n                (paramClocks[def.key] = Math.random() * 100)) +\n              dt * speed * next\n            paramClocks[def.key] = clock\n            gl.uniform1f(loc, clock)\n          } else {\n            gl.uniform1f(loc, next)\n          }\n        }\n\n        // Same resolution order and same easing as params, so a state change\n        // cross-fades the palette instead of cutting to it.\n        const liveColors = colorsRef.current\n        const stateColor = variant.stateColors?.[stateRef.current]\n        const overrideColor = stateColorsRef.current?.[stateRef.current]\n        for (const { def, loc } of colorLocs) {\n          const target = hexToRgb(\n            liveColors?.[def.key] ??\n              overrideColor?.[def.key] ??\n              stateColor?.[def.key] ??\n              def.default\n          )\n          const curCol = (colorCur[def.key] ??= [...target] as [\n            number,\n            number,\n            number,\n          ])\n          const velCol = (colorVel[def.key] ??= [0, 0, 0])\n          for (let i = 0; i < 3; i++) {\n            if (snap) {\n              curCol[i] = target[i]\n              velCol[i] = 0\n            } else {\n              springStep(curCol[i], velCol[i], target[i], dt, PARAM_EASE)\n              curCol[i] = springOut.x\n              velCol[i] = springOut.v\n            }\n          }\n          gl.uniform3f(loc, curCol[0], curCol[1], curCol[2])\n        }\n\n        gl.clearColor(0, 0, 0, 0)\n        gl.clear(gl.COLOR_BUFFER_BIT)\n        gl.drawArrays(gl.TRIANGLES, 0, 3)\n        // Deferred a microtask: the first of these draws runs synchronously\n        // inside this effect, and a sync setState there trips the compiler\n        // lint. A microtask still resolves before the browser paints, so the\n        // reveal is not delayed by a frame.\n        if (!announcedPaint) {\n          announcedPaint = true\n          queueMicrotask(() => {\n            /*\n              Re-check: the context can be evicted between this draw and the\n              microtask, and mounting one more orb anywhere on the page is\n              enough to do it — opening the details drawer over a full gallery\n              is exactly that. Revealing on the strength of a frame that has\n              already been thrown away puts a dead canvas on screen, which is\n              what the browser draws its broken-canvas placeholder over. The\n              generation that follows the restore announces again.\n            */\n            if (gl.isContextLost()) return\n            setPaintedKey(variant.key)\n          })\n        }\n      }\n\n      const releaseGL = () => {\n        resizeObserver?.disconnect()\n        intersectionObserver?.disconnect()\n        gl.deleteProgram(prog)\n        gl.deleteShader(vs)\n        gl.deleteShader(fs)\n        gl.deleteBuffer(buf)\n      }\n\n      if (reduceMotion) {\n        // One representative frame, then stop — snapped straight onto the\n        // state's targets, since a spring would only be part-way there.\n        tSec = 1\n        uploadAndDraw(1, true)\n        return releaseGL\n      }\n\n      const loop = () => {\n        raf = requestAnimationFrame(loop)\n        const now = performance.now() / 1000\n        const dt = Math.min(now - last, 0.05)\n        last = now\n        if (!visible || pausedRef.current) return\n        tSec += dt\n\n        /*\n          Adaptive resolution. When the smoothed frame time sits above ~30fps,\n          the GPU is drowning in fragment work (these shaders are pure fill\n          cost), so step the backing store down 20% and re-measure. Steps only\n          go down — never back up — so the resolution can't oscillate. The\n          warm-up guard keeps page-load jank (hydration, first compiles) from\n          triggering a downgrade the GPU never asked for.\n        */\n        /*\n          Only unstalled frames are evidence about GPU fill cost. `dt` above is\n          clamped at 0.05, so a frame that hits the clamp is the main thread\n          having been blocked — a slider drag re-rendering React, a GC pause, a\n          tab regaining focus — and feeding those in made UI jank look\n          identical to a drowning GPU.\n        */\n        if (dt < 0.05) frameEma += (dt - frameEma) * 0.08\n\n        if (tSec > 1.5 && frameEma > 1 / 34 && resScale > 0.5) {\n          resScale = Math.max(0.5, resScale * 0.8)\n          frameEma = 1 / 60 // require fresh evidence before the next step\n          resize()\n        } else if (tSec > 1.5 && frameEma < 1 / 55 && resScale < 1) {\n          /*\n            And step back up once frames are comfortably fast again. This used\n            to be one-way, on the reasoning that it could not then oscillate —\n            but that also meant one transient stall permanently halved the\n            orb's resolution, and at half resolution a high-frequency shader\n            aliases into shimmer that reads as the shader itself misbehaving.\n            The gap between the two thresholds (29ms down, 18ms up) is the\n            hysteresis that stops it hunting.\n          */\n          resScale = Math.min(1, resScale / 0.8)\n          frameEma = 1 / 60\n          resize()\n        }\n\n        uploadAndDraw(dt)\n      }\n      /*\n        First frame synchronously, before entering the rAF loop. rAF does not\n        run at all in hidden documents (background tabs, embedded previews),\n        so a freshly mounted orb would otherwise sit fully transparent until\n        the page next becomes visible — a grid of mounted, healthy, blank\n        canvases. The sync frame guarantees every mount paints: background\n        documents get a static frame, visible ones start animating over it.\n        dt = 1 lands the param glide on its targets, as in the reduce-motion\n        frame above.\n      */\n      uploadAndDraw(1)\n      loop()\n\n      return () => {\n        cancelAnimationFrame(raf)\n        releaseGL()\n      }\n    }\n\n    /*\n      Wire the canvas's lifecycle controller. The listeners are attached ONCE\n      per canvas element and never removed, deliberately: the lost event must\n      be canceled even while no orb is mounted on the canvas — an uncanceled\n      webglcontextlost marks the context permanently unrestorable, and the\n      router can show this exact canvas again later. Whether a loss leads to\n      a revival is decided by `desired`, not by listener presence.\n    */\n    /*\n      A canvas whose context has gone is not simply blank: Chrome paints its\n      broken-image placeholder over the element's whole box — the white square\n      you see on a reloaded grid. Hide the canvas the moment the context is\n      lost, and let the generation that follows a restore reveal it again.\n    */\n    const hideNow = () => {\n      /*\n        Both, deliberately. The style write lands in this tick — the browser\n        paints its placeholder over a dead canvas immediately, and a busy main\n        thread can hold a React update for several frames. The state change is\n        what keeps React's own view in sync, so the reveal that follows a\n        restore clears the inline value again rather than fighting it.\n      */\n      canvas.style.opacity = \"0\"\n      setPaintedKey(null)\n    }\n\n    const onContextLostHide = () => hideNow()\n    canvas.addEventListener(\"webglcontextlost\", onContextLostHide)\n\n    /*\n      Hand the context back before the next document asks for one.\n\n      A hard reload never runs this effect's cleanup — the document is\n      discarded whole — so the outgoing page's contexts are still alive while\n      the incoming page allocates its own. On a grid of orbs that puts the\n      live count past the browser's ~16 cap, and the ones it evicts are\n      exactly the canvases that come back as placeholders until the restore\n      path catches them. `persisted` is a bfcache suspend, where the page is\n      shown again untouched and must keep everything it holds.\n    */\n    const onPageHide = (event: PageTransitionEvent) => {\n      if (event.persisted) return\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Already released — nothing to hand back.\n      }\n    }\n    window.addEventListener(\"pagehide\", onPageHide)\n\n    let ctl = canvasControllers.get(canvas)\n    if (!ctl) {\n      const created: CanvasContextController = {\n        desired: false,\n        start: null,\n        stopGen: null,\n      }\n      canvas.addEventListener(\"webglcontextlost\", (event) => {\n        event.preventDefault() // always cancel — keeps the context restorable\n        created.stopGen?.()\n        created.stopGen = null\n        if (created.desired) {\n          /*\n            Ask for the context back — but in a LATER task. The browser only\n            marks a loss as restorable once the lost event's dispatch has\n            completed and it has seen the canceled flag, so a restoreContext()\n            issued during dispatch (or before it, as the mount path may) is\n            silently refused. This is the path a synchronous cleanup+setup\n            pair hits — React re-running the effect on the same canvas loses\n            the context and wants it right back. For losses we didn't cause\n            (eviction, GPU reset) the call may refuse; the canceled event then\n            lets the browser restore on its own schedule.\n          */\n          setTimeout(() => {\n            if (!created.desired) return\n            try {\n              loseExt?.restoreContext()\n            } catch {\n              // Natural loss — restoration is the browser's call now.\n            }\n          }, 0)\n        }\n      })\n      canvas.addEventListener(\"webglcontextrestored\", () => {\n        if (created.desired && created.start) {\n          created.stopGen = created.start()\n        }\n      })\n      canvasControllers.set(canvas, created)\n      ctl = created\n    }\n    const controller = ctl\n\n    controller.desired = true\n    controller.start = startGeneration\n    if (gl.isContextLost()) {\n      // A previous run on this canvas released the context (effect re-run, or\n      // the router re-showing a kept-alive page). If the lost event already\n      // dispatched this request is honored now; if it is still queued, the\n      // lost handler above re-requests it on dispatch.\n      try {\n        loseExt?.restoreContext()\n      } catch {\n        // No restore path — the orb stays blank rather than throwing.\n      }\n    } else {\n      controller.stopGen = startGeneration()\n    }\n\n    return () => {\n      /*\n        Hide BEFORE tearing the context down.\n\n        This cleanup releases the context deliberately, and the lost event it\n        provokes is dispatched asynchronously — by which point the listener\n        below is unhooked and the replacement effect has not drawn yet. That\n        leaves a revealed canvas with a dead context, which is precisely what\n        the browser paints its broken-canvas placeholder over. The window is\n        not rare: any prop change in this effect's deps re-runs it, so it hits\n        every time the drawer switches preview example (maxDpr differs on the\n        layout one) or a wrapper is toggled.\n      */\n      hideNow()\n      canvas.removeEventListener(\"webglcontextlost\", onContextLostHide)\n      window.removeEventListener(\"pagehide\", onPageHide)\n      controller.desired = false\n      controller.start = null\n      controller.stopGen?.()\n      controller.stopGen = null\n      /*\n        Release the context NOW instead of when the canvas is garbage\n        collected. Browsers cap live WebGL contexts per page (~8–16) and evict\n        the oldest when the cap is hit — client-side navigation that unmounts\n        and remounts a page of orbs otherwise piles up zombie contexts until\n        freshly mounted orbs get evicted and render blank.\n      */\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Context already lost — nothing to release.\n      }\n    }\n    /*\n      `wrapped` is in here because turning a wrapper on or off moves the canvas\n      from being this component's root element to being a child of the wrapper\n      div — React drops the old element and mounts a new one, and the GL\n      context, its observers and its render loop all belong to the old one. Any\n      other prop leaves the element alone, INCLUDING a swap between two\n      wrappers: the canvas keeps its slot among the decoration layers, so\n      glass -> ring reuses the context instead of rebuilding it.\n    */\n  }, [variant, pauseOffscreen, maxDpr, wrapped])\n\n  const sizeStyle: CSSProperties =\n    size === undefined ? {} : { width: size, height: size }\n\n  /*\n    Spread ahead of the caller's `style`, so an orb that wants to own its own\n    opacity still can — it simply opts out of the reveal.\n\n    A hard flip, deliberately: no transition, no fade. A hidden document\n    (background tab, embedded preview) does not advance CSS transitions, so a\n    faded reveal left orbs pinned at zero in exactly the case the synchronous\n    first frame above exists to serve — mounted, healthy, and invisible. The\n    cut is not a pop either way, since it happens on the frame the orb first\n    has something to show.\n  */\n  const revealStyle: CSSProperties = painted ? {} : { opacity: 0 }\n\n  const canvas = (\n    <canvas\n      // A lost WebGL context can't be reused, so each variant gets a fresh canvas.\n      key={variant.key}\n      ref={canvasRef}\n      className={spec ? undefined : className}\n      style={\n        spec\n          ? {\n              display: \"block\",\n              position: \"absolute\",\n              left: `${spec.inset}%`,\n              top: `${spec.inset}%`,\n              width: `${100 - 2 * spec.inset}%`,\n              height: `${100 - 2 * spec.inset}%`,\n              ...revealStyle,\n              ...(spec.mask ? masked(spec.mask) : {}),\n            }\n          : { display: \"block\", ...sizeStyle, ...revealStyle, ...style }\n      }\n      role={!spec && ariaLabel ? \"img\" : undefined}\n      aria-label={spec ? undefined : ariaLabel}\n      aria-hidden={!spec && ariaLabel ? undefined : true}\n    />\n  )\n\n  if (!spec) return canvas\n\n  /*\n    Wrapped: the box becomes the orb's footprint and the canvas is absolutely\n    positioned inside it. `under`, the canvas and `over` are all positioned\n    with an auto z-index, so they paint in DOM order — decoration behind the\n    orb, then the orb, then decoration in front of it.\n\n    `aspectRatio` is the fallback for the sizeless case: `size` is optional\n    (callers may size the orb with a class instead), and an absolutely\n    positioned canvas contributes nothing to its parent's height, so without\n    it a class that only sets a width would collapse the box to zero.\n  */\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"relative\",\n        aspectRatio: \"1 / 1\",\n        ...(spec.shadow ? { borderRadius: \"50%\", boxShadow: spec.shadow } : {}),\n        ...sizeStyle,\n        ...(wrapperColor ? { color: wrapperColor } : {}),\n        ...style,\n      }}\n      role={ariaLabel ? \"img\" : undefined}\n      aria-label={ariaLabel}\n      aria-hidden={ariaLabel ? undefined : true}\n    >\n      {spec.animated ? (\n        <style\n          href={WRAPPER_STYLE_HREF}\n          precedence=\"default\"\n          dangerouslySetInnerHTML={{ __html: WRAPPER_CSS }}\n        />\n      ) : null}\n      {spec.under}\n      {canvas}\n      {spec.over}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/examples/research-workflow.ts",
          "target": "@components/examples/research-workflow.ts",
          "type": "registry:component",
          "content": "export interface ResearchNote {\n  id: string\n  title: string\n  text: string\n  attached?: boolean\n}\nexport const researchProjects = [\n  {\n    id: \"field-notes\",\n    title: \"West dock interviews\",\n    subtitle: \"Field research · 5 interviews\",\n    question: \"What is slowing down the handoff?\",\n    notes: [\n      {\n        id: \"interview\",\n        title: \"Operator interviews\",\n        text: \"Four of five operators enter the same shipment identifier twice: first on paper, then on a shared tablet. The tablet often arrives after the paper sheet.\",\n      },\n      {\n        id: \"shift\",\n        title: \"Shift-change observation\",\n        text: \"At both observed shift changes, operators checked the clipboard and tablet before confirming which shipment record was current.\",\n      },\n      {\n        id: \"map\",\n        title: \"Workflow map\",\n        text: \"Paper, radio, and tablet steps each copy the shipment identifier. No step owns the canonical record. The team proposed confirming one record at intake and showing its sync status.\",\n      },\n    ],\n  },\n  {\n    id: \"accessibility\",\n    title: \"Wayfinding audit\",\n    subtitle: \"Station arrival · 2 observations\",\n    question: \"What should change in the station signs?\",\n    notes: [\n      {\n        id: \"arrival\",\n        title: \"Arrival walk-through\",\n        text: \"Three visitors paused before the platform turn. Transfer signs compete with advertising at the decision point, and the destination label changes between signs.\",\n      },\n      {\n        id: \"signs\",\n        title: \"Signage review\",\n        text: \"Repeat the same destination label at eye level before each turn. Keep arrows together with the label and validate the route with first-time visitors.\",\n      },\n    ],\n  },\n  {\n    id: \"handoff\",\n    title: \"Research handoff\",\n    subtitle: \"Product team · review brief\",\n    question: \"What needs to be in the handoff?\",\n    notes: [\n      {\n        id: \"review\",\n        title: \"Team review\",\n        text: \"The product team needs observed behavior, interpretation, and open questions separated. Every finding should include a field-note reference and a named owner for validation.\",\n      },\n      {\n        id: \"next\",\n        title: \"Next research round\",\n        text: \"Test the intake confirmation with two operators during one shift. Compare duplicate-entry frequency and ask each operator to identify the current shipment record.\",\n      },\n    ],\n  },\n]\n\n/** Extractive local demo: return the selected notes, never invented research. */\nexport function researchAnswer(\n  question: string,\n  notes: ResearchNote[],\n  concise = false\n) {\n  if (!notes.length)\n    return \"This conversation has no source notes yet. Attach a text note or open one of the research projects to ask about its evidence.\"\n  const terms =\n    question\n      .toLowerCase()\n      .match(/[a-z]{4,}/g)\n      ?.filter(\n        (word) =>\n          ![\n            \"what\",\n            \"with\",\n            \"from\",\n            \"that\",\n            \"this\",\n            \"about\",\n            \"should\",\n            \"could\",\n            \"please\",\n          ].includes(word)\n      ) ?? []\n  const ranked = notes\n    .map((note, index) => ({\n      note,\n      index,\n      score: terms.filter((term) =>\n        `${note.title} ${note.text}`.toLowerCase().includes(term)\n      ).length,\n    }))\n    .sort((a, b) => b.score - a.score)\n  const relevant =\n    ranked[0].score > 0 ? ranked.filter((item) => item.score > 0) : ranked\n  const chosen = relevant.slice(0, concise ? 1 : 3)\n  return `From ${chosen.length === 1 ? \"the selected note\" : \"the selected notes\"}:\\n\\n${chosen.map(({ note, index }) => `${note.text.slice(0, concise ? 220 : 480)}${note.text.length > (concise ? 220 : 480) ? \"…\" : \"\"} [${index + 1}]`).join(\"\\n\\n\")}`\n}\n\nexport function researchReport(\n  title: string,\n  notes: ResearchNote[],\n  answer: string\n) {\n  return `${title}\\n\\nRESEARCH BRIEF\\n\\n${answer}\\n\\nSOURCE NOTES\\n${notes.map((note, index) => `${index + 1}. ${note.title}\\n${note.text}`).join(\"\\n\\n\")}\\n\\nReview these observations with the project team before taking action.`\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE",
          "target": "@components/voice-agents/orbkit/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 zzzzshawn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/orbkit/SOURCE.json",
          "target": "@components/voice-agents/orbkit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"OrbKit\",\n  \"repository\": \"https://github.com/zzzzshawn/orbkit\",\n  \"commit\": \"35e42484560fd35e8502703ba58fa99541d8c686\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 zzzzshawn\",\n  \"core\": \"components/voice-agents/orbkit/core.tsx\",\n  \"credits\": \"components/voice-agents/orbkit/CREDITS.md\",\n  \"shaderLicense\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\",\n  \"changes\": [\n    \"Moved the dependency-free OrbKit runtime and selected variants into the Agents Kit voice collection.\",\n    \"Mapped variant imports to the local shared runtime.\",\n    \"Kept the upstream reduced-motion, offscreen pause, DPR cap, context recovery, and cleanup behavior.\"\n  ],\n  \"exclusions\": [\n    {\n      \"name\": \"shdr-19\",\n      \"reason\": \"Non-commercial XorDev shader; excluded from this distributable MIT collection.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    },\n    {\n      \"name\": \"XorDev shader ports\",\n      \"reason\": \"All variants listed under Shaders by XorDev in CREDITS.md are non-commercial and excluded.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    }\n  ],\n  \"components\": [\n    {\n      \"name\": \"shdr-11\",\n      \"path\": \"shdr-11.tsx\",\n      \"title\": \"Hydrogen\"\n    },\n    {\n      \"name\": \"shdr-13\",\n      \"path\": \"shdr-13.tsx\",\n      \"title\": \"Ion\"\n    },\n    {\n      \"name\": \"shdr-14\",\n      \"path\": \"shdr-14.tsx\",\n      \"title\": \"Dither\"\n    },\n    {\n      \"name\": \"shdr-21\",\n      \"path\": \"shdr-21.tsx\",\n      \"title\": \"Nimbus\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/CREDITS.md",
          "target": "@components/voice-agents/orbkit/CREDITS.md",
          "type": "registry:file",
          "content": "# Credits\n\nOrbkit ships two kinds of orb. Every file says which it is.\n\n## Shaders by XorDev\n\nThese 19 orbs are ported from golfed shaders by [XorDev](https://x.com/XorDev),\nused with his permission (agreed by direct message on 2026-09-06). Terms:\n**non-commercial use only, with attribution to XorDev**. Each file starts with\na notice that must stay with any copy, and the registry marks these items with\na `credit` field. See [LICENSE-SHADERS.md](LICENSE-SHADERS.md).\n\n| Orb     | Shader by | Original             |\n| ------- | --------- | -------------------- |\n| shdr-01 | XorDev    | https://x.com/XorDev |\n| shdr-02 | XorDev    | https://x.com/XorDev |\n| shdr-03 | XorDev    | https://x.com/XorDev |\n| shdr-04 | XorDev    | https://x.com/XorDev |\n| shdr-05 | XorDev    | https://x.com/XorDev |\n| shdr-06 | XorDev    | https://x.com/XorDev |\n| shdr-07 | XorDev    | https://x.com/XorDev |\n| shdr-08 | XorDev    | https://x.com/XorDev |\n| shdr-09 | XorDev    | https://x.com/XorDev |\n| shdr-10 | XorDev    | https://x.com/XorDev |\n| shdr-15 | XorDev    | https://x.com/XorDev |\n| shdr-18 | XorDev    | https://x.com/XorDev |\n| shdr-19 | XorDev    | https://x.com/XorDev |\n| shdr-20 | XorDev    | https://x.com/XorDev |\n| shdr-22 | XorDev    | https://x.com/XorDev |\n| shdr-25 | XorDev    | https://x.com/XorDev |\n| shdr-26 | XorDev    | https://x.com/XorDev |\n| shdr-28 | XorDev    | https://x.com/XorDev |\n| shdr-31 | XorDev    | https://x.com/XorDev |\n\nReplace a profile link with the specific post once it is known.\n\n## Original orbs\n\nThese 14 orbs are Orbkit's own work and are MIT-licensed, like the runtime:\nshdr-11, shdr-12, shdr-13, shdr-14, shdr-16, shdr-17, shdr-21, shdr-23, shdr-24, shdr-27, shdr-29, shdr-30, shdr-32, shdr-33.\n\n## Adding shaders\n\nAsk the original author before porting anything that is not your own. XorDev\nasked to be consulted before any more of his work is included.\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "target": "@components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "type": "registry:file",
          "content": "# Licence for the ported shaders\n\nThe orb files listed under \"Shaders by XorDev\" in [CREDITS.md](CREDITS.md) are\nderived from shaders by XorDev (https://x.com/XorDev) and are used with the\nauthor's permission on these terms:\n\n1. Non-commercial use only.\n2. Attribution to XorDev must be kept with every copy, including the notice at\n   the top of each file.\n3. Any further use of XorDev's work requires asking the author first.\n\nEverything else in this repository, including the runtime\n(`orbkit-core.tsx`), the site, the build scripts, and the original orbs, is\nlicensed under the MIT licence in [LICENSE](LICENSE).\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "App examples"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "example-chat-app",
      "type": "registry:block",
      "title": "Example Chat App",
      "description": "Start with a question or source note, then switch to voice without losing your draft.",
      "dependencies": [
        "@radix-ui/react-avatar@^1.1.3",
        "@radix-ui/react-slot@^1.2.2",
        "@radix-ui/react-tooltip@^1.2.6",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "lucide-react@0.577.0",
        "marked@^15.0.7",
        "motion@12.26.2",
        "next-themes@^0.4.4",
        "radix-ui@1.6.7",
        "react-aria-components@^1.21.1",
        "react-markdown@^10.1.0",
        "remark-breaks@^4.0.0",
        "remark-gfm@^4.0.1",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6",
        "use-stick-to-bottom@^1.1.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/examples/chat-app.tsx",
          "target": "@components/examples/chat-app.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { ConversationAppExample } from \"./conversation-app\"\n\nexport function ChatAppExample() {\n  return (\n    <ConversationAppExample className=\"h-[760px] overflow-hidden rounded-[14px] border\" />\n  )\n}\n"
        },
        {
          "path": "components/examples/conversation-app.tsx",
          "target": "@components/examples/conversation-app.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  ChatContainerContent,\n  ChatContainerRoot,\n} from \"@/components/prompt-kit/chat-container\"\nimport { Loader } from \"@/components/prompt-kit/loader\"\nimport { Message, MessageContent } from \"@/components/prompt-kit/message\"\nimport {\n  PromptInput,\n  PromptInputAction,\n  PromptInputActions,\n  PromptInputTextarea,\n} from \"@/components/prompt-kit/prompt-input\"\nimport { PromptSuggestion } from \"@/components/prompt-kit/prompt-suggestion\"\nimport { Button } from \"@/components/ui/button\"\nimport { ThemeToggle } from \"@/components/ui/theme-toggle\"\nimport { AgentTrackToggle } from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport { Shdr21 } from \"@/components/voice-agents/orbkit/shdr-21\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  ArrowUp,\n  AudioLines,\n  FileText,\n  Paperclip,\n  Square,\n  X,\n} from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\nimport {\n  researchAnswer,\n  researchProjects,\n  type ResearchNote,\n} from \"./research-workflow\"\n\ntype Turn = {\n  id: number\n  role: \"user\" | \"assistant\"\n  text: string\n  input: \"text\" | \"voice\"\n}\nconst starters = [\n  \"Summarize the dock interviews\",\n  \"What should the team change first?\",\n]\nconst sampleSpokenQuestion = \"What is slowing down the dock handoff?\"\n\n/** Composition of kit components with shared text and voice demo state. */\nexport function ConversationAppExample({\n  initialVoice = false,\n  className,\n}: {\n  initialVoice?: boolean\n  className?: string\n} = {}) {\n  const [voice, setVoice] = useState(initialVoice)\n  const [phase, setPhase] = useState<\"idle\" | \"thinking\" | \"speaking\">(\"idle\")\n  const [draft, setDraft] = useState(\"\")\n  const [turns, setTurns] = useState<Turn[]>([])\n  const [muted, setMuted] = useState(false)\n  const [concise, setConcise] = useState(true)\n  const [attachment, setAttachment] = useState<ResearchNote | null>(null)\n  const [notice, setNotice] = useState(\"\")\n  const sequence = useRef(0)\n  const attachmentVersion = useRef(0)\n  const replyTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n  const settleTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n  const fileInput = useRef<HTMLInputElement>(null)\n  const composer = useRef<HTMLDivElement>(null)\n  const reduce = useReducedMotion()\n  const centered = !voice && turns.length === 0\n  const thinking = phase === \"thinking\"\n\n  const clearTimers = () => {\n    if (replyTimer.current) clearTimeout(replyTimer.current)\n    if (settleTimer.current) clearTimeout(settleTimer.current)\n    replyTimer.current = null\n    settleTimer.current = null\n  }\n  useEffect(() => clearTimers, [])\n\n  const send = (text: string, input: Turn[\"input\"] = \"text\") => {\n    if (!text.trim() || thinking || (input === \"voice\" && muted)) return\n    clearTimers()\n    const answer = researchAnswer(\n      text,\n      attachment ? [attachment] : researchProjects[0].notes,\n      concise\n    )\n    const turn: Turn = {\n      id: ++sequence.current,\n      role: \"user\",\n      text: text.trim(),\n      input,\n    }\n    setTurns((current) => [...current, turn])\n    if (input === \"text\") setDraft(\"\")\n    setNotice(\"\")\n    setPhase(\"thinking\")\n    replyTimer.current = setTimeout(() => {\n      const reply: Turn = {\n        id: ++sequence.current,\n        role: \"assistant\",\n        text: answer,\n        input,\n      }\n      setTurns((current) => [...current, reply])\n      setPhase(\"speaking\")\n      replyTimer.current = null\n      settleTimer.current = setTimeout(() => {\n        setPhase(\"idle\")\n        settleTimer.current = null\n      }, 1800)\n    }, 900)\n  }\n  const toggleVoice = () => {\n    setVoice((current) => !current)\n    setNotice(\"\")\n    requestAnimationFrame(() =>\n      composer.current?.querySelector(\"textarea\")?.focus()\n    )\n  }\n  const stop = () => {\n    clearTimers()\n    setPhase(\"idle\")\n    setNotice(\"Response stopped. You can continue the conversation.\")\n  }\n  const reset = () => {\n    clearTimers()\n    setTurns([])\n    setDraft(\"\")\n    setVoice(initialVoice)\n    setPhase(\"idle\")\n    setMuted(false)\n    setConcise(true)\n    attachmentVersion.current += 1\n    setAttachment(null)\n    setNotice(\"\")\n  }\n  const attach = async (file?: File) => {\n    if (!file) return\n    const version = ++attachmentVersion.current\n    if (!/\\.(txt|md|csv)$/i.test(file.name) || file.size > 64 * 1024) {\n      setNotice(\"Choose a text, Markdown, or CSV note under 64 KB.\")\n      return\n    }\n    try {\n      const text = await file.text()\n      if (version !== attachmentVersion.current) return\n      setAttachment({ id: file.name, title: file.name, text })\n      setNotice(\"\")\n    } catch {\n      if (version === attachmentVersion.current)\n        setNotice(\"That note could not be read. Try another file.\")\n    }\n  }\n  const stateLabel = thinking\n    ? \"Thinking\"\n    : phase === \"speaking\"\n      ? \"Speaking\"\n      : muted\n        ? \"Microphone muted\"\n        : \"Listening\"\n\n  return (\n    <section\n      aria-label=\"Fieldwork conversation\"\n      data-conversation-preview\n      data-app-example={initialVoice ? \"voice\" : \"chat\"}\n      className={cn(\n        \"bg-background text-foreground flex h-dvh min-h-[560px] flex-col\",\n        className\n      )}\n    >\n      <header className=\"border-border flex h-16 shrink-0 items-center justify-between gap-3 border-b px-4 sm:px-8\">\n        <div className=\"min-w-0\">\n          <p className=\"text-sm font-medium\">Fieldwork assistant</p>\n          <p className=\"text-muted-foreground truncate text-xs\">\n            Agents Kit · Conversation example\n          </p>\n        </div>\n        <div className=\"flex shrink-0 items-center gap-2\">\n          <Button\n            variant=\"ghost\"\n            size=\"sm\"\n            onClick={reset}\n            className=\"text-muted-foreground text-xs\"\n          >\n            Reset preview\n          </Button>\n          <ThemeToggle />\n        </div>\n      </header>\n\n      <div className=\"relative mx-auto flex min-h-0 w-full max-w-3xl flex-1 flex-col px-4 sm:px-6\">\n        <ChatContainerRoot data-transcript className=\"min-h-0 flex-1\">\n          <ChatContainerContent className=\"gap-6 px-1 pt-8 pb-8 sm:px-2\">\n            {turns.map((turn) => (\n              <Message\n                key={turn.id}\n                data-turn={turn.id}\n                data-input={turn.input}\n                className={cn(turn.role === \"user\" && \"justify-end\")}\n              >\n                <div\n                  className={cn(\n                    \"min-w-0\",\n                    turn.role === \"user\" ? \"max-w-[90%]\" : \"w-full\"\n                  )}\n                >\n                  <p className=\"text-muted-foreground mb-1.5 flex items-center gap-1.5 text-xs\">\n                    {turn.role === \"user\" ? \"You\" : \"Fieldwork assistant\"}\n                    {turn.input === \"voice\" && turn.role === \"user\" && (\n                      <>\n                        <AudioLines className=\"size-3\" aria-hidden />\n                        Voice\n                      </>\n                    )}\n                  </p>\n                  <MessageContent\n                    className={cn(\n                      \"max-w-none text-sm leading-6 whitespace-pre-wrap\",\n                      turn.role === \"assistant\"\n                        ? \"bg-transparent p-0\"\n                        : \"px-3 py-2.5\"\n                    )}\n                  >\n                    {turn.text}\n                  </MessageContent>\n                </div>\n              </Message>\n            ))}\n            {thinking && (\n              <div\n                role=\"status\"\n                className=\"text-muted-foreground flex items-center gap-2 text-xs\"\n              >\n                <Loader variant=\"typing\" size=\"sm\" />\n                Reading the notes…\n              </div>\n            )}\n          </ChatContainerContent>\n        </ChatContainerRoot>\n\n        <motion.div\n          ref={composer}\n          layout=\"position\"\n          data-composer-position\n          transition={{ duration: reduce ? 0 : 0.3, ease: [0.2, 0, 0, 1] }}\n          className={cn(\n            \"relative w-full shrink-0 pb-4\",\n            centered && \"absolute inset-x-0 bottom-[38%] px-4 sm:px-6\"\n          )}\n        >\n          {centered && (\n            <div className=\"mb-6\">\n              <h1 className=\"text-2xl leading-8 font-normal tracking-tight\">\n                Work with your field notes\n              </h1>\n              <p className=\"text-muted-foreground mt-2 text-sm\">\n                Ask a question, talk it through, or add a source.\n              </p>\n            </div>\n          )}\n          <AnimatePresence initial={false}>\n            {voice && (\n              <motion.div\n                key=\"voice\"\n                initial={{ opacity: 0, y: reduce ? 0 : 6 }}\n                animate={{ opacity: 1, y: 0 }}\n                exit={{ opacity: 0 }}\n                transition={{ duration: reduce ? 0 : 0.15 }}\n                className=\"mb-4 flex items-center gap-4 px-1\"\n              >\n                <div data-voice-orb className=\"size-20 shrink-0\">\n                  <Shdr21\n                    size={80}\n                    state={phase}\n                    maxDpr={2}\n                    pauseOffscreen\n                    ariaLabel={`${stateLabel} voice orb`}\n                  />\n                </div>\n                <div className=\"min-w-0\">\n                  <p role=\"status\" className=\"text-sm font-medium\">\n                    {stateLabel}\n                  </p>\n                  <p className=\"text-muted-foreground mt-1 text-xs leading-5\">\n                    Voice and typing share this conversation.\n                  </p>\n                </div>\n              </motion.div>\n            )}\n          </AnimatePresence>\n\n          <PromptInput\n            data-composer\n            value={draft}\n            onValueChange={setDraft}\n            onSubmit={() => send(draft)}\n            isLoading={thinking}\n            maxHeight={144}\n            className=\"bg-card focus-within:ring-ring rounded-xl p-2 focus-within:ring-1\"\n          >\n            {attachment && (\n              <div className=\"bg-secondary mb-2 flex w-fit max-w-full items-center gap-2 rounded-md px-2 py-1 text-xs\">\n                <FileText className=\"size-3.5 shrink-0\" aria-hidden />\n                <span className=\"truncate\">{attachment.title}</span>\n                <Button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  className=\"size-6\"\n                  aria-label=\"Remove context note\"\n                  onClick={() => {\n                    attachmentVersion.current += 1\n                    setAttachment(null)\n                  }}\n                >\n                  <X className=\"size-3\" />\n                </Button>\n              </div>\n            )}\n            <PromptInputTextarea\n              data-conversation-input\n              aria-label=\"Message\"\n              placeholder={\n                voice\n                  ? \"Keep typing while voice is on…\"\n                  : \"Ask about your field notes…\"\n              }\n              className=\"min-h-12 px-2 py-2 text-base sm:text-sm\"\n            />\n            <PromptInputActions className=\"justify-between gap-2 pt-1\">\n              <div className=\"flex min-w-0 items-center gap-1\">\n                <PromptInputAction tooltip=\"Add a text, Markdown, or CSV note\">\n                  <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    aria-label=\"Add context note\"\n                    onClick={() => fileInput.current?.click()}\n                  >\n                    <Paperclip />\n                  </Button>\n                </PromptInputAction>\n                <PromptInputAction\n                  tooltip={\n                    concise ? \"Use a detailed answer\" : \"Use a concise answer\"\n                  }\n                >\n                  <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    aria-label=\"Concise answers\"\n                    aria-pressed={concise}\n                    onClick={() => setConcise((value) => !value)}\n                    className=\"text-muted-foreground text-xs\"\n                  >\n                    {concise ? \"Concise\" : \"Detailed\"}\n                  </Button>\n                </PromptInputAction>\n              </div>\n              <div className=\"flex shrink-0 items-center gap-2\">\n                {voice && (\n                  <PromptInputAction\n                    tooltip={muted ? \"Unmute microphone\" : \"Mute microphone\"}\n                  >\n                    <AgentTrackToggle\n                      source=\"microphone\"\n                      pressed={!muted}\n                      onPressedChange={(enabled) => setMuted(!enabled)}\n                      aria-label={\n                        muted ? \"Unmute microphone\" : \"Mute microphone\"\n                      }\n                    />\n                  </PromptInputAction>\n                )}\n                <PromptInputAction\n                  tooltip={voice ? \"Return to typing\" : \"Start voice mode\"}\n                >\n                  <Button\n                    type=\"button\"\n                    variant={voice ? \"secondary\" : \"outline\"}\n                    size=\"icon\"\n                    aria-label={voice ? \"Exit voice mode\" : \"Enter voice mode\"}\n                    onClick={toggleVoice}\n                  >\n                    {voice ? <X /> : <AudioLines />}\n                  </Button>\n                </PromptInputAction>\n                <PromptInputAction\n                  tooltip={thinking ? \"Stop response\" : \"Send message\"}\n                >\n                  <Button\n                    type=\"button\"\n                    size=\"icon\"\n                    disabled={!thinking && !draft.trim()}\n                    aria-label={thinking ? \"Stop response\" : \"Send message\"}\n                    onClick={thinking ? stop : () => send(draft)}\n                  >\n                    {thinking ? (\n                      <Square className=\"size-3.5 fill-current\" />\n                    ) : (\n                      <ArrowUp />\n                    )}\n                  </Button>\n                </PromptInputAction>\n              </div>\n            </PromptInputActions>\n          </PromptInput>\n          <input\n            ref={fileInput}\n            type=\"file\"\n            accept=\".txt,.md,.csv\"\n            className=\"sr-only\"\n            aria-label=\"Context note file\"\n            onChange={(event) => {\n              void attach(event.currentTarget.files?.[0])\n              event.currentTarget.value = \"\"\n            }}\n          />\n          {notice && (\n            <p role=\"status\" className=\"text-muted-foreground mt-3 text-xs\">\n              {notice}\n            </p>\n          )}\n          {centered && (\n            <div className=\"mt-4 flex flex-wrap gap-2\">\n              {starters.map((text) => (\n                <PromptSuggestion\n                  key={text}\n                  size=\"sm\"\n                  className=\"h-auto min-h-8 rounded-lg text-xs font-normal whitespace-normal\"\n                  onClick={() => send(text)}\n                >\n                  {text}\n                </PromptSuggestion>\n              ))}\n            </div>\n          )}\n          {voice && (\n            <div className=\"mt-3 flex justify-end\">\n              <Button\n                variant=\"link\"\n                size=\"sm\"\n                disabled={muted || thinking}\n                onClick={() => send(sampleSpokenQuestion, \"voice\")}\n                className=\"text-muted-foreground h-7 px-0 text-xs\"\n              >\n                Try a sample voice turn\n              </Button>\n            </div>\n          )}\n        </motion.div>\n      </div>\n      <footer className=\"text-muted-foreground border-border flex shrink-0 flex-wrap items-center justify-between gap-2 border-t px-4 py-3 text-[11px] sm:px-8\">\n        <span>Interactive demo · sample replies · no microphone recording</span>\n        <details className=\"relative\">\n          <summary className=\"cursor-pointer\">Components used</summary>\n          <div className=\"bg-popover text-popover-foreground absolute right-0 bottom-full z-20 mb-3 w-64 rounded-lg border p-4 text-xs shadow-sm\">\n            <p className=\"mb-2 font-medium\">Composed from Agents Kit</p>\n            <ul className=\"space-y-2\">\n              <li>\n                Prompt Kit: input, messages, scrolling, suggestions, loader\n              </li>\n              <li>LiveKit: microphone toggle</li>\n              <li>OrbKit: Nimbus</li>\n              <li>Shared buttons and theme tokens</li>\n            </ul>\n          </div>\n        </details>\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/prompt-kit/chat-container.tsx",
          "target": "@components/prompt-kit/chat-container.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { StickToBottom } from \"use-stick-to-bottom\"\n\nexport type ChatContainerRootProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport type ChatContainerContentProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport type ChatContainerScrollAnchorProps = {\n  className?: string\n  ref?: React.RefObject<HTMLDivElement>\n} & React.HTMLAttributes<HTMLDivElement>\n\nfunction ChatContainerRoot({\n  children,\n  className,\n  ...props\n}: ChatContainerRootProps) {\n  return (\n    <StickToBottom\n      className={cn(\"flex overflow-y-auto\", className)}\n      resize=\"smooth\"\n      initial=\"instant\"\n      role=\"log\"\n      {...props}\n    >\n      {children}\n    </StickToBottom>\n  )\n}\n\nfunction ChatContainerContent({\n  children,\n  className,\n  ...props\n}: ChatContainerContentProps) {\n  return (\n    <StickToBottom.Content\n      className={cn(\"flex w-full flex-col\", className)}\n      {...props}\n    >\n      {children}\n    </StickToBottom.Content>\n  )\n}\n\nfunction ChatContainerScrollAnchor({\n  className,\n  ...props\n}: ChatContainerScrollAnchorProps) {\n  return (\n    <div\n      className={cn(\"h-px w-full shrink-0 scroll-mt-4\", className)}\n      aria-hidden=\"true\"\n      {...props}\n    />\n  )\n}\n\nexport { ChatContainerRoot, ChatContainerContent, ChatContainerScrollAnchor }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/prompt-kit/loader.tsx",
          "target": "@components/prompt-kit/loader.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React from \"react\"\n\nexport interface LoaderProps {\n  variant?:\n    | \"circular\"\n    | \"classic\"\n    | \"pulse\"\n    | \"pulse-dot\"\n    | \"dots\"\n    | \"typing\"\n    | \"wave\"\n    | \"bars\"\n    | \"terminal\"\n    | \"text-blink\"\n    | \"text-shimmer\"\n    | \"loading-dots\"\n  size?: \"sm\" | \"md\" | \"lg\"\n  text?: string\n  className?: string\n}\n\nexport function CircularLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"border-primary animate-spin rounded-full border-2 border-t-transparent\",\n        sizeClasses[size],\n        className\n      )}\n    >\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function ClassicLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  const barSizes = {\n    sm: { height: \"6px\", width: \"1.5px\" },\n    md: { height: \"8px\", width: \"2px\" },\n    lg: { height: \"10px\", width: \"2.5px\" },\n  }\n\n  return (\n    <div className={cn(\"relative\", sizeClasses[size], className)}>\n      <div className=\"absolute h-full w-full\">\n        {[...Array(12)].map((_, i) => (\n          <div\n            key={i}\n            className=\"bg-primary absolute animate-[spinner-fade_1.2s_linear_infinite] rounded-full\"\n            style={{\n              top: \"0\",\n              left: \"50%\",\n              marginLeft:\n                size === \"sm\" ? \"-0.75px\" : size === \"lg\" ? \"-1.25px\" : \"-1px\",\n              transformOrigin: `${size === \"sm\" ? \"0.75px\" : size === \"lg\" ? \"1.25px\" : \"1px\"} ${size === \"sm\" ? \"10px\" : size === \"lg\" ? \"14px\" : \"12px\"}`,\n              transform: `rotate(${i * 30}deg)`,\n              opacity: 0,\n              animationDelay: `${i * 0.1}s`,\n              height: barSizes[size].height,\n              width: barSizes[size].width,\n            }}\n          />\n        ))}\n      </div>\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function PulseLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  return (\n    <div className={cn(\"relative\", sizeClasses[size], className)}>\n      <div className=\"border-primary absolute inset-0 animate-[thin-pulse_1.5s_ease-in-out_infinite] rounded-full border-2\" />\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function PulseDotLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-1\",\n    md: \"size-2\",\n    lg: \"size-3\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"bg-primary animate-[pulse-dot_1.2s_ease-in-out_infinite] rounded-full\",\n        sizeClasses[size],\n        className\n      )}\n    >\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function DotsLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const dotSizes = {\n    sm: \"h-1.5 w-1.5\",\n    md: \"h-2 w-2\",\n    lg: \"h-2.5 w-2.5\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[bounce-dots_1.4s_ease-in-out_infinite] rounded-full\",\n            dotSizes[size]\n          )}\n          style={{\n            animationDelay: `${i * 160}ms`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TypingLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const dotSizes = {\n    sm: \"h-1 w-1\",\n    md: \"h-1.5 w-1.5\",\n    lg: \"h-2 w-2\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[typing_1s_infinite] rounded-full\",\n            dotSizes[size]\n          )}\n          style={{\n            animationDelay: `${i * 250}ms`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function WaveLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const barWidths = {\n    sm: \"w-0.5\",\n    md: \"w-0.5\",\n    lg: \"w-1\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  const heights = {\n    sm: [\"6px\", \"9px\", \"12px\", \"9px\", \"6px\"],\n    md: [\"8px\", \"12px\", \"16px\", \"12px\", \"8px\"],\n    lg: [\"10px\", \"15px\", \"20px\", \"15px\", \"10px\"],\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center gap-0.5\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(5)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[wave_1s_ease-in-out_infinite] rounded-full\",\n            barWidths[size]\n          )}\n          style={{\n            animationDelay: `${i * 100}ms`,\n            height: heights[size][i],\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function BarsLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const barWidths = {\n    sm: \"w-1\",\n    md: \"w-1.5\",\n    lg: \"w-2\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4 gap-1\",\n    md: \"h-5 gap-1.5\",\n    lg: \"h-6 gap-2\",\n  }\n\n  return (\n    <div className={cn(\"flex\", containerSizes[size], className)}>\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary h-full animate-[wave-bars_1.2s_ease-in-out_infinite]\",\n            barWidths[size]\n          )}\n          style={{\n            animationDelay: `${i * 0.2}s`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TerminalLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const cursorSizes = {\n    sm: \"h-3 w-1.5\",\n    md: \"h-4 w-2\",\n    lg: \"h-5 w-2.5\",\n  }\n\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      <span className={cn(\"text-primary font-mono\", textSizes[size])}>\n        {\">\"}\n      </span>\n      <div\n        className={cn(\n          \"bg-primary animate-[blink_1s_step-end_infinite]\",\n          cursorSizes[size]\n        )}\n      />\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TextBlinkLoader({\n  text = \"Thinking\",\n  className,\n  size = \"md\",\n}: {\n  text?: string\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"animate-[text-blink_2s_ease-in-out_infinite] font-medium\",\n        textSizes[size],\n        className\n      )}\n    >\n      {text}\n    </div>\n  )\n}\n\nexport function TextShimmerLoader({\n  text = \"Thinking\",\n  className,\n  size = \"md\",\n}: {\n  text?: string\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"bg-[linear-gradient(to_right,var(--muted-foreground)_40%,var(--foreground)_60%,var(--muted-foreground)_80%)]\",\n        \"bg-size-[200%_auto] bg-clip-text font-medium text-transparent\",\n        \"animate-[shimmer_4s_infinite_linear]\",\n        textSizes[size],\n        className\n      )}\n    >\n      {text}\n    </div>\n  )\n}\n\nexport function TextDotsLoader({\n  className,\n  text = \"Thinking\",\n  size = \"md\",\n}: {\n  className?: string\n  text?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\"inline-flex items-center\", className)}\n    >\n      <span className={cn(\"text-primary font-medium\", textSizes[size])}>\n        {text}\n      </span>\n      <span className=\"inline-flex\">\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.2s]\">\n          .\n        </span>\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.4s]\">\n          .\n        </span>\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.6s]\">\n          .\n        </span>\n      </span>\n    </div>\n  )\n}\n\nfunction Loader({\n  variant = \"circular\",\n  size = \"md\",\n  text,\n  className,\n}: LoaderProps) {\n  switch (variant) {\n    case \"circular\":\n      return <CircularLoader size={size} className={className} />\n    case \"classic\":\n      return <ClassicLoader size={size} className={className} />\n    case \"pulse\":\n      return <PulseLoader size={size} className={className} />\n    case \"pulse-dot\":\n      return <PulseDotLoader size={size} className={className} />\n    case \"dots\":\n      return <DotsLoader size={size} className={className} />\n    case \"typing\":\n      return <TypingLoader size={size} className={className} />\n    case \"wave\":\n      return <WaveLoader size={size} className={className} />\n    case \"bars\":\n      return <BarsLoader size={size} className={className} />\n    case \"terminal\":\n      return <TerminalLoader size={size} className={className} />\n    case \"text-blink\":\n      return <TextBlinkLoader text={text} size={size} className={className} />\n    case \"text-shimmer\":\n      return <TextShimmerLoader text={text} size={size} className={className} />\n    case \"loading-dots\":\n      return <TextDotsLoader text={text} size={size} className={className} />\n    default:\n      return <CircularLoader size={size} className={className} />\n  }\n}\n\nexport { Loader }\n"
        },
        {
          "path": "components/prompt-kit/message.tsx",
          "target": "@components/prompt-kit/message.tsx",
          "type": "registry:component",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport { Markdown } from \"./markdown\"\n\nexport type MessageProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nconst Message = ({ children, className, ...props }: MessageProps) => (\n  <div className={cn(\"flex gap-3\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type MessageAvatarProps = {\n  src: string\n  alt: string\n  fallback?: string\n  delayMs?: number\n  className?: string\n}\n\nconst MessageAvatar = ({\n  src,\n  alt,\n  fallback,\n  delayMs,\n  className,\n}: MessageAvatarProps) => {\n  return (\n    <Avatar className={cn(\"h-8 w-8 shrink-0\", className)}>\n      <AvatarImage src={src} alt={alt} />\n      {fallback && (\n        <AvatarFallback delayMs={delayMs}>{fallback}</AvatarFallback>\n      )}\n    </Avatar>\n  )\n}\n\nexport type MessageContentProps = {\n  children: React.ReactNode\n  markdown?: boolean\n  className?: string\n} & React.ComponentProps<typeof Markdown> &\n  React.HTMLProps<HTMLDivElement>\n\nconst MessageContent = ({\n  children,\n  markdown = false,\n  className,\n  ...props\n}: MessageContentProps) => {\n  const classNames = cn(\n    \"prose prose-sm dark:prose-invert rounded-lg bg-secondary p-2 text-foreground break-words whitespace-normal\",\n    className\n  )\n\n  return markdown ? (\n    <Markdown className={classNames} {...props}>\n      {children as string}\n    </Markdown>\n  ) : (\n    <div className={classNames} {...props}>\n      {children}\n    </div>\n  )\n}\n\nexport type MessageActionsProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nconst MessageActions = ({\n  children,\n  className,\n  ...props\n}: MessageActionsProps) => (\n  <div\n    className={cn(\"text-muted-foreground flex items-center gap-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type MessageActionProps = {\n  className?: string\n  tooltip: React.ReactNode\n  children: React.ReactNode\n  side?: \"top\" | \"bottom\" | \"left\" | \"right\"\n} & React.ComponentProps<typeof Tooltip>\n\nconst MessageAction = ({\n  tooltip,\n  children,\n  className,\n  side = \"top\",\n  ...props\n}: MessageActionProps) => {\n  return (\n    <TooltipProvider>\n      <Tooltip {...props}>\n        <TooltipTrigger asChild>{children}</TooltipTrigger>\n        <TooltipContent side={side} className={className}>\n          {tooltip}\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n\nexport { Message, MessageAvatar, MessageContent, MessageActions, MessageAction }\n"
        },
        {
          "path": "components/ui/avatar.tsx",
          "target": "@components/ui/avatar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Avatar({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n  return (\n    <AvatarPrimitive.Root\n      data-slot=\"avatar\"\n      className={cn(\n        \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarImage({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n  return (\n    <AvatarPrimitive.Image\n      data-slot=\"avatar-image\"\n      className={cn(\"aspect-square size-full\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarFallback({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n  return (\n    <AvatarPrimitive.Fallback\n      data-slot=\"avatar-fallback\"\n      className={cn(\n        \"bg-muted flex size-full items-center justify-center rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Avatar, AvatarImage, AvatarFallback }\n"
        },
        {
          "path": "components/ui/tooltip.tsx",
          "target": "@components/ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 4,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-gray-900 text-gray-50 dark:bg-gray-50 dark:text-gray-900 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-w-sm rounded-md px-3 py-1.5 text-xs\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"fill-gray-900 dark:fill-gray-50 z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "components/prompt-kit/markdown.tsx",
          "target": "@components/prompt-kit/markdown.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { marked } from \"marked\"\nimport { memo, useId, useMemo } from \"react\"\nimport ReactMarkdown, { Components } from \"react-markdown\"\nimport remarkBreaks from \"remark-breaks\"\nimport remarkGfm from \"remark-gfm\"\nimport { CodeBlock, CodeBlockCode } from \"./code-block\"\n\nexport type MarkdownProps = {\n  children: string\n  id?: string\n  className?: string\n  components?: Partial<Components>\n}\n\nfunction parseMarkdownIntoBlocks(markdown: string): string[] {\n  const tokens = marked.lexer(markdown)\n  return tokens.map((token) => token.raw)\n}\n\nfunction extractLanguage(className?: string): string {\n  if (!className) return \"plaintext\"\n  const match = className.match(/language-(\\w+)/)\n  return match ? match[1] : \"plaintext\"\n}\n\nconst INITIAL_COMPONENTS: Partial<Components> = {\n  code: function CodeComponent({ className, children, ...props }) {\n    const isInline =\n      !props.node?.position?.start.line ||\n      props.node?.position?.start.line === props.node?.position?.end.line\n\n    if (isInline) {\n      return (\n        <span\n          className={cn(\n            \"bg-primary-foreground rounded-sm px-1 font-mono text-sm\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </span>\n      )\n    }\n\n    const language = extractLanguage(className)\n\n    return (\n      <CodeBlock className={className}>\n        <CodeBlockCode code={children as string} language={language} />\n      </CodeBlock>\n    )\n  },\n  pre: function PreComponent({ children }) {\n    return <>{children}</>\n  },\n}\n\nconst MemoizedMarkdownBlock = memo(\n  function MarkdownBlock({\n    content,\n    components = INITIAL_COMPONENTS,\n  }: {\n    content: string\n    components?: Partial<Components>\n  }) {\n    return (\n      <ReactMarkdown\n        remarkPlugins={[remarkGfm, remarkBreaks]}\n        components={components}\n      >\n        {content}\n      </ReactMarkdown>\n    )\n  },\n  function propsAreEqual(prevProps, nextProps) {\n    return prevProps.content === nextProps.content\n  }\n)\n\nMemoizedMarkdownBlock.displayName = \"MemoizedMarkdownBlock\"\n\nfunction MarkdownComponent({\n  children,\n  id,\n  className,\n  components = INITIAL_COMPONENTS,\n}: MarkdownProps) {\n  const generatedId = useId()\n  const blockId = id ?? generatedId\n  const blocks = useMemo(() => parseMarkdownIntoBlocks(children), [children])\n\n  return (\n    <div className={className}>\n      {blocks.map((block, index) => (\n        <MemoizedMarkdownBlock\n          key={`${blockId}-block-${index}`}\n          content={block}\n          components={components}\n        />\n      ))}\n    </div>\n  )\n}\n\nconst Markdown = memo(MarkdownComponent)\nMarkdown.displayName = \"Markdown\"\n\nexport { Markdown }\n"
        },
        {
          "path": "components/prompt-kit/code-block.tsx",
          "target": "@components/prompt-kit/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React, { useEffect, useState } from \"react\"\nimport { codeToHtml } from \"shiki\"\n\nexport type CodeBlockProps = {\n  children?: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlock({ children, className, ...props }: CodeBlockProps) {\n  return (\n    <div\n      className={cn(\n        \"not-prose flex w-full flex-col overflow-clip border\",\n        \"border-border bg-card text-card-foreground rounded-xl\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type CodeBlockCodeProps = {\n  code: string\n  language?: string\n  theme?: string\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlockCode({\n  code,\n  language = \"tsx\",\n  theme = \"github-light\",\n  className,\n  ...props\n}: CodeBlockCodeProps) {\n  const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)\n\n  useEffect(() => {\n    async function highlight() {\n      if (!code) {\n        setHighlightedHtml(\"<pre><code></code></pre>\")\n        return\n      }\n\n      const html = await codeToHtml(code, { lang: language, theme })\n      setHighlightedHtml(html)\n    }\n    highlight()\n  }, [code, language, theme])\n\n  const classNames = cn(\n    \"w-full overflow-x-auto text-[13px] [&>pre]:px-4 [&>pre]:py-4\",\n    className\n  )\n\n  // SSR fallback: render plain code if not hydrated yet\n  return highlightedHtml ? (\n    <div\n      data-code-theme={theme}\n      className={classNames}\n      dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n      {...props}\n    />\n  ) : (\n    <div data-code-theme={theme} className={classNames} {...props}>\n      <pre>\n        <code>{code}</code>\n      </pre>\n    </div>\n  )\n}\n\nexport type CodeBlockGroupProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction CodeBlockGroup({\n  children,\n  className,\n  ...props\n}: CodeBlockGroupProps) {\n  return (\n    <div\n      className={cn(\"flex items-center justify-between\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport { CodeBlockGroup, CodeBlockCode, CodeBlock }\n"
        },
        {
          "path": "components/prompt-kit/prompt-input.tsx",
          "target": "@components/prompt-kit/prompt-input.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Textarea } from \"@/components/ui/textarea\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport React, {\n  createContext,\n  useContext,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\"\n\ntype PromptInputContextType = {\n  isLoading: boolean\n  value: string\n  setValue: (value: string) => void\n  maxHeight: number | string\n  onSubmit?: () => void\n  disabled?: boolean\n  textareaRef: React.RefObject<HTMLTextAreaElement | null>\n}\n\nconst PromptInputContext = createContext<PromptInputContextType>({\n  isLoading: false,\n  value: \"\",\n  setValue: () => {},\n  maxHeight: 240,\n  onSubmit: undefined,\n  disabled: false,\n  textareaRef: React.createRef<HTMLTextAreaElement>(),\n})\n\nfunction usePromptInput() {\n  return useContext(PromptInputContext)\n}\n\nexport type PromptInputProps = {\n  isLoading?: boolean\n  value?: string\n  onValueChange?: (value: string) => void\n  maxHeight?: number | string\n  onSubmit?: () => void\n  children: React.ReactNode\n  className?: string\n  disabled?: boolean\n} & React.ComponentProps<\"div\">\n\nfunction PromptInput({\n  className,\n  isLoading = false,\n  maxHeight = 240,\n  value,\n  onValueChange,\n  onSubmit,\n  children,\n  disabled = false,\n  onClick,\n  ...props\n}: PromptInputProps) {\n  const [internalValue, setInternalValue] = useState(value || \"\")\n  const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n  const handleChange = (newValue: string) => {\n    setInternalValue(newValue)\n    onValueChange?.(newValue)\n  }\n\n  const handleClick: React.MouseEventHandler<HTMLDivElement> = (event) => {\n    if (!disabled) textareaRef.current?.focus()\n    onClick?.(event)\n  }\n\n  return (\n    <TooltipProvider>\n      <PromptInputContext.Provider\n        value={{\n          isLoading,\n          value: value ?? internalValue,\n          setValue: onValueChange ?? handleChange,\n          maxHeight,\n          onSubmit,\n          disabled,\n          textareaRef,\n        }}\n      >\n        <div\n          onClick={handleClick}\n          className={cn(\n            \"border-input bg-background cursor-text rounded-3xl border p-2 shadow-xs\",\n            disabled && \"cursor-not-allowed opacity-60\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </div>\n      </PromptInputContext.Provider>\n    </TooltipProvider>\n  )\n}\n\nexport type PromptInputTextareaProps = {\n  disableAutosize?: boolean\n} & React.ComponentProps<typeof Textarea>\n\nfunction PromptInputTextarea({\n  className,\n  onKeyDown,\n  disableAutosize = false,\n  ...props\n}: PromptInputTextareaProps) {\n  const { value, setValue, maxHeight, onSubmit, disabled, textareaRef } =\n    usePromptInput()\n\n  const adjustHeight = (element: HTMLTextAreaElement | null) => {\n    if (!element || disableAutosize) return\n    element.style.height = \"auto\"\n    element.style.height =\n      typeof maxHeight === \"number\"\n        ? `${Math.min(element.scrollHeight, maxHeight)}px`\n        : `min(${element.scrollHeight}px, ${maxHeight})`\n  }\n\n  const handleRef = (element: HTMLTextAreaElement | null) => {\n    textareaRef.current = element\n    adjustHeight(element)\n  }\n\n  useLayoutEffect(() => {\n    adjustHeight(textareaRef.current)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [value, maxHeight, disableAutosize])\n\n  const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n    adjustHeight(event.target)\n    setValue(event.target.value)\n  }\n\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n      e.preventDefault()\n      onSubmit?.()\n    }\n    onKeyDown?.(e)\n  }\n\n  return (\n    <Textarea\n      ref={handleRef}\n      value={value}\n      onChange={handleChange}\n      onKeyDown={handleKeyDown}\n      className={cn(\n        \"text-primary min-h-[44px] w-full resize-none border-none bg-transparent shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0\",\n        className\n      )}\n      rows={1}\n      disabled={disabled}\n      {...props}\n    />\n  )\n}\n\nexport type PromptInputActionsProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction PromptInputActions({\n  children,\n  className,\n  ...props\n}: PromptInputActionsProps) {\n  return (\n    <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n      {children}\n    </div>\n  )\n}\n\nexport type PromptInputActionProps = {\n  className?: string\n  tooltip: React.ReactNode\n  children: React.ReactNode\n  side?: \"top\" | \"bottom\" | \"left\" | \"right\"\n} & React.ComponentProps<typeof Tooltip>\n\nfunction PromptInputAction({\n  tooltip,\n  children,\n  className,\n  side = \"top\",\n  ...props\n}: PromptInputActionProps) {\n  const { disabled } = usePromptInput()\n\n  return (\n    <Tooltip {...props}>\n      <TooltipTrigger\n        asChild\n        disabled={disabled}\n        onClick={(event) => event.stopPropagation()}\n      >\n        {children}\n      </TooltipTrigger>\n      <TooltipContent side={side} className={className}>\n        {tooltip}\n      </TooltipContent>\n    </Tooltip>\n  )\n}\n\nexport {\n  PromptInput,\n  PromptInputTextarea,\n  PromptInputActions,\n  PromptInputAction,\n}\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "components/prompt-kit/prompt-suggestion.tsx",
          "target": "@components/prompt-kit/prompt-suggestion.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { VariantProps } from \"class-variance-authority\"\n\nexport type PromptSuggestionProps = {\n  children: React.ReactNode\n  variant?: VariantProps<typeof buttonVariants>[\"variant\"]\n  size?: VariantProps<typeof buttonVariants>[\"size\"]\n  className?: string\n  highlight?: string\n} & React.ButtonHTMLAttributes<HTMLButtonElement>\n\nfunction PromptSuggestion({\n  children,\n  variant,\n  size,\n  className,\n  highlight,\n  ...props\n}: PromptSuggestionProps) {\n  const isHighlightMode = highlight !== undefined && highlight.trim() !== \"\"\n  const content = typeof children === \"string\" ? children : \"\"\n\n  if (!isHighlightMode) {\n    return (\n      <Button\n        variant={variant || \"outline\"}\n        size={size || \"lg\"}\n        className={cn(\"rounded-full\", className)}\n        {...props}\n      >\n        {children}\n      </Button>\n    )\n  }\n\n  if (!content) {\n    return (\n      <Button\n        variant={variant || \"ghost\"}\n        size={size || \"sm\"}\n        className={cn(\n          \"w-full cursor-pointer justify-start rounded-xl py-2\",\n          \"hover:bg-accent\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n      </Button>\n    )\n  }\n\n  const trimmedHighlight = highlight.trim()\n  const contentLower = content.toLowerCase()\n  const highlightLower = trimmedHighlight.toLowerCase()\n  const shouldHighlight = contentLower.includes(highlightLower)\n\n  return (\n    <Button\n      variant={variant || \"ghost\"}\n      size={size || \"sm\"}\n      className={cn(\n        \"w-full cursor-pointer justify-start gap-0 rounded-xl py-2\",\n        \"hover:bg-accent\",\n        className\n      )}\n      {...props}\n    >\n      {shouldHighlight ? (\n        (() => {\n          const index = contentLower.indexOf(highlightLower)\n          if (index === -1)\n            return (\n              <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                {content}\n              </span>\n            )\n\n          const actualHighlightedText = content.substring(\n            index,\n            index + highlightLower.length\n          )\n\n          const before = content.substring(0, index)\n          const after = content.substring(index + actualHighlightedText.length)\n\n          return (\n            <>\n              {before && (\n                <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                  {before}\n                </span>\n              )}\n              <span className=\"text-primary font-medium whitespace-pre-wrap\">\n                {actualHighlightedText}\n              </span>\n              {after && (\n                <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                  {after}\n                </span>\n              )}\n            </>\n          )\n        })()\n      ) : (\n        <span className=\"text-muted-foreground whitespace-pre-wrap\">\n          {content}\n        </span>\n      )}\n    </Button>\n  )\n}\n\nexport { PromptSuggestion }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ui/theme-toggle.tsx",
          "target": "@components/ui/theme-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Moon, Sun } from \"lucide-react\"\nimport { useTheme } from \"next-themes\"\nimport { useEffect, useState } from \"react\"\n\nexport function ThemeToggle() {\n  const { resolvedTheme, setTheme } = useTheme()\n  const [mounted, setMounted] = useState(false)\n  useEffect(() => setMounted(true), [])\n  if (!mounted) return <span aria-hidden className=\"inline-block size-8\" />\n  const dark = resolvedTheme === \"dark\"\n  return (\n    <Button\n      variant=\"ghost\"\n      size=\"small\"\n      iconOnly\n      leadingIcon={dark ? Sun : Moon}\n      aria-label={dark ? \"Use light theme\" : \"Use dark theme\"}\n      onClick={() => setTheme(dark ? \"light\" : \"dark\")}\n    />\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-toggle.tsx",
          "target": "@components/voice-agents/livekit/agent-track-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Track } from \"livekit-client\"\nimport {\n  LoaderIcon,\n  MicIcon,\n  MicOffIcon,\n  MonitorOffIcon,\n  MonitorUpIcon,\n  VideoIcon,\n  VideoOffIcon,\n} from \"lucide-react\"\nimport { Fragment, useMemo, useState, type ComponentProps } from \"react\"\n\nexport const agentTrackToggleVariants = cva([\"size-9\"], {\n  variants: {\n    size: {\n      default: \"h-9 px-2 min-w-9\",\n      sm: \"h-8 px-1.5 min-w-8\",\n      lg: \"h-10 px-2.5 min-w-10\",\n    },\n    variant: {\n      default: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive\",\n        \"data-[state=off]:hover:bg-destructive/15\",\n        \"data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n        \"data-[state=on]:hover:bg-foreground/10\",\n      ],\n      outline: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive data-[state=off]:border-destructive/20\",\n        \"data-[state=off]:hover:bg-destructive/15 data-[state=off]:hover:text-destructive\",\n        \"data-[state=off]:focus:text-destructive\",\n        \"data-[state=off]:focus-visible:border-destructive data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:hover:bg-foreground/10 data-[state=on]:hover:border-foreground/12\",\n        \"dark:data-[state=on]:hover:bg-foreground/10\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n})\n\nfunction getSourceIcon(\n  source: Track.Source,\n  enabled: boolean,\n  pending = false\n) {\n  if (pending) {\n    return LoaderIcon\n  }\n\n  switch (source) {\n    case Track.Source.Microphone:\n      return enabled ? MicIcon : MicOffIcon\n    case Track.Source.Camera:\n      return enabled ? VideoIcon : VideoOffIcon\n    case Track.Source.ScreenShare:\n      return enabled ? MonitorUpIcon : MonitorOffIcon\n    default:\n      return Fragment\n  }\n}\n\n/**\n * Props for the AgentTrackToggle component.\n */\nexport type AgentTrackToggleProps = VariantProps<\n  typeof agentTrackToggleVariants\n> &\n  ComponentProps<\"button\"> & {\n    /**\n     * The size of the toggle.\n     */\n    size?: \"sm\" | \"default\" | \"lg\"\n    /**\n     * The variant of the toggle.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\"\n    /**\n     * The track source to toggle (Microphone, Camera, or ScreenShare).\n     */\n    source: \"camera\" | \"microphone\" | \"screen_share\"\n    /**\n     * Whether the toggle is in a pending/loading state.\n     * When true, displays a loading spinner icon.\n     * @defaultValue false\n     */\n    pending?: boolean\n    /**\n     * Whether the toggle is currently pressed/enabled.\n     * @defaultValue false\n     */\n    pressed?: boolean\n    /**\n     * The default pressed state when uncontrolled.\n     * @defaultValue false\n     */\n    defaultPressed?: boolean\n    /**\n     * Callback fired when the pressed state changes.\n     */\n    onPressedChange?: (pressed: boolean) => void\n  }\n\n/**\n * A toggle button for controlling track publishing state.\n * Displays appropriate icons based on the track source and state.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentTrackToggle\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n * />\n * ```\n */\nexport function AgentTrackToggle({\n  size = \"default\",\n  variant = \"default\",\n  source,\n  pending = false,\n  pressed,\n  defaultPressed = false,\n  className,\n  onPressedChange,\n  ...props\n}: AgentTrackToggleProps) {\n  const [uncontrolledPressed, setUncontrolledPressed] = useState(\n    defaultPressed ?? false\n  )\n  const isControlled = pressed !== undefined\n  const resolvedPressed = useMemo(\n    () => (isControlled ? pressed : uncontrolledPressed) ?? false,\n    [isControlled, pressed, uncontrolledPressed]\n  )\n  const IconComponent = getSourceIcon(\n    source as Track.Source,\n    resolvedPressed,\n    pending\n  )\n  const handlePressedChange = (nextPressed: boolean) => {\n    if (!isControlled) {\n      setUncontrolledPressed(nextPressed)\n    }\n    onPressedChange?.(nextPressed)\n  }\n\n  return (\n    <Toggle\n      size={size}\n      variant={variant}\n      pressed={isControlled ? pressed : undefined}\n      defaultPressed={isControlled ? undefined : defaultPressed}\n      aria-label={`Toggle ${source}`}\n      onPressedChange={handlePressedChange}\n      className={cn(\n        agentTrackToggleVariants({\n          size,\n          variant: variant ?? \"default\",\n          className,\n        })\n      )}\n      {...props}\n    >\n      <IconComponent className={cn(pending && \"animate-spin\")} />\n      {props.children}\n    </Toggle>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/toggle.tsx",
          "target": "@components/voice-agents/livekit/_ui/toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline:\n          \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-9 min-w-9 px-2\",\n        sm: \"h-8 min-w-8 px-1.5\",\n        lg: \"h-10 min-w-10 px-2.5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n  VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      className={cn(toggleVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
        },
        {
          "path": "components/voice-agents/orbkit/shdr-21.tsx",
          "target": "@components/voice-agents/orbkit/shdr-21.tsx",
          "type": "registry:component",
          "content": "/*\n * Deliberately not a `\"use client\"` module — see the note in `shdr-11.tsx`.\n *\n * Note for editors: the shader lives in a template literal, so its comments\n * must not contain backticks.\n */\nimport { ShaderOrb, type OrbVariant, type ShaderOrbProps } from \"./core\"\n\n/* ----------------------------------------------------------------------------\n   SHDR-21 — light diffusing through a cloud.\n\n   A real volumetric integration rather than a surface. The march walks a\n   density field bounded by a sphere and, at every step, does three things:\n\n     TRANSMITTANCE  how much of the background still gets through, tracked as\n                    T *= exp(-density * dt * absorb). Beer-Lambert.\n     SHADOW         a short second march toward the light, so the far side of a\n                    dense clump is dimmer than the lit side. This is the whole\n                    reason the orb reads as volume and not as a flat glow.\n     IN-SCATTER     light added at this step, weighted by density, by the shadow\n                    term, and by a Henyey-Greenstein phase function.\n\n   The phase function is what makes it feel like light rather than paint. It\n   biases scattering forward, so the limb facing the light blooms and the rest\n   stays soft — the same reason a cloud is blinding when you look toward the sun\n   through it and merely bright otherwise.\n\n   Alpha is 1 - T, which is exactly what the volume occludes, so this one needs\n   no radial fade to hide the canvas edge: density falls to zero at the sphere\n   boundary and the alpha goes with it.\n---------------------------------------------------------------------------- */\n\n/*\n * Step counts are `#define`s: ES 1.0 requires constant loop bounds. The march\n * is STEPS * (1 + LIGHT_STEPS) density evaluations, so LIGHT_STEPS is the\n * expensive knob — 4 is enough for readable self-shadowing.\n */\nconst NIMBUS_FRAG = `\n#define STEPS 56\n#define LIGHT_STEPS 4\n#define DENSITY_OCT 4\n#define AA 1\n\nconst float PI = 3.14159265359;\n\n// Volume-reactive values, resolved once per fragment in main().\nfloat nimbusPower;\nfloat nimbusDensity;\n\n/*\n  Density inside the sphere.\n\n  The radial term falls to zero at the boundary, which both bounds the volume\n  and gives the soft edge for free. The cos-warp folds the sample point a few\n  times — the same cheap turbulence the other orbs use — and the threshold\n  carves that into clumps rather than an even fog.\n*/\nfloat density(vec3 p, float animTime) {\n  float shell = 1.0 - length(p) / uP_radius;\n  if (shell <= 0.0) return 0.0;\n\n  vec3 q = p * uP_scale;\n  float f = 1.0;\n  for (int k = 0; k < DENSITY_OCT; k++) {\n    q += cos(q.yzx * f + animTime * uP_churn) / f;\n    f *= 1.8;\n  }\n\n  float n = (sin(q.x) + sin(q.y) + sin(q.z)) / 3.0 * 0.5 + 0.5;\n  // smoothstep against the threshold is the clump control: high threshold\n  // leaves sparse wisps, low fills the sphere with even fog\n  float clump = smoothstep(uP_threshold, 1.0, n);\n  return clump * pow(shell, uP_edgeSoft) * nimbusDensity;\n}\n\n/*\n  Henyey-Greenstein: g > 0 biases scattering forward, which is what gives the\n  bloom on the limb facing the light.\n\n  The physical form carries a 1/(4*PI) normalisation. It is dropped here and\n  folded into uP_power instead — kept in, the whole term sits around 0.02 and\n  the orb renders black unless power is pushed into the hundreds, which makes\n  the slider useless.\n*/\nfloat phaseHG(float c, float g) {\n  float g2 = g * g;\n  return (1.0 - g2) / pow(max(1.0 + g2 - 2.0 * g * c, 0.0001), 1.5);\n}\n\nvec4 nimbusRender(vec2 fragCoord) {\n  float animTime = uP_speed; // integrated clock\n\n  vec2 uv = (2.0 * fragCoord - uRes) / min(uRes.x, uRes.y);\n  vec3 ro = vec3(0.0, 0.0, -uP_camDist);\n  vec3 rd = normalize(vec3(uv, uP_focal));\n\n  /*\n    Light direction, slowly orbiting so the shading is never static.\n\n    The z term is kept POSITIVE — the camera looks along +z, so a light also\n    pointing along +z sits behind the cloud. That is the back-lit case, where\n    dot(rd, L) approaches 1 and the forward-scattering phase blooms. Put the\n    light on the camera's side instead and every ray samples the phase function\n    on its back-scatter tail, where it is roughly ten times smaller, and the orb\n    goes muddy.\n  */\n  vec3 L = normalize(vec3(\n    cos(animTime * uP_lightSpin) * 0.7,\n    0.45,\n    sin(animTime * uP_lightSpin) * 0.35 + 0.65\n  ));\n\n  float phase = phaseHG(dot(rd, L), uP_aniso);\n\n  // Start the march at the sphere's front face instead of the camera — every\n  // step before that contributes nothing, and at 56 steps they are expensive.\n  float toCentre = uP_camDist;\n  float tStart = max(toCentre - uP_radius, 0.0);\n  float span = 2.0 * uP_radius;\n  float dt = span / float(STEPS);\n\n  float T = 1.0;\n  vec3 scattered = vec3(0.0);\n\n  for (int i = 0; i < STEPS; i++) {\n    float t = tStart + (float(i) + 0.5) * dt;\n    vec3 p = ro + rd * t;\n\n    float dn = density(p, animTime);\n    if (dn > 0.001) {\n      // short march toward the light for self-shadowing\n      float shadow = 1.0;\n      float lstep = uP_radius / float(LIGHT_STEPS);\n      for (int k = 1; k <= LIGHT_STEPS; k++) {\n        vec3 lp = p + L * (float(k) - 0.5) * lstep;\n        shadow *= exp(-density(lp, animTime) * lstep * uP_shadowAbsorb);\n      }\n\n      /*\n        In-scattered light: warm where lit, cool where the volume shadows\n        itself.\n\n        The shadow term appears ONCE, inside the mix. Multiplying by it again\n        as a factor — the obvious-looking thing to write — scales the shadowed\n        end of the mix toward zero, so the cool colour is always multiplied\n        away and the cloud comes out monochrome beige however it is tinted.\n        uP_shadowLift is how much light still reaches the shadowed side.\n      */\n      vec3 lit = mix(uC_shadow * uP_shadowLift, uC_light, shadow);\n      scattered += T * dn * dt * lit * phase * nimbusPower;\n\n      T *= exp(-dn * dt * uP_absorb);\n      if (T < 0.01) break;\n    }\n  }\n\n  // a soft ambient body so the unlit side is not pure black\n  float body = 1.0 - T;\n  scattered += uC_shadow * body * uP_ambient;\n\n  return vec4(scattered, body);\n}\n\nvoid main() {\n  /*\n    Agent output turns the light up; user input thickens the cloud. Both are\n    AMPLITUDES. Churn is deliberately NOT volume-scaled: it multiplies the\n    accumulated clock into a phase (animTime * churn), so scaling it by the\n    live volume would turn every volume wobble into a phase jump the size of\n    the whole clock — the cloud scrambles chaotically on each state change\n    instead of gliding, and gets worse the longer the page is open.\n  */\n  nimbusPower = uP_power * (0.7 + 0.9 * uOutput);\n  nimbusDensity = uP_density * (1.0 + 0.35 * uInput);\n\n  vec4 acc = vec4(0.0);\n#if AA > 1\n  for (int mx = 0; mx < AA; mx++) {\n    for (int my = 0; my < AA; my++) {\n      vec2 offset = vec2(float(mx), float(my)) / float(AA) - 0.5;\n      acc += nimbusRender(gl_FragCoord.xy + offset);\n    }\n  }\n  acc /= float(AA * AA);\n#else\n  acc = nimbusRender(gl_FragCoord.xy);\n#endif\n\n  vec3 col = tanh3(acc.rgb * uP_exposure);\n  float a = clamp(acc.a * uP_alphaGain, 0.0, 1.0);\n\n  // Emitted/scattered light, so rgb is already premultiplied — do NOT multiply\n  // by alpha again (see the same note in shdr-31).\n  gl_FragColor = vec4(col, a);\n}\n`\n\nexport const shdr21Orb: OrbVariant = {\n  key: \"shdr-21\",\n  label: \"SHDR-21\",\n  note: \"light diffusing through a cloud\",\n  frag: NIMBUS_FRAG,\n  params: [\n    {\n      key: \"speed\",\n      label: \"Anim speed\",\n      min: 0.015,\n      max: 10,\n      step: 0.05,\n      default: 10,\n      integrate: true,\n    },\n    {\n      key: \"camDist\",\n      label: \"Camera distance\",\n      min: 0.5,\n      max: 40,\n      step: 0.2,\n      default: 4.4,\n    },\n    { key: \"focal\", label: \"Lens\", min: 0.3, max: 15, step: 0.1, default: 1.8 },\n    {\n      key: \"radius\",\n      label: \"Cloud radius\",\n      min: 0.15,\n      max: 10,\n      step: 0.05,\n      default: 2,\n    },\n    {\n      key: \"scale\",\n      label: \"Cloud scale\",\n      min: 0.1,\n      max: 15,\n      step: 0.1,\n      default: 0.8,\n    },\n    { key: \"churn\", label: \"Churn\", min: 0, max: 5, step: 0.03, default: 0.3 },\n    {\n      key: \"threshold\",\n      label: \"Clumping\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.075,\n    },\n    {\n      key: \"edgeSoft\",\n      label: \"Edge softness\",\n      min: 0.1,\n      max: 10,\n      step: 0.05,\n      default: 0.8,\n    },\n    {\n      key: \"density\",\n      label: \"Density\",\n      min: 0.03,\n      max: 20,\n      step: 0.1,\n      default: 3.2,\n    },\n    {\n      key: \"absorb\",\n      label: \"Absorption\",\n      min: 0.03,\n      max: 15,\n      step: 0.1,\n      default: 1.4,\n    },\n    {\n      key: \"shadowAbsorb\",\n      label: \"Shadow depth\",\n      min: 0,\n      max: 20,\n      step: 0.1,\n      default: 2.4,\n    },\n    {\n      key: \"shadowLift\",\n      label: \"Shadow lift\",\n      min: 0,\n      max: 5,\n      step: 0.03,\n      default: 0.55,\n    },\n    {\n      key: \"aniso\",\n      label: \"Forward scatter\",\n      min: -0.9,\n      max: 0.9,\n      step: 0.01,\n      default: 0.45,\n    },\n    {\n      key: \"lightSpin\",\n      label: \"Light orbit\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.12,\n    },\n    {\n      key: \"power\",\n      label: \"Light power\",\n      min: 0.03,\n      max: 40,\n      step: 0.2,\n      default: 1.9,\n    },\n    {\n      key: \"ambient\",\n      label: \"Ambient\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.12,\n    },\n    {\n      key: \"exposure\",\n      label: \"Exposure\",\n      min: 0.03,\n      max: 10,\n      step: 0.05,\n      default: 1,\n    },\n    {\n      key: \"alphaGain\",\n      label: \"Alpha gain\",\n      min: 0.05,\n      max: 10,\n      step: 0.05,\n      default: 1.5,\n    },\n  ],\n  /*\n   * The engine uploads these as uC_<key> vec3 uniforms. Warm light against a\n   * cool shadow is what reads as depth — a single-hue cloud looks flat however\n   * well it is shadowed.\n   */\n  colors: [\n    { key: \"light\", label: \"Light\", default: \"#ffd7a3\" },\n    { key: \"shadow\", label: \"Shadow\", default: \"#3a4a8c\" },\n  ],\n  statePresets: {\n    /*\n      Every state shares the same speed, geometry and cloud shape — only the\n      AMBIENCE and the palette move, so switching state relights the cloud\n      instead of restaging it. The engine glides params and cross-fades\n      colours on one shared easing, so the change reads as a mood shift.\n    */\n    idle: {\n      ambient: 0.12,\n      power: 1.9,\n      shadowLift: 0.55,\n    },\n    thinking: {\n      ambient: 0.22,\n      power: 2.15,\n      shadowLift: 0.65,\n    },\n    speaking: {\n      ambient: 0.46,\n      power: 3.1,\n      shadowLift: 0.95,\n    },\n  },\n  /*\n    The palette carries the rest of the state read: a warm lamp over cool\n    shadow at rest, shifting violet while it thinks, and burning hot while\n    speaking.\n  */\n  stateColors: {\n    idle: { light: \"#ffd7a3\", shadow: \"#3a4a8c\" },\n    thinking: { light: \"#e6d4ff\", shadow: \"#3b3f96\" },\n    speaking: { light: \"#ffb066\", shadow: \"#7a2f6e\" },\n  },\n}\n\nexport type Shdr21Props = Omit<ShaderOrbProps, \"variant\">\n\nexport function Shdr21({ size = 280, ...rest }: Shdr21Props) {\n  return <ShaderOrb variant={shdr21Orb} size={size} {...rest} />\n}\n\nexport default Shdr21\n"
        },
        {
          "path": "components/voice-agents/orbkit/core.tsx",
          "target": "@components/voice-agents/orbkit/core.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport React, {\n  useEffect,\n  useRef,\n  useState,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/* ----------------------------------------------------------------------------\n   Orbkit core — raw WebGL shader orb runtime. No dependencies.\n\n   An orb is a full-screen triangle rendered into a transparent canvas by a\n   fragment shader. Every orb declares a parameter schema (sliders + colors);\n   the values are uploaded as uniforms each frame from a ref, so a controls\n   panel can tune them live without ever remounting the canvas (a remount would\n   drop the WebGL context).\n\n   Animation model: every state synthesizes two volume signals — input (user\n   speech energy) and output (agent speech energy) — smooths them, and the\n   shaders react to those. The flow clock's speed itself follows the output\n   volume, so orbs visibly quicken when the agent is talking.\n---------------------------------------------------------------------------- */\n\nexport type OrbState = \"idle\" | \"thinking\" | \"speaking\"\n\nexport const ORB_STATES = [\"idle\", \"thinking\", \"speaking\"] as const\n\nfunction clamp01(n: number) {\n  return Math.min(1, Math.max(0, n))\n}\n\n/** Per-state [input, output] volume synthesis. */\n/**\n * Transition rate shared by params, colours and the flow-speed multiplier.\n * They must move together: if the rate multiplier eases faster than the look,\n * a state change spins the orb up before it has finished cross-fading, which\n * reads as a lurch.\n *\n * This drives a critically damped spring rather than the exponential ease it\n * used to. An exponential's velocity is highest at the instant the target\n * changes, so every state change began with a jolt — and for params that are\n * spatial frequencies (Corona's warpFreq travels 5.25 -> 19.5 between states)\n * that jolt sweeps the field through its intermediate frequencies at maximum\n * rate, which is what read as the transition \"scrambling\".\n *\n * A spring starts at rest and accelerates, so the sweep is spread across the\n * transition instead of front-loaded. Measured on that warpFreq move it is a\n * 20% lower peak rate of change (20.3/s vs 25.3/s) AND it arrives sooner —\n * 1.50s to within 2% against the exponential's 2.18s, since an exponential\n * only ever asymptotes toward its target.\n */\nconst PARAM_EASE = 4\n\n/*\n  One step of a critically damped spring, implicit (semi-implicit Euler would\n  blow up at the frame times a backgrounded tab produces). Returns nothing and\n  writes through the scratch pair so the hot loop allocates nothing.\n*/\nconst springOut = { x: 0, v: 0 }\nfunction springStep(\n  x: number,\n  v: number,\n  target: number,\n  dt: number,\n  omega: number\n) {\n  const f = 1 + 2 * dt * omega\n  const oo = omega * omega\n  const hoo = dt * oo\n  const hhoo = dt * hoo\n  const detInv = 1 / (f + hhoo)\n  springOut.x = (f * x + dt * v + hhoo * target) * detInv\n  springOut.v = (v + hoo * (target - x)) * detInv\n}\n\nfunction targetVolumes(state: OrbState, t: number): [number, number] {\n  switch (state) {\n    case \"idle\":\n      return [0, 0.3]\n    case \"speaking\":\n      return [\n        clamp01(0.65 + Math.sin(t * 4.8) * 0.22),\n        clamp01(0.75 + Math.sin(t * 3.6) * 0.22),\n      ]\n    case \"thinking\": {\n      const base = 0.38 + 0.07 * Math.sin(t * 0.7)\n      const wander = 0.05 * Math.sin(t * 2.1) * Math.sin(t * 0.37 + 1.2)\n      return [\n        clamp01(base + wander),\n        clamp01(0.48 + 0.12 * Math.sin(t * 1.05 + 0.6)),\n      ]\n    }\n  }\n}\n\n/* ------------------------------ param schema ------------------------------- */\n\nexport interface OrbParamDef {\n  key: string\n  label: string\n  min: number\n  max: number\n  step: number\n  default: number\n  /**\n   * Rate params. The engine integrates them into a clock\n   * (`clock += dt * value * volumeSpeed`) and uploads the clock instead of the\n   * raw value, so changing the rate never jumps the phase — the motion speeds\n   * up or slows down rather than snapping to a new position.\n   */\n  integrate?: boolean\n}\n\nexport interface OrbColorDef {\n  key: string\n  label: string\n  /** hex, e.g. `#ff8b73` */\n  default: string\n}\n\nexport interface OrbVariant {\n  key: string\n  label: string\n  note: string\n  /** GLSL fragment shader body. Uniform declarations are generated for you. */\n  frag: string\n  params: OrbParamDef[]\n  colors: OrbColorDef[]\n  /**\n   * Per-state parameter targets. The engine glides each param toward the\n   * active state's preset. Params passed explicitly via the `params` prop\n   * always win over the preset.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /**\n   * Per-state colour targets, the colour counterpart of `statePresets`.\n   * Kept a separate map because presets are numeric and colours are hex\n   * strings — a union would lose type safety on both. Colours glide in RGB\n   * on the same easing as params, so a state change cross-fades rather\n   * than cutting. Colours passed explicitly via the `colors` prop always\n   * win, exactly as with params.\n   */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n}\n\nexport type OrbParamValues = Partial<Record<string, number>>\nexport type OrbColorValues = Partial<Record<string, string>>\n\n/** Every param and color at its schema default. */\nexport function defaultValuesFor(variant: OrbVariant): {\n  params: Record<string, number>\n  colors: Record<string, string>\n} {\n  return {\n    params: Object.fromEntries(variant.params.map((p) => [p.key, p.default])),\n    colors: Object.fromEntries(variant.colors.map((c) => [c.key, c.default])),\n  }\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace(\"#\", \"\").trim()\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]\n  const n = parseInt(h, 16)\n  if (h.length !== 6 || Number.isNaN(n)) return [1, 1, 1]\n  return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255]\n}\n\n/* ------------------------------- GLSL shared ------------------------------- */\n\nconst VERT = `\nattribute vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\n/**\n * Prelude prepended to every orb fragment shader: uniforms, value noise, fbm,\n * and the centered aspect-corrected UV helper.\n */\nexport const ORB_GLSL_HELPERS = `\nprecision highp float;\nuniform vec2 uRes;\nuniform float uTime;   // slow ambient clock (half real-time)\nuniform float uAnim;   // flow clock — its speed follows the output volume\nuniform float uInput;  // input volume 0..1: user speech energy\nuniform float uOutput; // output volume 0..1: agent speech energy\n\nfloat hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); }\nfloat noise(vec2 p) {\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);\n  return mix(\n    mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),\n    mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x),\n    f.y\n  );\n}\nfloat fbm(vec2 p) {\n  float v = 0.0;\n  float a = 0.5;\n  for (int i = 0; i < 5; i++) {\n    v += a * noise(p);\n    p = p * 2.03 + vec2(11.7, 7.3);\n    a *= 0.5;\n  }\n  return v;\n}\nvec2 orbUV() { return (2.0 * gl_FragCoord.xy - uRes) / min(uRes.x, uRes.y); }\n\n// GLSL ES 1.0 has no tanh() — it arrived in ES 3.0. Shader-golf listings lean\n// on it as a tone-mapper, so it ships here. Clamped against exp() overflow;\n// accurate for the non-negative accumulators those shaders produce.\nvec3 tanh3(vec3 x) {\n  x = clamp(x, -10.0, 10.0);\n  vec3 e = exp(2.0 * x);\n  return (e - 1.0) / (e + 1.0);\n}\n\n`\n\nfunction paramUniformDecls(variant: OrbVariant): string {\n  return [\n    ...variant.params.map((p) => `uniform float uP_${p.key};`),\n    ...variant.colors.map((c) => `uniform vec3 uC_${c.key};`),\n  ].join(\"\\n\")\n}\n\n/* ------------------------------- engine ------------------------------------ */\n\n/**\n * Per-canvas context-lifecycle controller. Created on first mount of a canvas\n * and kept for the element's whole life — the router can hide a page and show\n * the same DOM again, and React re-runs effects on the same canvas, so the\n * lost/restored listeners must outlive any single effect run: an uncanceled\n * webglcontextlost event marks the context permanently unrestorable.\n */\ninterface CanvasContextController {\n  /** Whether a mounted orb currently wants this context alive. */\n  desired: boolean\n  /** Builds a render generation; returns its teardown. Rebound per effect run. */\n  start: (() => () => void) | null\n  /** Teardown of the live generation, if one is running. */\n  stopGen: (() => void) | null\n}\n\nconst canvasControllers = new WeakMap<\n  HTMLCanvasElement,\n  CanvasContextController\n>()\n\nfunction compile(\n  gl: WebGLRenderingContext,\n  type: number,\n  src: string\n): WebGLShader | null {\n  const shader = gl.createShader(type)\n  if (!shader) return null\n  gl.shaderSource(shader, src)\n  gl.compileShader(shader)\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    console.error(\"[orbkit] shader compile error:\", gl.getShaderInfoLog(shader))\n    gl.deleteShader(shader)\n    return null\n  }\n  return shader\n}\n\n/* ----------------------------------------------------------------------------\n   Wrappers — optional decoration drawn around, under and over the orb.\n\n   A wrapper is pure CSS/SVG, never a shader: the orb keeps its own canvas and\n   the decoration is composited on top of it by the browser. That keeps the\n   whole set free for any orb (no per-variant shader work), costs nothing on\n   the GPU budget the shaders are already spending, and means swapping one\n   wrapper for another at runtime never touches the WebGL context. Turning a\n   wrapper on or off does, since that is what moves the canvas into or out of\n   the wrapper element — see the effect's `wrapped` dependency.\n\n   Layout: a wrapped orb becomes a square box, and the canvas is absolutely\n   positioned inside it with the spec's `inset`. The FOOTPRINT is unchanged —\n   `size` is still the outer diameter — so dropping a wrapper onto an existing\n   orb reflows nothing; the orb itself just shrinks to leave the ring room.\n\n   Colour: every layer that isn't physically light or shadow paints in\n   `currentColor`, so a wrapper picks up the surrounding text colour and reads\n   correctly on light and dark pages with no configuration. `wrapperColor`\n   sets that colour when you want something other than the inherited one.\n---------------------------------------------------------------------------- */\n\nexport const ORB_WRAPPERS = [\n  \"none\",\n  \"glass\",\n  \"ring\",\n  \"dotted\",\n  \"ticks\",\n  \"reticle\",\n  \"grid\",\n  \"halftone\",\n  \"scanlines\",\n] as const\n\nexport type OrbWrapper = (typeof ORB_WRAPPERS)[number]\n\n/*\n  Keyframes for the animated wrappers, shipped inside the component so an orb\n  stays a single self-contained file with nothing to add to a global\n  stylesheet. React 19 hoists a <style href precedence> into <head> and\n  de-duplicates it, so a page full of wrapped orbs emits this exactly once;\n  older React renders it inline, which is redundant but harmless.\n\n  Reduced motion parks all of it. The shader runtime already honours the same\n  preference for the orb itself (see the reduce-motion branch in the render\n  loop), and a ring that keeps spinning around a frozen orb would be the worse\n  half of the two still moving.\n*/\nconst WRAPPER_STYLE_HREF = \"orbkit-wrapper\"\nconst WRAPPER_CSS = `\n@keyframes orbkit-w-spin { to { transform: rotate(360deg); } }\n@keyframes orbkit-w-roll { from { transform: translateY(-110%); } to { transform: translateY(360%); } }\n@media (prefers-reduced-motion: reduce) {\n  .orbkit-w-anim { animation: none !important; }\n}\n`\n\ninterface WrapperSpec {\n  /**\n   * How far the canvas sits inside the box, in percent, leaving the\n   * decoration room. Applied as explicit width/height rather than as `inset`:\n   * a canvas is a REPLACED element, so an absolutely positioned one with\n   * `left` and `right` both set does not stretch between them — it keeps its\n   * intrinsic size and the over-constrained edge is dropped. The orb would\n   * then be drawn into a canvas the size of the page.\n   */\n  inset: number\n  /**\n   * Soft circular mask on the canvas. Only the wrappers that read as a\n   * CONTAINER set one — a bubble has to hold the orb, whereas a bezel sits\n   * beside it and clipping the halo there would just amputate the glow.\n   */\n  mask?: string\n  /** Cast by the assembly as a whole, on the outer box. */\n  shadow?: string\n\n  /** True when the spec uses one of the keyframes above. */\n  animated?: boolean\n  /** Painted beneath the canvas. */\n  under?: ReactNode\n  /** Painted over it. */\n  over?: ReactNode\n}\n\nconst DISC: CSSProperties = { borderRadius: \"50%\" }\n\n/** One absolutely-positioned decoration layer, filling the wrapper box. */\nfunction Layer({\n  inset = 0,\n  style,\n  className,\n}: {\n  inset?: number | string\n  style: CSSProperties\n  className?: string\n}) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={className}\n      style={{ position: \"absolute\", inset, pointerEvents: \"none\", ...style }}\n    />\n  )\n}\n\n/**\n * A free-floating highlight — glass's specular and its bounce. These do not go\n * through `Layer` because they are placed with `left`/`top`/`width`, and a\n * style object that sets those on top of `Layer`'s `inset` shorthand is mixing\n * shorthand and longhand for the same property: React warns about it, and the\n * result depends on key order rather than on anything you would want to rely\n * on.\n */\nfunction Highlight({ style }: { style: CSSProperties }) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      style={{\n        position: \"absolute\",\n        borderRadius: \"50%\",\n        pointerEvents: \"none\",\n        ...style,\n      }}\n    />\n  )\n}\n\n/**\n * The mask that makes a wrapper HOLD the orb: cuts the canvas back to the\n * bubble and stops a hairline short of the rim, so the orb never quite touches\n * the glass.\n *\n * The percentage has to be derived rather than written down. `closest-side`\n * measures the CANVAS, and a wrapper with a negative inset draws its canvas\n * LARGER than the bubble — at -7 the canvas is 114% of the box, so the rim\n * sits at 100/1.14 = 87.7% of the canvas's own radius, not at 100%.\n *\n * The gap is real pixels rather than a share of the size: it reads as the same\n * band at 120px and at 900px, which a percentage would not.\n */\nconst RIM_GAP_PX = 4\n\nfunction rimMask(inset: number): string {\n  const rim = (100 / (1 - (2 * inset) / 100)).toFixed(2)\n  // Feathered over the final pixel, so the cut is not a razor edge.\n  const solid = RIM_GAP_PX + 0.5\n  const clear = RIM_GAP_PX - 0.5\n  return `radial-gradient(circle closest-side, #000 calc(${rim}% - ${solid}px), rgba(0,0,0,0) calc(${rim}% - ${clear}px))`\n}\n\n/** Both spellings, since Safari still wants the prefix for mask-image. */\nfunction masked(image: string): CSSProperties {\n  return { WebkitMaskImage: image, maskImage: image }\n}\n\nconst svgLayer: CSSProperties = {\n  position: \"absolute\",\n  inset: 0,\n  width: \"100%\",\n  height: \"100%\",\n  pointerEvents: \"none\",\n  overflow: \"visible\",\n}\n\n/** Glass's overfill, shared by its inset and the mask derived from it. */\nconst GLASS_INSET = -4\n\nconst WRAPPER_SPECS: Record<Exclude<OrbWrapper, \"none\">, WrapperSpec> = {\n  /*\n    glass — a blown bubble with the orb suspended inside it.\n\n    Five layers in the order light actually arrives: the body brightening\n    toward the key light, the Fresnel ring where a sphere's edge turns almost\n    edge-on and reflects nearly everything, the rim itself, the window\n    reflection, and the bounce coming back up off whatever the bubble is\n    sitting on. All of it is white and black rather than `currentColor` —\n    glass has no colour of its own, only the light it moves around.\n  */\n  glass: {\n    /*\n      Negative on purpose. An orb's shader does not necessarily paint to the\n      edge of its canvas — most draw a sphere with transparent margin around\n      it — so a canvas sized to the bubble leaves a dead ring between the orb\n      and the rim, which is not what a thing suspended in glass looks like.\n      Oversizing the canvas by 14% pushes the sphere out to the rim, and\n      `rimMask` cuts whatever overflows — a few pixels short of the glass, so\n      the orb sits just inside it rather than welded to it. Orbs that already fill\n      their canvas lose a few percent off the limb, which is the same crop the\n      reference bubble makes.\n    */\n    inset: GLASS_INSET,\n    mask: rimMask(GLASS_INSET),\n    shadow: \"0 24px 48px -26px rgba(0,0,0,0.55)\",\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(ellipse 80% 70% at 28% 20%, rgba(255,255,255,0.16), rgba(255,255,255,0.03) 45%, rgba(255,255,255,0) 72%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(255,255,255,0) 0%, rgba(255,255,255,0.0) 55%, rgba(255,255,255,0.05) 99.5%, rgba(255,255,255,0) 100%)\",\n            overflow: \"hidden\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow: \"3px 6px 10px #ffffff20 inset\",\n          }}\n        />\n        {/*\n          The shell's own darkening, just inside the rim. Invisible on a dark\n          page — it is black over black — and doing all the work on a light\n          one, where the white highlights below have nothing to stand out\n          against and the bubble would otherwise read as a bare drop shadow.\n        */}\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(0,0,0,0) 78%, rgba(0,0,0,0.05) 93%, rgba(0,0,0,0.02) 100%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow:\n              \"inset 0 6px 12px -7px rgba(255,255,255,0.05), inset 0 -9px 16px -9px rgba(255,255,255,0.1), 0 0 0 1px rgba(0,0,0,0.07)\",\n          }}\n        />\n        <Highlight\n          style={{\n            left: \"15%\",\n            top: \"10%\",\n            width: \"38%\",\n            height: \"22%\",\n            transform: \"rotate(-25deg)\",\n            background:\n              \"radial-gradient(closest-side, rgba(255,255,255,0.9), rgba(255,255,255,0.3) 55%, rgba(255,255,255,0) 100%)\",\n            filter: \"blur(10px)\",\n          }}\n        />\n      </>\n    ),\n  },\n\n  /* ring — two hairlines and nothing else. The restrained one. */\n  ring: {\n    inset: 9,\n    over: (\n      <>\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.22 }}\n        />\n        <Layer\n          inset=\"5%\"\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.1 }}\n        />\n      </>\n    ),\n  },\n\n  /*\n    dotted — evenly spaced dots around the circumference, turning slowly.\n\n    Drawn as one dashed circle with round caps and a near-zero dash length, so\n    each dash collapses to a dot. `pathLength=\"64\"` renormalizes the path to 64\n    units first, which is what makes the count exact: the dash period is\n    literally 1/64th of the circle, so the pattern closes on itself with no\n    seam where the last gap would otherwise be short.\n  */\n  dotted: {\n    inset: 10,\n    animated: true,\n    over: (\n      <svg\n        aria-hidden=\"true\"\n        viewBox=\"0 0 100 100\"\n        className=\"orbkit-w-anim\"\n        style={{ ...svgLayer, animation: \"orbkit-w-spin 48s linear infinite\" }}\n      >\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"47\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.7\"\n          strokeLinecap=\"round\"\n          pathLength={64}\n          strokeDasharray=\"0.0001 0.9999\"\n          opacity={0.45}\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    ticks — an instrument bezel: a fine minor scale every 6 degrees with a\n    longer major tick every 30. Both are one repeating conic gradient masked\n    down to an annulus, so the tick count is set by the gradient's period and\n    the tick LENGTH by how far in the mask reaches.\n  */\n  ticks: {\n    inset: 12,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.32,\n            background:\n              \"repeating-conic-gradient(from -0.5deg, transparent 0deg 0.2deg, currentColor 0.4deg 0.6deg, transparent 0.8deg 6deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 88%, #000 90%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.6,\n            background:\n              \"repeating-conic-gradient(from -0.75deg, transparent 0deg 0.25deg, currentColor 0.5deg 1deg, transparent 1.25deg 30deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 80%, #000 82%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.12 }}\n        />\n      </>\n    ),\n  },\n\n  /* reticle — viewfinder furniture: corner brackets, cardinal ticks, a track. */\n  reticle: {\n    inset: 13,\n    over: (\n      <svg aria-hidden=\"true\" viewBox=\"0 0 100 100\" style={svgLayer}>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" opacity=\"0.5\">\n          <path d=\"M1 13 L1 1 L13 1\" />\n          <path d=\"M87 1 L99 1 L99 13\" />\n          <path d=\"M99 87 L99 99 L87 99\" />\n          <path d=\"M13 99 L1 99 L1 87\" />\n        </g>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.38\">\n          <path d=\"M50 1 L50 9\" />\n          <path d=\"M50 91 L50 99\" />\n          <path d=\"M1 50 L9 50\" />\n          <path d=\"M91 50 L99 50\" />\n        </g>\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"46\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"0.7\"\n          opacity=\"0.22\"\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    grid — a graticule laid over the orb and masked back to the disc, so the\n    mesh appears to be etched on the glass in front of it rather than drawn on\n    the page behind. The lines are 1px whatever the size; the SPACING is a\n    percentage, so the cell count holds from a gallery thumbnail to a\n    full-bleed hero.\n  */\n  grid: {\n    inset: 8,\n    /*\n      The ruling sits UNDER the canvas: graph paper the orb rests on, not a\n      mesh laid over its face. Drawn on top it crosshatched the shader — the\n      one thing the wrapper is meant to frame. The ring stays over, since it\n      only ever meets the transparent margin at the canvas edge.\n    */\n    under: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.18,\n          backgroundImage:\n            \"repeating-linear-gradient(to right, currentColor 0 1px, transparent 1px 12.5%), repeating-linear-gradient(to bottom, currentColor 0 1px, transparent 1px 12.5%)\",\n          ...masked(\n            \"radial-gradient(circle closest-side, #000 86%, rgba(0,0,0,0) 99%)\"\n          ),\n        }}\n      />\n    ),\n    over: (\n      <Layer\n        style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.2 }}\n      />\n    ),\n  },\n\n  /*\n    halftone — a print screen over the outer band of the orb. The mask keeps\n    the middle clear, so the dots read as the image breaking up toward its\n    edge instead of a texture pasted across the whole face.\n  */\n  halftone: {\n    inset: 6,\n    over: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.5,\n          backgroundImage: \"radial-gradient(currentColor 22%, transparent 24%)\",\n          backgroundSize: \"7px 7px\",\n          ...masked(\n            \"radial-gradient(circle closest-side, transparent 40%, #000 80%, #000 94%, rgba(0,0,0,0) 100%)\"\n          ),\n        }}\n      />\n    ),\n  },\n\n  /*\n    scanlines — a phosphor tube. Black lines rather than `currentColor`,\n    because scanlines are the UNLIT gaps between rows and stay dark whatever\n    the page is; the slow bright band rolling down is the vertical hold\n    drifting, which is the part that reads as a CRT rather than as stripes.\n  */\n  scanlines: {\n    inset: 0,\n    animated: true,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            backgroundImage:\n              \"repeating-linear-gradient(to bottom, rgba(0,0,0,0.45) 0 1px, rgba(0,0,0,0) 1px 3px)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, #000 84%, rgba(0,0,0,0) 100%)\"\n            ),\n          }}\n        />\n        <span\n          aria-hidden=\"true\"\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            borderRadius: \"50%\",\n            overflow: \"hidden\",\n            pointerEvents: \"none\",\n          }}\n        >\n          <span\n            className=\"orbkit-w-anim\"\n            style={{\n              position: \"absolute\",\n              left: 0,\n              right: 0,\n              top: 0,\n              height: \"30%\",\n              background:\n                \"linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,0.07) 50%, rgba(255,255,255,0) 100%)\",\n              animation: \"orbkit-w-roll 7s linear infinite\",\n            }}\n          />\n        </span>\n        <Layer\n          style={{ ...DISC, boxShadow: \"inset 0 0 40px -8px rgba(0,0,0,0.5)\" }}\n        />\n      </>\n    ),\n  },\n}\n\nexport interface ShaderOrbProps {\n  /** The orb definition: shader + param schema + state presets. */\n  variant: OrbVariant\n  /** Drives the synthesized volume signals. Defaults to `\"idle\"`. */\n  state?: OrbState\n  /** Rendered size in CSS pixels. Ignored when `className` sizes the canvas. */\n  size?: number\n  /** Explicit param overrides. Any key present here wins over the state preset. */\n  params?: OrbParamValues\n  /** Explicit color overrides, as hex strings. */\n  colors?: OrbColorValues\n  /**\n   * Per-state parameter targets, overriding the variant's own. Merged KEY BY\n   * KEY over what the orb already defines, so `{ thinking: { churn: 1.62 } }`\n   * retouches one param of one state and leaves every other param — and the\n   * other two states — exactly as the orb ships them.\n   *\n   * This is the prop form of the variant's `statePresets`, so you can retune\n   * an orb's states from the outside without forking its file. Values still\n   * glide, so switching states cross-fades into your targets. An explicit\n   * `params` value outranks this, the same way it outranks the variant.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /** The colour counterpart of `statePresets`, merged the same key-by-key way. */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n  /**\n   * Per-state volume drive, the third member of the same family. Use it to\n   * give each state its own energy; use `volumes` below instead when you have\n   * a real signal to feed in, such as live mic level.\n   */\n  stateVolumes?: Partial<Record<OrbState, { input?: number; output?: number }>>\n  /**\n   * Overrides the synthesized volume signals for the active state. The engine\n   * normally derives these from `state` — a slow breath at idle, a restless\n   * wander while thinking, speech-shaped peaks while speaking — and most\n   * shaders read them as their reactivity. Setting either channel here pins\n   * it instead, which is how the playground lets you dial each state's drive\n   * independently. Omit a channel to keep its synthesized motion.\n   */\n  volumes?: { input?: number; output?: number }\n  /** Freeze the animation on the current frame. */\n  paused?: boolean\n  /**\n   * Stop rendering while the orb is scrolled out of view. Defaults to `true` —\n   * a page full of orbs would otherwise run a WebGL loop per card.\n   */\n  pauseOffscreen?: boolean\n  /** Device-pixel-ratio ceiling. Defaults to `2`. */\n  maxDpr?: number\n  /**\n   * Decoration drawn around the orb — a glass bubble, a dotted bezel, a\n   * viewfinder. Defaults to `\"none\"`, which renders the bare canvas exactly as\n   * it always has, with no extra element in the tree.\n   *\n   * A wrapper never changes the orb's footprint: `size` stays the outer\n   * diameter and the canvas is inset inside it, so switching one on reflows\n   * nothing around it.\n   */\n  wrapper?: OrbWrapper\n  /**\n   * The colour a wrapper draws its lines and dots in. Defaults to\n   * `currentColor` — the inherited text colour — which is what makes the\n   * bezels legible on a light and a dark page without being told which one\n   * they are on. `glass` ignores it: glass has no colour of its own.\n   */\n  wrapperColor?: string\n  /** Applied to the outermost element — the wrapper when there is one. */\n  className?: string\n  /** Merged onto the outermost element's style. */\n  style?: CSSProperties\n  /** Accessible label. When omitted the orb is hidden from assistive tech. */\n  ariaLabel?: string\n}\n\nexport function ShaderOrb({\n  variant,\n  state = \"idle\",\n  size,\n  params,\n  colors,\n  statePresets,\n  stateColors,\n  stateVolumes,\n  volumes,\n  paused = false,\n  pauseOffscreen = true,\n  maxDpr = 2,\n  wrapper = \"none\",\n  wrapperColor,\n  className,\n  style,\n  ariaLabel,\n}: ShaderOrbProps) {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const spec = wrapper === \"none\" ? undefined : WRAPPER_SPECS[wrapper]\n  const wrapped = spec !== undefined\n\n  // Live refs: the render loop reads these every frame, so changing a param\n  // never re-runs the GL setup effect (which would drop the context). Synced in\n  // an effect rather than during render — a ref write during render is unsafe\n  // under concurrent rendering, and the loop picks the new value up on the very\n  // next frame anyway.\n  /*\n    Whether the canvas has drawn a frame yet, tracked per variant because a\n    variant swap mounts a brand new canvas (see the `key` below).\n\n    A mounted-but-never-drawn canvas is at the browser's mercy: rather than\n    the transparent rectangle you would expect, a page that mounts a dozen at\n    once gets white boxes — and in some browsers a broken-image placeholder —\n    for as long as the compositor has nothing to raster. That window is not\n    small here: every orb compiles a full fragment shader synchronously in its\n    own mount effect, so on the gallery grid the first canvases sit empty\n    while the last ones are still compiling. Holding each canvas invisible\n    until its own first frame lands is what makes the grid fade in cleanly\n    instead of flashing. One state change per orb, once, on mount.\n  */\n  const [paintedKey, setPaintedKey] = useState<string | null>(null)\n  const painted = paintedKey === variant.key\n\n  const stateRef = useRef<OrbState>(state)\n  const paramsRef = useRef<OrbParamValues | undefined>(params)\n  const colorsRef = useRef<OrbColorValues | undefined>(colors)\n  const statePresetsRef = useRef(statePresets)\n  const stateColorsRef = useRef(stateColors)\n  const stateVolumesRef = useRef(stateVolumes)\n  const volumesRef = useRef(volumes)\n  const pausedRef = useRef(paused)\n\n  useEffect(() => {\n    stateRef.current = state\n    paramsRef.current = params\n    colorsRef.current = colors\n    statePresetsRef.current = statePresets\n    stateColorsRef.current = stateColors\n    stateVolumesRef.current = stateVolumes\n    volumesRef.current = volumes\n    pausedRef.current = paused\n  }, [\n    state,\n    params,\n    colors,\n    statePresets,\n    stateColors,\n    stateVolumes,\n    volumes,\n    paused,\n  ])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    const gl = canvas.getContext(\"webgl\", {\n      alpha: true,\n      // No MSAA: the geometry is a single full-screen triangle, so there are no\n      // primitive edges to antialias — softness comes from the shaders. Leaving\n      // it on costs the multisample buffers plus a resolve every frame.\n      antialias: false,\n      premultipliedAlpha: true,\n    })\n    if (!gl) return\n\n    const loseExt = gl.getExtension(\"WEBGL_lose_context\")\n\n    /*\n      A \"generation\" is everything tied to a live context: program, buffers,\n      observers, render loop. Browsers cap live WebGL contexts per page and\n      evict the oldest past the cap, and an evicted orb's canvas stays blank\n      forever unless the app rebuilds — so generations tear down and rebuild on\n      the lost/restored events instead of assuming the context is immortal.\n    */\n    let announcedPaint = false\n\n    const startGeneration = (): (() => void) => {\n      if (gl.isContextLost()) return () => {}\n      // Every generation announces its own first frame: a context that was\n      // lost and restored has an empty drawing buffer and is hidden again\n      // (below), so it has to earn its reveal back.\n      announcedPaint = false\n\n      const vs = compile(gl, gl.VERTEX_SHADER, VERT)\n      const fs = compile(\n        gl,\n        gl.FRAGMENT_SHADER,\n        ORB_GLSL_HELPERS + paramUniformDecls(variant) + variant.frag\n      )\n      const releaseShaders = () => {\n        if (vs) gl.deleteShader(vs)\n        if (fs) gl.deleteShader(fs)\n      }\n      if (!vs || !fs) return releaseShaders\n\n      const prog = gl.createProgram()\n      if (!prog) return releaseShaders\n      gl.attachShader(prog, vs)\n      gl.attachShader(prog, fs)\n      gl.linkProgram(prog)\n      if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n        console.error(\n          \"[orbkit] program link error:\",\n          gl.getProgramInfoLog(prog)\n        )\n        gl.deleteProgram(prog)\n        return releaseShaders\n      }\n      gl.useProgram(prog)\n\n      const buf = gl.createBuffer()\n      gl.bindBuffer(gl.ARRAY_BUFFER, buf)\n      gl.bufferData(\n        gl.ARRAY_BUFFER,\n        new Float32Array([-1, -1, 3, -1, -1, 3]),\n        gl.STATIC_DRAW\n      )\n      const aPos = gl.getAttribLocation(prog, \"aPos\")\n      gl.enableVertexAttribArray(aPos)\n      gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0)\n\n      gl.enable(gl.BLEND)\n      gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n\n      const uRes = gl.getUniformLocation(prog, \"uRes\")\n      const uTime = gl.getUniformLocation(prog, \"uTime\")\n      const uAnim = gl.getUniformLocation(prog, \"uAnim\")\n      const uInput = gl.getUniformLocation(prog, \"uInput\")\n      const uOutput = gl.getUniformLocation(prog, \"uOutput\")\n\n      const paramLocs = variant.params.map((p) => ({\n        def: p,\n        loc: gl.getUniformLocation(prog, `uP_${p.key}`),\n      }))\n      const colorLocs = variant.colors.map((c) => ({\n        def: c,\n        loc: gl.getUniformLocation(prog, `uC_${c.key}`),\n      }))\n\n      /* --- sizing: track the element box, not a one-shot measurement ------- */\n      // Backing-store scale, stepped down by the adaptive-resolution logic in\n      // the loop when the GPU can't hold frame rate. CSS size never changes —\n      // the browser upscales, which these soft shaders absorb gracefully.\n      let resScale = 1\n      const resize = () => {\n        const dpr = Math.min(window.devicePixelRatio || 1, maxDpr) * resScale\n        const w = Math.max(1, Math.round(canvas.clientWidth * dpr))\n        const h = Math.max(1, Math.round(canvas.clientHeight * dpr))\n        if (canvas.width !== w || canvas.height !== h) {\n          canvas.width = w\n          canvas.height = h\n          gl.viewport(0, 0, w, h)\n        }\n        /*\n          Uploaded UNCONDITIONALLY, outside the size guard. A rebuilt\n          generation (React strict-mode remount, a restored context) links a\n          fresh program whose uRes starts at zero — and the canvas usually\n          already holds the right backing size, so an upload gated behind\n          the resize never ran. With uRes = 0, orbUV() divides by zero and\n          every fragment lands transparent: a healthy context, a bound\n          program, and a permanently blank orb.\n        */\n        gl.uniform2f(uRes, w, h)\n      }\n      resize()\n\n      const resizeObserver =\n        typeof ResizeObserver !== \"undefined\"\n          ? new ResizeObserver(resize)\n          : null\n      resizeObserver?.observe(canvas)\n\n      /* --- visibility: don't burn a render loop on an offscreen orb -------- */\n      let visible = !pauseOffscreen\n      const intersectionObserver =\n        pauseOffscreen && typeof IntersectionObserver !== \"undefined\"\n          ? new IntersectionObserver(\n              (entries) => {\n                visible = Boolean(entries[0]?.isIntersecting)\n                if (visible) {\n                  last = performance.now() / 1000\n                }\n              },\n              { rootMargin: \"150px 0px\", threshold: 0 }\n            )\n          : null\n      if (intersectionObserver) {\n        intersectionObserver.observe(canvas)\n      } else {\n        visible = true\n      }\n\n      const reduceMotion =\n        typeof window.matchMedia === \"function\" &&\n        window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n\n      /* --- driver state ---------------------------------------------------- */\n      let tSec = 0\n      // random phase so two orbs on the same page never look synchronized\n      let anim = Math.random() * 100\n      let speed = 0.1\n      const cur = { in: 0, out: 0.3 }\n      const presets = variant.statePresets\n      const paramCur: Record<string, number> = {}\n      const paramVel: Record<string, number> = {}\n      const paramClocks: Record<string, number> = {}\n      const colorCur: Record<string, [number, number, number]> = {}\n      const colorVel: Record<string, [number, number, number]> = {}\n      let speedVel = 0\n      const [initialIn, initialOut] = targetVolumes(stateRef.current, 0)\n      cur.in = initialIn\n      cur.out = initialOut\n      let last = performance.now() / 1000\n      let raf = 0\n      // smoothed frame time for the adaptive-resolution check\n      let frameEma = 1 / 60\n\n      const uploadAndDraw = (dt: number, snap = false) => {\n        // Synthesized from the state, unless a channel is pinned via\n        // `volumes`. Pinned values still glide on the same easing, so dialing\n        // one in the playground cross-fades rather than jumping.\n        const [tin, tout] = targetVolumes(stateRef.current, tSec)\n        // Same order as params and colours: direct prop, then the per-state\n        // map, then the engine's own synthesis.\n        const liveVolumes = volumesRef.current\n        const stateVolume = stateVolumesRef.current?.[stateRef.current]\n        const targetIn = liveVolumes?.input ?? stateVolume?.input ?? tin\n        const targetOut = liveVolumes?.output ?? stateVolume?.output ?? tout\n        const kVol = 1 - Math.exp(-dt * 12)\n        cur.in += (targetIn - cur.in) * kVol\n        cur.out += (targetOut - cur.out) * kVol\n\n        /*\n          Flow speed follows the output volume. It multiplies every integrated\n          clock's increment, so it is a RATE: easing it quickly makes the orb\n          visibly lurch — a state change would spin the orb up hard before the\n          params had finished gliding.\n\n          It is therefore eased on the same constant as the params below, so a\n          state change ramps its motion over the same half second that its look\n          takes to cross-fade. The steady-state values are unchanged, so a\n          speaking orb still flows faster than an idle one; only the transition\n          into that rate is gradual.\n        */\n        const targetSpeed = 0.1 + (1 - Math.pow(cur.out - 1, 2)) * 0.9\n        if (snap) {\n          speed = targetSpeed\n          speedVel = 0\n        } else {\n          springStep(speed, speedVel, targetSpeed, dt, PARAM_EASE)\n          speed = springOut.x\n          speedVel = springOut.v\n        }\n        anim += dt * speed\n\n        gl.uniform1f(uTime, tSec * 0.5)\n        gl.uniform1f(uAnim, anim)\n        gl.uniform1f(uInput, cur.in)\n        gl.uniform1f(uOutput, cur.out)\n\n        // Resolution order per param: explicit `params` → `statePresets`\n        // prop → the variant's own preset → schema default. The two middle\n        // steps are per-key, so overriding one param of one state leaves the\n        // rest of that state alone. Values glide rather than snap.\n        const liveParams = paramsRef.current\n        const statePreset = presets?.[stateRef.current]\n        const overridePreset = statePresetsRef.current?.[stateRef.current]\n\n        for (const { def, loc } of paramLocs) {\n          const explicit = liveParams?.[def.key]\n          const target =\n            typeof explicit === \"number\"\n              ? explicit\n              : (overridePreset?.[def.key] ??\n                statePreset?.[def.key] ??\n                def.default)\n          const curVal = paramCur[def.key] ?? target\n          let next: number\n          if (snap) {\n            next = target\n            paramVel[def.key] = 0\n          } else {\n            springStep(curVal, paramVel[def.key] ?? 0, target, dt, PARAM_EASE)\n            next = springOut.x\n            paramVel[def.key] = springOut.v\n          }\n          paramCur[def.key] = next\n\n          if (def.integrate) {\n            const clock =\n              (paramClocks[def.key] ??\n                (paramClocks[def.key] = Math.random() * 100)) +\n              dt * speed * next\n            paramClocks[def.key] = clock\n            gl.uniform1f(loc, clock)\n          } else {\n            gl.uniform1f(loc, next)\n          }\n        }\n\n        // Same resolution order and same easing as params, so a state change\n        // cross-fades the palette instead of cutting to it.\n        const liveColors = colorsRef.current\n        const stateColor = variant.stateColors?.[stateRef.current]\n        const overrideColor = stateColorsRef.current?.[stateRef.current]\n        for (const { def, loc } of colorLocs) {\n          const target = hexToRgb(\n            liveColors?.[def.key] ??\n              overrideColor?.[def.key] ??\n              stateColor?.[def.key] ??\n              def.default\n          )\n          const curCol = (colorCur[def.key] ??= [...target] as [\n            number,\n            number,\n            number,\n          ])\n          const velCol = (colorVel[def.key] ??= [0, 0, 0])\n          for (let i = 0; i < 3; i++) {\n            if (snap) {\n              curCol[i] = target[i]\n              velCol[i] = 0\n            } else {\n              springStep(curCol[i], velCol[i], target[i], dt, PARAM_EASE)\n              curCol[i] = springOut.x\n              velCol[i] = springOut.v\n            }\n          }\n          gl.uniform3f(loc, curCol[0], curCol[1], curCol[2])\n        }\n\n        gl.clearColor(0, 0, 0, 0)\n        gl.clear(gl.COLOR_BUFFER_BIT)\n        gl.drawArrays(gl.TRIANGLES, 0, 3)\n        // Deferred a microtask: the first of these draws runs synchronously\n        // inside this effect, and a sync setState there trips the compiler\n        // lint. A microtask still resolves before the browser paints, so the\n        // reveal is not delayed by a frame.\n        if (!announcedPaint) {\n          announcedPaint = true\n          queueMicrotask(() => {\n            /*\n              Re-check: the context can be evicted between this draw and the\n              microtask, and mounting one more orb anywhere on the page is\n              enough to do it — opening the details drawer over a full gallery\n              is exactly that. Revealing on the strength of a frame that has\n              already been thrown away puts a dead canvas on screen, which is\n              what the browser draws its broken-canvas placeholder over. The\n              generation that follows the restore announces again.\n            */\n            if (gl.isContextLost()) return\n            setPaintedKey(variant.key)\n          })\n        }\n      }\n\n      const releaseGL = () => {\n        resizeObserver?.disconnect()\n        intersectionObserver?.disconnect()\n        gl.deleteProgram(prog)\n        gl.deleteShader(vs)\n        gl.deleteShader(fs)\n        gl.deleteBuffer(buf)\n      }\n\n      if (reduceMotion) {\n        // One representative frame, then stop — snapped straight onto the\n        // state's targets, since a spring would only be part-way there.\n        tSec = 1\n        uploadAndDraw(1, true)\n        return releaseGL\n      }\n\n      const loop = () => {\n        raf = requestAnimationFrame(loop)\n        const now = performance.now() / 1000\n        const dt = Math.min(now - last, 0.05)\n        last = now\n        if (!visible || pausedRef.current) return\n        tSec += dt\n\n        /*\n          Adaptive resolution. When the smoothed frame time sits above ~30fps,\n          the GPU is drowning in fragment work (these shaders are pure fill\n          cost), so step the backing store down 20% and re-measure. Steps only\n          go down — never back up — so the resolution can't oscillate. The\n          warm-up guard keeps page-load jank (hydration, first compiles) from\n          triggering a downgrade the GPU never asked for.\n        */\n        /*\n          Only unstalled frames are evidence about GPU fill cost. `dt` above is\n          clamped at 0.05, so a frame that hits the clamp is the main thread\n          having been blocked — a slider drag re-rendering React, a GC pause, a\n          tab regaining focus — and feeding those in made UI jank look\n          identical to a drowning GPU.\n        */\n        if (dt < 0.05) frameEma += (dt - frameEma) * 0.08\n\n        if (tSec > 1.5 && frameEma > 1 / 34 && resScale > 0.5) {\n          resScale = Math.max(0.5, resScale * 0.8)\n          frameEma = 1 / 60 // require fresh evidence before the next step\n          resize()\n        } else if (tSec > 1.5 && frameEma < 1 / 55 && resScale < 1) {\n          /*\n            And step back up once frames are comfortably fast again. This used\n            to be one-way, on the reasoning that it could not then oscillate —\n            but that also meant one transient stall permanently halved the\n            orb's resolution, and at half resolution a high-frequency shader\n            aliases into shimmer that reads as the shader itself misbehaving.\n            The gap between the two thresholds (29ms down, 18ms up) is the\n            hysteresis that stops it hunting.\n          */\n          resScale = Math.min(1, resScale / 0.8)\n          frameEma = 1 / 60\n          resize()\n        }\n\n        uploadAndDraw(dt)\n      }\n      /*\n        First frame synchronously, before entering the rAF loop. rAF does not\n        run at all in hidden documents (background tabs, embedded previews),\n        so a freshly mounted orb would otherwise sit fully transparent until\n        the page next becomes visible — a grid of mounted, healthy, blank\n        canvases. The sync frame guarantees every mount paints: background\n        documents get a static frame, visible ones start animating over it.\n        dt = 1 lands the param glide on its targets, as in the reduce-motion\n        frame above.\n      */\n      uploadAndDraw(1)\n      loop()\n\n      return () => {\n        cancelAnimationFrame(raf)\n        releaseGL()\n      }\n    }\n\n    /*\n      Wire the canvas's lifecycle controller. The listeners are attached ONCE\n      per canvas element and never removed, deliberately: the lost event must\n      be canceled even while no orb is mounted on the canvas — an uncanceled\n      webglcontextlost marks the context permanently unrestorable, and the\n      router can show this exact canvas again later. Whether a loss leads to\n      a revival is decided by `desired`, not by listener presence.\n    */\n    /*\n      A canvas whose context has gone is not simply blank: Chrome paints its\n      broken-image placeholder over the element's whole box — the white square\n      you see on a reloaded grid. Hide the canvas the moment the context is\n      lost, and let the generation that follows a restore reveal it again.\n    */\n    const hideNow = () => {\n      /*\n        Both, deliberately. The style write lands in this tick — the browser\n        paints its placeholder over a dead canvas immediately, and a busy main\n        thread can hold a React update for several frames. The state change is\n        what keeps React's own view in sync, so the reveal that follows a\n        restore clears the inline value again rather than fighting it.\n      */\n      canvas.style.opacity = \"0\"\n      setPaintedKey(null)\n    }\n\n    const onContextLostHide = () => hideNow()\n    canvas.addEventListener(\"webglcontextlost\", onContextLostHide)\n\n    /*\n      Hand the context back before the next document asks for one.\n\n      A hard reload never runs this effect's cleanup — the document is\n      discarded whole — so the outgoing page's contexts are still alive while\n      the incoming page allocates its own. On a grid of orbs that puts the\n      live count past the browser's ~16 cap, and the ones it evicts are\n      exactly the canvases that come back as placeholders until the restore\n      path catches them. `persisted` is a bfcache suspend, where the page is\n      shown again untouched and must keep everything it holds.\n    */\n    const onPageHide = (event: PageTransitionEvent) => {\n      if (event.persisted) return\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Already released — nothing to hand back.\n      }\n    }\n    window.addEventListener(\"pagehide\", onPageHide)\n\n    let ctl = canvasControllers.get(canvas)\n    if (!ctl) {\n      const created: CanvasContextController = {\n        desired: false,\n        start: null,\n        stopGen: null,\n      }\n      canvas.addEventListener(\"webglcontextlost\", (event) => {\n        event.preventDefault() // always cancel — keeps the context restorable\n        created.stopGen?.()\n        created.stopGen = null\n        if (created.desired) {\n          /*\n            Ask for the context back — but in a LATER task. The browser only\n            marks a loss as restorable once the lost event's dispatch has\n            completed and it has seen the canceled flag, so a restoreContext()\n            issued during dispatch (or before it, as the mount path may) is\n            silently refused. This is the path a synchronous cleanup+setup\n            pair hits — React re-running the effect on the same canvas loses\n            the context and wants it right back. For losses we didn't cause\n            (eviction, GPU reset) the call may refuse; the canceled event then\n            lets the browser restore on its own schedule.\n          */\n          setTimeout(() => {\n            if (!created.desired) return\n            try {\n              loseExt?.restoreContext()\n            } catch {\n              // Natural loss — restoration is the browser's call now.\n            }\n          }, 0)\n        }\n      })\n      canvas.addEventListener(\"webglcontextrestored\", () => {\n        if (created.desired && created.start) {\n          created.stopGen = created.start()\n        }\n      })\n      canvasControllers.set(canvas, created)\n      ctl = created\n    }\n    const controller = ctl\n\n    controller.desired = true\n    controller.start = startGeneration\n    if (gl.isContextLost()) {\n      // A previous run on this canvas released the context (effect re-run, or\n      // the router re-showing a kept-alive page). If the lost event already\n      // dispatched this request is honored now; if it is still queued, the\n      // lost handler above re-requests it on dispatch.\n      try {\n        loseExt?.restoreContext()\n      } catch {\n        // No restore path — the orb stays blank rather than throwing.\n      }\n    } else {\n      controller.stopGen = startGeneration()\n    }\n\n    return () => {\n      /*\n        Hide BEFORE tearing the context down.\n\n        This cleanup releases the context deliberately, and the lost event it\n        provokes is dispatched asynchronously — by which point the listener\n        below is unhooked and the replacement effect has not drawn yet. That\n        leaves a revealed canvas with a dead context, which is precisely what\n        the browser paints its broken-canvas placeholder over. The window is\n        not rare: any prop change in this effect's deps re-runs it, so it hits\n        every time the drawer switches preview example (maxDpr differs on the\n        layout one) or a wrapper is toggled.\n      */\n      hideNow()\n      canvas.removeEventListener(\"webglcontextlost\", onContextLostHide)\n      window.removeEventListener(\"pagehide\", onPageHide)\n      controller.desired = false\n      controller.start = null\n      controller.stopGen?.()\n      controller.stopGen = null\n      /*\n        Release the context NOW instead of when the canvas is garbage\n        collected. Browsers cap live WebGL contexts per page (~8–16) and evict\n        the oldest when the cap is hit — client-side navigation that unmounts\n        and remounts a page of orbs otherwise piles up zombie contexts until\n        freshly mounted orbs get evicted and render blank.\n      */\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Context already lost — nothing to release.\n      }\n    }\n    /*\n      `wrapped` is in here because turning a wrapper on or off moves the canvas\n      from being this component's root element to being a child of the wrapper\n      div — React drops the old element and mounts a new one, and the GL\n      context, its observers and its render loop all belong to the old one. Any\n      other prop leaves the element alone, INCLUDING a swap between two\n      wrappers: the canvas keeps its slot among the decoration layers, so\n      glass -> ring reuses the context instead of rebuilding it.\n    */\n  }, [variant, pauseOffscreen, maxDpr, wrapped])\n\n  const sizeStyle: CSSProperties =\n    size === undefined ? {} : { width: size, height: size }\n\n  /*\n    Spread ahead of the caller's `style`, so an orb that wants to own its own\n    opacity still can — it simply opts out of the reveal.\n\n    A hard flip, deliberately: no transition, no fade. A hidden document\n    (background tab, embedded preview) does not advance CSS transitions, so a\n    faded reveal left orbs pinned at zero in exactly the case the synchronous\n    first frame above exists to serve — mounted, healthy, and invisible. The\n    cut is not a pop either way, since it happens on the frame the orb first\n    has something to show.\n  */\n  const revealStyle: CSSProperties = painted ? {} : { opacity: 0 }\n\n  const canvas = (\n    <canvas\n      // A lost WebGL context can't be reused, so each variant gets a fresh canvas.\n      key={variant.key}\n      ref={canvasRef}\n      className={spec ? undefined : className}\n      style={\n        spec\n          ? {\n              display: \"block\",\n              position: \"absolute\",\n              left: `${spec.inset}%`,\n              top: `${spec.inset}%`,\n              width: `${100 - 2 * spec.inset}%`,\n              height: `${100 - 2 * spec.inset}%`,\n              ...revealStyle,\n              ...(spec.mask ? masked(spec.mask) : {}),\n            }\n          : { display: \"block\", ...sizeStyle, ...revealStyle, ...style }\n      }\n      role={!spec && ariaLabel ? \"img\" : undefined}\n      aria-label={spec ? undefined : ariaLabel}\n      aria-hidden={!spec && ariaLabel ? undefined : true}\n    />\n  )\n\n  if (!spec) return canvas\n\n  /*\n    Wrapped: the box becomes the orb's footprint and the canvas is absolutely\n    positioned inside it. `under`, the canvas and `over` are all positioned\n    with an auto z-index, so they paint in DOM order — decoration behind the\n    orb, then the orb, then decoration in front of it.\n\n    `aspectRatio` is the fallback for the sizeless case: `size` is optional\n    (callers may size the orb with a class instead), and an absolutely\n    positioned canvas contributes nothing to its parent's height, so without\n    it a class that only sets a width would collapse the box to zero.\n  */\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"relative\",\n        aspectRatio: \"1 / 1\",\n        ...(spec.shadow ? { borderRadius: \"50%\", boxShadow: spec.shadow } : {}),\n        ...sizeStyle,\n        ...(wrapperColor ? { color: wrapperColor } : {}),\n        ...style,\n      }}\n      role={ariaLabel ? \"img\" : undefined}\n      aria-label={ariaLabel}\n      aria-hidden={ariaLabel ? undefined : true}\n    >\n      {spec.animated ? (\n        <style\n          href={WRAPPER_STYLE_HREF}\n          precedence=\"default\"\n          dangerouslySetInnerHTML={{ __html: WRAPPER_CSS }}\n        />\n      ) : null}\n      {spec.under}\n      {canvas}\n      {spec.over}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/examples/research-workflow.ts",
          "target": "@components/examples/research-workflow.ts",
          "type": "registry:component",
          "content": "export interface ResearchNote {\n  id: string\n  title: string\n  text: string\n  attached?: boolean\n}\nexport const researchProjects = [\n  {\n    id: \"field-notes\",\n    title: \"West dock interviews\",\n    subtitle: \"Field research · 5 interviews\",\n    question: \"What is slowing down the handoff?\",\n    notes: [\n      {\n        id: \"interview\",\n        title: \"Operator interviews\",\n        text: \"Four of five operators enter the same shipment identifier twice: first on paper, then on a shared tablet. The tablet often arrives after the paper sheet.\",\n      },\n      {\n        id: \"shift\",\n        title: \"Shift-change observation\",\n        text: \"At both observed shift changes, operators checked the clipboard and tablet before confirming which shipment record was current.\",\n      },\n      {\n        id: \"map\",\n        title: \"Workflow map\",\n        text: \"Paper, radio, and tablet steps each copy the shipment identifier. No step owns the canonical record. The team proposed confirming one record at intake and showing its sync status.\",\n      },\n    ],\n  },\n  {\n    id: \"accessibility\",\n    title: \"Wayfinding audit\",\n    subtitle: \"Station arrival · 2 observations\",\n    question: \"What should change in the station signs?\",\n    notes: [\n      {\n        id: \"arrival\",\n        title: \"Arrival walk-through\",\n        text: \"Three visitors paused before the platform turn. Transfer signs compete with advertising at the decision point, and the destination label changes between signs.\",\n      },\n      {\n        id: \"signs\",\n        title: \"Signage review\",\n        text: \"Repeat the same destination label at eye level before each turn. Keep arrows together with the label and validate the route with first-time visitors.\",\n      },\n    ],\n  },\n  {\n    id: \"handoff\",\n    title: \"Research handoff\",\n    subtitle: \"Product team · review brief\",\n    question: \"What needs to be in the handoff?\",\n    notes: [\n      {\n        id: \"review\",\n        title: \"Team review\",\n        text: \"The product team needs observed behavior, interpretation, and open questions separated. Every finding should include a field-note reference and a named owner for validation.\",\n      },\n      {\n        id: \"next\",\n        title: \"Next research round\",\n        text: \"Test the intake confirmation with two operators during one shift. Compare duplicate-entry frequency and ask each operator to identify the current shipment record.\",\n      },\n    ],\n  },\n]\n\n/** Extractive local demo: return the selected notes, never invented research. */\nexport function researchAnswer(\n  question: string,\n  notes: ResearchNote[],\n  concise = false\n) {\n  if (!notes.length)\n    return \"This conversation has no source notes yet. Attach a text note or open one of the research projects to ask about its evidence.\"\n  const terms =\n    question\n      .toLowerCase()\n      .match(/[a-z]{4,}/g)\n      ?.filter(\n        (word) =>\n          ![\n            \"what\",\n            \"with\",\n            \"from\",\n            \"that\",\n            \"this\",\n            \"about\",\n            \"should\",\n            \"could\",\n            \"please\",\n          ].includes(word)\n      ) ?? []\n  const ranked = notes\n    .map((note, index) => ({\n      note,\n      index,\n      score: terms.filter((term) =>\n        `${note.title} ${note.text}`.toLowerCase().includes(term)\n      ).length,\n    }))\n    .sort((a, b) => b.score - a.score)\n  const relevant =\n    ranked[0].score > 0 ? ranked.filter((item) => item.score > 0) : ranked\n  const chosen = relevant.slice(0, concise ? 1 : 3)\n  return `From ${chosen.length === 1 ? \"the selected note\" : \"the selected notes\"}:\\n\\n${chosen.map(({ note, index }) => `${note.text.slice(0, concise ? 220 : 480)}${note.text.length > (concise ? 220 : 480) ? \"…\" : \"\"} [${index + 1}]`).join(\"\\n\\n\")}`\n}\n\nexport function researchReport(\n  title: string,\n  notes: ResearchNote[],\n  answer: string\n) {\n  return `${title}\\n\\nRESEARCH BRIEF\\n\\n${answer}\\n\\nSOURCE NOTES\\n${notes.map((note, index) => `${index + 1}. ${note.title}\\n${note.text}`).join(\"\\n\\n\")}\\n\\nReview these observations with the project team before taking action.`\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE",
          "target": "@components/voice-agents/orbkit/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 zzzzshawn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/orbkit/SOURCE.json",
          "target": "@components/voice-agents/orbkit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"OrbKit\",\n  \"repository\": \"https://github.com/zzzzshawn/orbkit\",\n  \"commit\": \"35e42484560fd35e8502703ba58fa99541d8c686\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 zzzzshawn\",\n  \"core\": \"components/voice-agents/orbkit/core.tsx\",\n  \"credits\": \"components/voice-agents/orbkit/CREDITS.md\",\n  \"shaderLicense\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\",\n  \"changes\": [\n    \"Moved the dependency-free OrbKit runtime and selected variants into the Agents Kit voice collection.\",\n    \"Mapped variant imports to the local shared runtime.\",\n    \"Kept the upstream reduced-motion, offscreen pause, DPR cap, context recovery, and cleanup behavior.\"\n  ],\n  \"exclusions\": [\n    {\n      \"name\": \"shdr-19\",\n      \"reason\": \"Non-commercial XorDev shader; excluded from this distributable MIT collection.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    },\n    {\n      \"name\": \"XorDev shader ports\",\n      \"reason\": \"All variants listed under Shaders by XorDev in CREDITS.md are non-commercial and excluded.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    }\n  ],\n  \"components\": [\n    {\n      \"name\": \"shdr-11\",\n      \"path\": \"shdr-11.tsx\",\n      \"title\": \"Hydrogen\"\n    },\n    {\n      \"name\": \"shdr-13\",\n      \"path\": \"shdr-13.tsx\",\n      \"title\": \"Ion\"\n    },\n    {\n      \"name\": \"shdr-14\",\n      \"path\": \"shdr-14.tsx\",\n      \"title\": \"Dither\"\n    },\n    {\n      \"name\": \"shdr-21\",\n      \"path\": \"shdr-21.tsx\",\n      \"title\": \"Nimbus\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/CREDITS.md",
          "target": "@components/voice-agents/orbkit/CREDITS.md",
          "type": "registry:file",
          "content": "# Credits\n\nOrbkit ships two kinds of orb. Every file says which it is.\n\n## Shaders by XorDev\n\nThese 19 orbs are ported from golfed shaders by [XorDev](https://x.com/XorDev),\nused with his permission (agreed by direct message on 2026-09-06). Terms:\n**non-commercial use only, with attribution to XorDev**. Each file starts with\na notice that must stay with any copy, and the registry marks these items with\na `credit` field. See [LICENSE-SHADERS.md](LICENSE-SHADERS.md).\n\n| Orb     | Shader by | Original             |\n| ------- | --------- | -------------------- |\n| shdr-01 | XorDev    | https://x.com/XorDev |\n| shdr-02 | XorDev    | https://x.com/XorDev |\n| shdr-03 | XorDev    | https://x.com/XorDev |\n| shdr-04 | XorDev    | https://x.com/XorDev |\n| shdr-05 | XorDev    | https://x.com/XorDev |\n| shdr-06 | XorDev    | https://x.com/XorDev |\n| shdr-07 | XorDev    | https://x.com/XorDev |\n| shdr-08 | XorDev    | https://x.com/XorDev |\n| shdr-09 | XorDev    | https://x.com/XorDev |\n| shdr-10 | XorDev    | https://x.com/XorDev |\n| shdr-15 | XorDev    | https://x.com/XorDev |\n| shdr-18 | XorDev    | https://x.com/XorDev |\n| shdr-19 | XorDev    | https://x.com/XorDev |\n| shdr-20 | XorDev    | https://x.com/XorDev |\n| shdr-22 | XorDev    | https://x.com/XorDev |\n| shdr-25 | XorDev    | https://x.com/XorDev |\n| shdr-26 | XorDev    | https://x.com/XorDev |\n| shdr-28 | XorDev    | https://x.com/XorDev |\n| shdr-31 | XorDev    | https://x.com/XorDev |\n\nReplace a profile link with the specific post once it is known.\n\n## Original orbs\n\nThese 14 orbs are Orbkit's own work and are MIT-licensed, like the runtime:\nshdr-11, shdr-12, shdr-13, shdr-14, shdr-16, shdr-17, shdr-21, shdr-23, shdr-24, shdr-27, shdr-29, shdr-30, shdr-32, shdr-33.\n\n## Adding shaders\n\nAsk the original author before porting anything that is not your own. XorDev\nasked to be consulted before any more of his work is included.\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "target": "@components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "type": "registry:file",
          "content": "# Licence for the ported shaders\n\nThe orb files listed under \"Shaders by XorDev\" in [CREDITS.md](CREDITS.md) are\nderived from shaders by XorDev (https://x.com/XorDev) and are used with the\nauthor's permission on these terms:\n\n1. Non-commercial use only.\n2. Attribution to XorDev must be kept with every copy, including the notice at\n   the top of each file.\n3. Any further use of XorDev's work requires asking the author first.\n\nEverything else in this repository, including the runtime\n(`orbkit-core.tsx`), the site, the build scripts, and the original orbs, is\nlicensed under the MIT licence in [LICENSE](LICENSE).\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "App examples"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "example-coding-app",
      "type": "registry:block",
      "title": "Example Coding App",
      "description": "An agent proposes a patch, you review it, and the checks explain the result.",
      "dependencies": [
        "@radix-ui/react-slot@^1.2.2",
        "@radix-ui/react-tooltip@^1.2.6",
        "ansi-to-react@6.2.6",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/examples/coding-app.tsx",
          "target": "@components/examples/coding-app.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  FileTree,\n  FileTreeFile,\n  FileTreeFolder,\n} from \"@/components/ai-elements/file-tree\"\nimport { Terminal } from \"@/components/ai-elements/terminal\"\nimport {\n  TestResults,\n  TestResultsHeader,\n  TestResultsSummary,\n} from \"@/components/ai-elements/test-results\"\nimport { CodeBlock } from \"@/components/beautiful-ui/code-block\"\nimport {\n  PromptInput,\n  PromptInputTextarea,\n} from \"@/components/prompt-kit/prompt-input\"\nimport { Button } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  ArrowUp,\n  Check,\n  ChevronRight,\n  GitBranch,\n  Play,\n  RotateCcw,\n  Square,\n  X,\n} from \"lucide-react\"\nimport { useEffect, useRef, useState } from \"react\"\nimport {\n  checkWorkingFiles,\n  codingFiles,\n  workingCode,\n  type PatchDecision,\n} from \"./coding-workflow\"\n\nexport function CodingAppExample({\n  appearance = \"kit\",\n}: {\n  appearance?: \"basic\" | \"kit\"\n}) {\n  const basic = appearance === \"basic\"\n  const [selected, setSelected] = useState(0)\n  const [decisions, setDecisions] = useState<PatchDecision[]>([\n    \"pending\",\n    \"pending\",\n  ])\n  const [panel, setPanel] = useState<\"changes\" | \"file\" | \"checks\">(\"changes\")\n  const [draft, setDraft] = useState(\"\")\n  const [running, setRunning] = useState(false)\n  const [results, setResults] = useState<ReturnType<\n    typeof checkWorkingFiles\n  > | null>(null)\n  const [notice, setNotice] = useState(\"\")\n  const timer = useRef<ReturnType<typeof setTimeout> | null>(null)\n  useEffect(\n    () => () => {\n      if (timer.current) clearTimeout(timer.current)\n    },\n    []\n  )\n  const stop = () => {\n    if (timer.current) clearTimeout(timer.current)\n    timer.current = null\n    setRunning(false)\n  }\n  const decide = (value: PatchDecision) => {\n    stop()\n    setDecisions((current) =>\n      current.map((item, index) => (index === selected ? value : item))\n    )\n    setResults(null)\n    setNotice(\n      value === \"accepted\"\n        ? \"Patch applied to the working file. Run checks to verify it.\"\n        : value === \"rejected\"\n          ? \"Patch rejected. The working file is unchanged.\"\n          : \"Decision reset. Review the proposed patch again.\"\n    )\n  }\n  const run = () => {\n    stop()\n    setRunning(true)\n    setPanel(\"checks\")\n    setResults(null)\n    setNotice(\"\")\n    timer.current = setTimeout(() => {\n      setResults(checkWorkingFiles(decisions))\n      setRunning(false)\n      timer.current = null\n    }, 650)\n  }\n  const propose = (value: string) => {\n    const text = value.trim().toLowerCase()\n    if (!text) return\n    const index = /limit|query|validat/.test(text)\n      ? 0\n      : /empty|accessib|screen reader/.test(text)\n        ? 1\n        : -1\n    if (index === -1) {\n      setNotice(\n        \"This local example supports query validation and empty-state changes. Choose a task below, or connect your coding agent for other requests.\"\n      )\n      return\n    }\n    stop()\n    setSelected(index)\n    setPanel(\"changes\")\n    setResults(null)\n    setDecisions((current) =>\n      current.map((item, i) => (i === index ? \"pending\" : item))\n    )\n    setDraft(\"\")\n    setNotice(\n      `Proposed patch: ${codingFiles[index].task.toLowerCase()}. Review it before applying.`\n    )\n  }\n  const file = codingFiles[selected]\n  const decision = decisions[selected]\n  const passed = results?.filter((result) => result.passed).length ?? 0\n  const output = results\n    ? [\n        \"Local fixture checks — no shell command was run\",\n        \"\",\n        ...results.map(\n          (result) =>\n            `${result.passed ? \"PASS\" : \"FAIL\"} ${result.name}\\n     ${result.path}`\n        ),\n        \"\",\n        `${passed} passed · ${results.length - passed} failed`,\n        ...(passed < 2\n          ? [\"Apply the remaining patches, then run checks again.\"]\n          : [\"Both accepted changes match the expected file snapshots.\"]),\n      ].join(\"\\n\")\n    : running\n      ? \"Checking the current working files…\"\n      : \"Run checks to inspect the current working files.\"\n  const diff =\n    file.before\n      .split(\"\\n\")\n      .filter(Boolean)\n      .map((line) => `-${line}`)\n      .join(\"\\n\") +\n    \"\\n\" +\n    file.after\n      .split(\"\\n\")\n      .filter(Boolean)\n      .map((line) => `+${line}`)\n      .join(\"\\n\")\n  const tabs = [\n    { id: \"changes\", label: \"Changes\" },\n    { id: \"file\", label: \"Working file\" },\n    { id: \"checks\", label: \"Checks\" },\n  ] as const\n  const selectFile = (index: number) => {\n    setSelected(index)\n    setPanel(\"changes\")\n    setNotice(\"\")\n  }\n\n  return (\n    <section\n      data-app-example=\"coding\"\n      aria-label=\"Coding workspace example\"\n      className={cn(\n        \"text-foreground flex min-w-0 flex-col overflow-hidden border text-sm [&_button]:min-h-6\",\n        basic\n          ? \"bg-background rounded-md\"\n          : \"bg-background rounded-[14px] shadow-sm\"\n      )}\n    >\n      <header className=\"flex min-h-14 flex-wrap items-center justify-between gap-3 border-b px-4 py-3\">\n        <div className=\"flex min-w-0 items-center gap-2 text-[13px]\">\n          <span className=\"font-medium\">Fieldwork</span>\n          <ChevronRight className=\"text-muted-foreground size-3\" aria-hidden />\n          <span className=\"text-muted-foreground\">Visit scheduling</span>\n          <span className=\"text-muted-foreground ml-2 hidden rounded border px-1.5 py-0.5 text-[10px] sm:inline\">\n            Local workspace\n          </span>\n        </div>\n        <Button\n          size=\"sm\"\n          variant=\"outline\"\n          onClick={run}\n          disabled={running}\n          className=\"h-8 gap-2 text-xs\"\n        >\n          <Play className=\"size-3\" aria-hidden />\n          {running ? \"Checking…\" : \"Run checks\"}\n        </Button>\n      </header>\n      <div className=\"grid min-w-0 md:h-[580px] md:grid-cols-[220px_minmax(0,1fr)]\">\n        <aside className=\"bg-muted/20 min-w-0 border-b px-3 py-4 md:overflow-y-auto md:border-r md:border-b-0\">\n          <div className=\"text-muted-foreground mb-5 flex items-center gap-2 px-1 text-xs\">\n            <GitBranch className=\"size-3.5\" aria-hidden />\n            fix/visit-scheduling\n          </div>\n          <p className=\"text-muted-foreground mb-2 px-1 text-[11px] font-medium\">\n            Files\n          </p>\n          {basic ? (\n            <nav aria-label=\"Workspace files\">\n              {codingFiles.map((item, index) => (\n                <button\n                  type=\"button\"\n                  key={item.path}\n                  onClick={() => selectFile(index)}\n                  aria-pressed={selected === index}\n                  className=\"hover:bg-muted block w-full rounded px-2 py-2 text-left text-xs\"\n                >\n                  {item.name}\n                </button>\n              ))}\n            </nav>\n          ) : (\n            <FileTree\n              defaultExpanded={new Set([\"src\", \"routes\", \"components\"])}\n              selectedPath={file.path}\n              onSelect={(path) => {\n                const i = codingFiles.findIndex((item) => item.path === path)\n                if (i >= 0) selectFile(i)\n              }}\n              className=\"border-0 bg-transparent text-xs [&_button]:font-normal\"\n            >\n              <FileTreeFolder name=\"src\" path=\"src\">\n                <FileTreeFolder name=\"routes\" path=\"routes\">\n                  <FileTreeFile name=\"visits.ts\" path={codingFiles[0].path} />\n                </FileTreeFolder>\n                <FileTreeFolder name=\"components\" path=\"components\">\n                  <FileTreeFile\n                    name=\"visit-card.tsx\"\n                    path={codingFiles[1].path}\n                  />\n                </FileTreeFolder>\n              </FileTreeFolder>\n            </FileTree>\n          )}\n          <div className=\"mt-7 border-t pt-4\">\n            <p className=\"text-muted-foreground mb-3 px-1 text-[11px] font-medium\">\n              Review queue\n            </p>\n            {codingFiles.map((item, index) => (\n              <button\n                key={item.path}\n                onClick={() => selectFile(index)}\n                className=\"hover:bg-muted mb-1 flex w-full items-start gap-2 rounded-md px-1 py-2 text-left text-xs\"\n                type=\"button\"\n              >\n                <span className=\"mt-0.5 size-3 shrink-0\" aria-hidden>\n                  {decisions[index] === \"accepted\" ? (\n                    <Check className=\"size-3 text-emerald-600\" />\n                  ) : decisions[index] === \"rejected\" ? (\n                    <X className=\"size-3\" />\n                  ) : (\n                    <span className=\"border-muted-foreground/50 block size-2.5 rounded-full border\" />\n                  )}\n                </span>\n                <span>\n                  {item.task}\n                  <span className=\"text-muted-foreground mt-1 block text-[11px] capitalize\">\n                    {decisions[index]}\n                  </span>\n                </span>\n              </button>\n            ))}\n          </div>\n        </aside>\n        <div className=\"flex min-w-0 flex-col\">\n          <div className=\"flex flex-wrap items-center justify-between gap-2 border-b px-4 py-2\">\n            <div\n              role=\"group\"\n              aria-label=\"Workspace view\"\n              className=\"flex flex-wrap gap-1\"\n            >\n              {tabs.map((tab) => (\n                <Button\n                  key={tab.id}\n                  size=\"sm\"\n                  variant={panel === tab.id ? \"secondary\" : \"ghost\"}\n                  aria-pressed={panel === tab.id}\n                  onClick={() => setPanel(tab.id)}\n                  className=\"h-8 rounded-md text-xs\"\n                >\n                  {tab.label}\n                </Button>\n              ))}\n            </div>\n            <span className=\"text-muted-foreground text-[11px]\">\n              {decisions.filter((item) => item === \"accepted\").length} of 2\n              applied\n            </span>\n          </div>\n          <div className=\"min-h-[320px] min-w-0 flex-1 overflow-auto p-4 md:min-h-0\">\n            {panel !== \"checks\" ? (\n              <>\n                <div className=\"mb-4 flex flex-wrap items-center justify-between gap-3\">\n                  <div>\n                    <h3 className=\"text-[13px] font-medium\">{file.task}</h3>\n                    <p className=\"text-muted-foreground mt-1 text-xs\">\n                      {panel === \"file\"\n                        ? \"Current working copy\"\n                        : \"Proposed change\"}{\" \"}\n                      · {decision}\n                    </p>\n                  </div>\n                  {panel === \"changes\" && (\n                    <div className=\"flex gap-2\">\n                      {decision === \"pending\" ? (\n                        <>\n                          <Button\n                            size=\"sm\"\n                            variant=\"ghost\"\n                            onClick={() => decide(\"rejected\")}\n                            className=\"h-8 text-xs\"\n                          >\n                            Reject\n                          </Button>\n                          <Button\n                            size=\"sm\"\n                            onClick={() => decide(\"accepted\")}\n                            className=\"h-8 gap-1.5 text-xs\"\n                          >\n                            <Check className=\"size-3\" aria-hidden />\n                            Apply patch\n                          </Button>\n                        </>\n                      ) : (\n                        <Button\n                          size=\"sm\"\n                          variant=\"outline\"\n                          onClick={() => decide(\"pending\")}\n                          className=\"h-8 gap-1.5 text-xs\"\n                        >\n                          <RotateCcw className=\"size-3\" aria-hidden />\n                          Reset decision\n                        </Button>\n                      )}\n                    </div>\n                  )}\n                </div>\n                {basic ? (\n                  <pre className=\"overflow-x-auto rounded border p-3 font-mono text-xs leading-6\">\n                    {panel === \"changes\"\n                      ? diff\n                      : workingCode(selected, decisions)}\n                  </pre>\n                ) : (\n                  <CodeBlock\n                    filename={file.path}\n                    code={\n                      panel === \"changes\"\n                        ? diff\n                        : workingCode(selected, decisions)\n                    }\n                    variant={panel === \"changes\" ? \"diff\" : \"code\"}\n                    language={selected ? \"tsx\" : \"typescript\"}\n                    className=\"rounded-lg shadow-none\"\n                  />\n                )}\n                {panel === \"changes\" && (\n                  <p className=\"text-muted-foreground mt-4 text-xs leading-5\">\n                    Applying a patch updates the working copy. Checks read that\n                    copy, so rejecting a required change leaves its check\n                    failing.\n                  </p>\n                )}\n              </>\n            ) : (\n              <div className=\"space-y-4\">\n                <div className=\"flex items-center justify-between\">\n                  <h3 className=\"text-[13px] font-medium\">\n                    Working-copy checks\n                  </h3>\n                  {running && (\n                    <Button\n                      size=\"sm\"\n                      variant=\"ghost\"\n                      onClick={() => {\n                        stop()\n                        setNotice(\"Checks stopped. Run checks to try again.\")\n                      }}\n                      className=\"h-8 gap-1.5 text-xs\"\n                    >\n                      <Square className=\"size-3\" aria-hidden />\n                      Stop checks\n                    </Button>\n                  )}\n                </div>\n                {basic ? (\n                  <pre className=\"overflow-auto rounded border p-4 text-xs leading-6 whitespace-pre-wrap\">\n                    {output}\n                  </pre>\n                ) : (\n                  <Terminal output={output} className=\"rounded-lg text-xs\" />\n                )}\n                {results &&\n                  (basic ? (\n                    <p role=\"status\" className=\"text-xs\">\n                      {passed} passed · {2 - passed} failed\n                    </p>\n                  ) : (\n                    <TestResults\n                      summary={{\n                        passed,\n                        failed: 2 - passed,\n                        skipped: 0,\n                        total: 2,\n                      }}\n                    >\n                      <TestResultsHeader>\n                        <TestResultsSummary />\n                      </TestResultsHeader>\n                    </TestResults>\n                  ))}\n              </div>\n            )}\n            <p\n              role=\"status\"\n              className=\"text-muted-foreground mt-4 text-xs leading-5\"\n            >\n              {notice}\n            </p>\n          </div>\n          <div className=\"border-t px-4 py-3\">\n            <div className=\"mb-2 flex flex-wrap gap-2\">\n              {codingFiles.map((item, index) => (\n                <button\n                  key={item.path}\n                  type=\"button\"\n                  onClick={() =>\n                    propose(index ? \"Improve empty state\" : \"Fix query limit\")\n                  }\n                  className=\"text-muted-foreground decoration-border hover:text-foreground text-[11px] underline underline-offset-4\"\n                >\n                  {item.task}\n                </button>\n              ))}\n            </div>\n            {basic ? (\n              <form\n                className=\"flex gap-2\"\n                onSubmit={(event) => {\n                  event.preventDefault()\n                  propose(draft)\n                }}\n              >\n                <label className=\"min-w-0 flex-1\">\n                  <span className=\"sr-only\">Follow-up request</span>\n                  <input\n                    value={draft}\n                    onChange={(event) => setDraft(event.target.value)}\n                    placeholder=\"Request a sample change…\"\n                    className=\"h-10 w-full rounded border bg-transparent px-3 text-base sm:text-sm\"\n                  />\n                </label>\n                <Button type=\"submit\" size=\"sm\">\n                  Propose\n                </Button>\n              </form>\n            ) : (\n              <PromptInput\n                value={draft}\n                onValueChange={setDraft}\n                onSubmit={() => propose(draft)}\n                className=\"focus-within:ring-ring flex items-center gap-2 rounded-lg p-1 shadow-none focus-within:ring-2\"\n              >\n                <PromptInputTextarea\n                  aria-label=\"Follow-up request\"\n                  placeholder=\"Request a sample change…\"\n                  className=\"min-h-10 px-2 text-base sm:text-[13px]\"\n                />\n                <Button\n                  size=\"sm\"\n                  disabled={!draft.trim()}\n                  onClick={() => propose(draft)}\n                  aria-label=\"Propose change\"\n                  className=\"mr-1 size-8 shrink-0 p-0\"\n                >\n                  <ArrowUp className=\"size-3.5\" aria-hidden />\n                </Button>\n              </PromptInput>\n            )}\n            <p className=\"text-muted-foreground mt-2 text-[10px]\">\n              Local fixture · no commands run · connect your coding agent for\n              other changes\n            </p>\n          </div>\n        </div>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/file-tree.tsx",
          "target": "@components/ai-elements/file-tree.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  ChevronRightIcon,\n  FileIcon,\n  FolderIcon,\n  FolderOpenIcon,\n} from \"lucide-react\"\nimport type { HTMLAttributes, ReactNode } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useMemo,\n  useState,\n} from \"react\"\n\ninterface FileTreeContextType {\n  expandedPaths: Set<string>\n  togglePath: (path: string) => void\n  selectedPath?: string\n  onSelect?: (path: string) => void\n}\n\n// Default noop for context default value\n// oxlint-disable-next-line eslint(no-empty-function)\nconst noop = () => {}\n\nconst FileTreeContext = createContext<FileTreeContextType>({\n  // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)\n  expandedPaths: new Set(),\n  togglePath: noop,\n})\n\nexport type FileTreeProps = Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> & {\n  expanded?: Set<string>\n  defaultExpanded?: Set<string>\n  selectedPath?: string\n  onSelect?: (path: string) => void\n  onExpandedChange?: (expanded: Set<string>) => void\n}\n\nexport const FileTree = ({\n  expanded: controlledExpanded,\n  defaultExpanded = new Set(),\n  selectedPath,\n  onSelect,\n  onExpandedChange,\n  className,\n  children,\n  ...props\n}: FileTreeProps) => {\n  const [internalExpanded, setInternalExpanded] = useState(defaultExpanded)\n  const expandedPaths = controlledExpanded ?? internalExpanded\n\n  const togglePath = useCallback(\n    (path: string) => {\n      const newExpanded = new Set(expandedPaths)\n      if (newExpanded.has(path)) {\n        newExpanded.delete(path)\n      } else {\n        newExpanded.add(path)\n      }\n      setInternalExpanded(newExpanded)\n      onExpandedChange?.(newExpanded)\n    },\n    [expandedPaths, onExpandedChange]\n  )\n\n  const contextValue = useMemo(\n    () => ({ expandedPaths, onSelect, selectedPath, togglePath }),\n    [expandedPaths, onSelect, selectedPath, togglePath]\n  )\n\n  return (\n    <FileTreeContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"bg-background rounded-lg border font-mono text-sm\",\n          className\n        )}\n        role=\"tree\"\n        {...props}\n      >\n        <div className=\"p-2\">{children}</div>\n      </div>\n    </FileTreeContext.Provider>\n  )\n}\n\nexport type FileTreeIconProps = HTMLAttributes<HTMLSpanElement>\n\nexport const FileTreeIcon = ({\n  className,\n  children,\n  ...props\n}: FileTreeIconProps) => (\n  <span className={cn(\"shrink-0\", className)} {...props}>\n    {children}\n  </span>\n)\n\nexport type FileTreeNameProps = HTMLAttributes<HTMLSpanElement>\n\nexport const FileTreeName = ({\n  className,\n  children,\n  ...props\n}: FileTreeNameProps) => (\n  <span className={cn(\"truncate\", className)} {...props}>\n    {children}\n  </span>\n)\n\ninterface FileTreeFolderContextType {\n  path: string\n  name: string\n  isExpanded: boolean\n}\n\nconst FileTreeFolderContext = createContext<FileTreeFolderContextType>({\n  isExpanded: false,\n  name: \"\",\n  path: \"\",\n})\n\nexport type FileTreeFolderProps = HTMLAttributes<HTMLDivElement> & {\n  path: string\n  name: string\n}\n\nexport const FileTreeFolder = ({\n  path,\n  name,\n  className,\n  children,\n  ...props\n}: FileTreeFolderProps) => {\n  const { expandedPaths, togglePath, selectedPath, onSelect } =\n    useContext(FileTreeContext)\n  const isExpanded = expandedPaths.has(path)\n  const isSelected = selectedPath === path\n\n  const handleOpenChange = useCallback(() => {\n    togglePath(path)\n  }, [togglePath, path])\n\n  const handleSelect = useCallback(() => {\n    onSelect?.(path)\n  }, [onSelect, path])\n\n  const folderContextValue = useMemo(\n    () => ({ isExpanded, name, path }),\n    [isExpanded, name, path]\n  )\n\n  return (\n    <FileTreeFolderContext.Provider value={folderContextValue}>\n      <Collapsible onOpenChange={handleOpenChange} open={isExpanded}>\n        <div\n          aria-selected={isSelected}\n          className={cn(\"\", className)}\n          role=\"treeitem\"\n          tabIndex={0}\n          {...props}\n        >\n          <div\n            className={cn(\n              \"hover:bg-muted/50 flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors\",\n              isSelected && \"bg-muted\"\n            )}\n          >\n            <CollapsibleTrigger asChild>\n              <button\n                className=\"flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0\"\n                type=\"button\"\n              >\n                <ChevronRightIcon\n                  className={cn(\n                    \"text-muted-foreground size-4 shrink-0 transition-transform\",\n                    isExpanded && \"rotate-90\"\n                  )}\n                />\n              </button>\n            </CollapsibleTrigger>\n            <button\n              className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left\"\n              onClick={handleSelect}\n              type=\"button\"\n            >\n              <FileTreeIcon>\n                {isExpanded ? (\n                  <FolderOpenIcon className=\"size-4 text-blue-500\" />\n                ) : (\n                  <FolderIcon className=\"size-4 text-blue-500\" />\n                )}\n              </FileTreeIcon>\n              <FileTreeName>{name}</FileTreeName>\n            </button>\n          </div>\n          <CollapsibleContent>\n            <div className=\"ml-4 border-l pl-2\">{children}</div>\n          </CollapsibleContent>\n        </div>\n      </Collapsible>\n    </FileTreeFolderContext.Provider>\n  )\n}\n\ninterface FileTreeFileContextType {\n  path: string\n  name: string\n}\n\nconst FileTreeFileContext = createContext<FileTreeFileContextType>({\n  name: \"\",\n  path: \"\",\n})\n\nexport type FileTreeFileProps = HTMLAttributes<HTMLDivElement> & {\n  path: string\n  name: string\n  icon?: ReactNode\n}\n\nexport const FileTreeFile = ({\n  path,\n  name,\n  icon,\n  className,\n  children,\n  ...props\n}: FileTreeFileProps) => {\n  const { selectedPath, onSelect } = useContext(FileTreeContext)\n  const isSelected = selectedPath === path\n\n  const handleClick = useCallback(() => {\n    onSelect?.(path)\n  }, [onSelect, path])\n\n  const handleKeyDown = useCallback(\n    (e: React.KeyboardEvent) => {\n      if (e.key === \"Enter\" || e.key === \" \") {\n        onSelect?.(path)\n      }\n    },\n    [onSelect, path]\n  )\n\n  const fileContextValue = useMemo(() => ({ name, path }), [name, path])\n\n  return (\n    <FileTreeFileContext.Provider value={fileContextValue}>\n      <div\n        aria-selected={isSelected}\n        className={cn(\n          \"hover:bg-muted/50 flex cursor-pointer items-center gap-1 rounded px-2 py-1 transition-colors\",\n          isSelected && \"bg-muted\",\n          className\n        )}\n        onClick={handleClick}\n        onKeyDown={handleKeyDown}\n        role=\"treeitem\"\n        tabIndex={0}\n        {...props}\n      >\n        {children ?? (\n          <>\n            {/* Spacer for alignment */}\n            <span className=\"size-4 shrink-0\" />\n            <FileTreeIcon>\n              {icon ?? <FileIcon className=\"text-muted-foreground size-4\" />}\n            </FileTreeIcon>\n            <FileTreeName>{name}</FileTreeName>\n          </>\n        )}\n      </div>\n    </FileTreeFileContext.Provider>\n  )\n}\n\nexport type FileTreeActionsProps = HTMLAttributes<HTMLDivElement>\n\nconst stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation()\n\nexport const FileTreeActions = ({\n  className,\n  children,\n  ...props\n}: FileTreeActionsProps) => (\n  <div\n    className={cn(\"ml-auto flex items-center gap-1\", className)}\n    onClick={stopPropagation}\n    onKeyDown={stopPropagation}\n    role=\"group\"\n    {...props}\n  >\n    {children}\n  </div>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/terminal.tsx",
          "target": "@components/ai-elements/terminal.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport Ansi from \"ansi-to-react\"\nimport { CheckIcon, CopyIcon, TerminalIcon, Trash2Icon } from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\ninterface TerminalContextType {\n  output: string\n  isStreaming: boolean\n  autoScroll: boolean\n  onClear?: () => void\n}\n\nconst TerminalContext = createContext<TerminalContextType>({\n  autoScroll: true,\n  isStreaming: false,\n  output: \"\",\n})\n\nexport type TerminalHeaderProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalHeader = ({\n  className,\n  children,\n  ...props\n}: TerminalHeaderProps) => (\n  <div\n    className={cn(\n      \"flex items-center justify-between border-b border-zinc-800 px-4 py-2\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type TerminalTitleProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalTitle = ({\n  className,\n  children,\n  ...props\n}: TerminalTitleProps) => (\n  <div\n    className={cn(\"flex items-center gap-2 text-sm text-zinc-400\", className)}\n    {...props}\n  >\n    <TerminalIcon className=\"size-4\" />\n    {children ?? \"Terminal\"}\n  </div>\n)\n\nexport type TerminalStatusProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalStatus = ({\n  className,\n  children,\n  ...props\n}: TerminalStatusProps) => {\n  const { isStreaming } = useContext(TerminalContext)\n\n  if (!isStreaming) {\n    return null\n  }\n\n  return (\n    <div\n      className={cn(\"flex items-center gap-2 text-xs text-zinc-400\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type TerminalActionsProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalActions = ({\n  className,\n  children,\n  ...props\n}: TerminalActionsProps) => (\n  <div className={cn(\"flex items-center gap-1\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type TerminalCopyButtonProps = ComponentProps<typeof Button> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const TerminalCopyButton = ({\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  className,\n  ...props\n}: TerminalCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n  const { output } = useContext(TerminalContext)\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      await navigator.clipboard.writeText(output)\n      setIsCopied(true)\n      onCopy?.()\n      timeoutRef.current = window.setTimeout(() => setIsCopied(false), timeout)\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [output, onCopy, onError, timeout])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <Button\n      className={cn(\n        \"size-7 shrink-0 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100\",\n        className\n      )}\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type TerminalClearButtonProps = ComponentProps<typeof Button>\n\nexport const TerminalClearButton = ({\n  children,\n  className,\n  ...props\n}: TerminalClearButtonProps) => {\n  const { onClear } = useContext(TerminalContext)\n\n  if (!onClear) {\n    return null\n  }\n\n  return (\n    <Button\n      className={cn(\n        \"size-7 shrink-0 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100\",\n        className\n      )}\n      onClick={onClear}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Trash2Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type TerminalContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalContent = ({\n  className,\n  children,\n  ...props\n}: TerminalContentProps) => {\n  const { output, isStreaming, autoScroll } = useContext(TerminalContext)\n  const containerRef = useRef<HTMLDivElement>(null)\n\n  useEffect(() => {\n    if (autoScroll && containerRef.current) {\n      containerRef.current.scrollTop = containerRef.current.scrollHeight\n    }\n  }, [output, autoScroll])\n\n  return (\n    <div\n      className={cn(\n        \"max-h-96 overflow-auto p-4 font-mono text-sm leading-relaxed\",\n        className\n      )}\n      ref={containerRef}\n      {...props}\n    >\n      {children ?? (\n        <pre className=\"break-words whitespace-pre-wrap\">\n          <Ansi>{output}</Ansi>\n          {isStreaming && (\n            <span className=\"ml-0.5 inline-block h-4 w-2 animate-pulse bg-zinc-100\" />\n          )}\n        </pre>\n      )}\n    </div>\n  )\n}\n\nexport type TerminalProps = HTMLAttributes<HTMLDivElement> & {\n  output: string\n  isStreaming?: boolean\n  autoScroll?: boolean\n  onClear?: () => void\n}\n\nexport const Terminal = ({\n  output,\n  isStreaming = false,\n  autoScroll = true,\n  onClear,\n  className,\n  children,\n  ...props\n}: TerminalProps) => {\n  const contextValue = useMemo(\n    () => ({ autoScroll, isStreaming, onClear, output }),\n    [autoScroll, isStreaming, onClear, output]\n  )\n\n  return (\n    <TerminalContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"flex flex-col overflow-hidden rounded-lg border bg-zinc-950 text-zinc-100\",\n          className\n        )}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <TerminalHeader>\n              <TerminalTitle />\n              <div className=\"flex items-center gap-1\">\n                <TerminalStatus />\n                <TerminalActions>\n                  <TerminalCopyButton />\n                  {onClear && <TerminalClearButton />}\n                </TerminalActions>\n              </div>\n            </TerminalHeader>\n            <TerminalContent />\n          </>\n        )}\n      </div>\n    </TerminalContext.Provider>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ai-elements/test-results.tsx",
          "target": "@components/ai-elements/test-results.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  CheckCircle2Icon,\n  ChevronRightIcon,\n  CircleDotIcon,\n  CircleIcon,\n  XCircleIcon,\n} from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\nimport { createContext, useContext, useMemo } from \"react\"\n\ntype TestStatus = \"passed\" | \"failed\" | \"skipped\" | \"running\"\n\ninterface TestResultsSummary {\n  passed: number\n  failed: number\n  skipped: number\n  total: number\n  duration?: number\n}\n\ninterface TestResultsContextType {\n  summary?: TestResultsSummary\n}\n\nconst TestResultsContext = createContext<TestResultsContextType>({})\n\nconst formatDuration = (ms: number) => {\n  if (ms < 1000) {\n    return `${ms}ms`\n  }\n  return `${(ms / 1000).toFixed(2)}s`\n}\n\nexport type TestResultsHeaderProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestResultsHeader = ({\n  className,\n  children,\n  ...props\n}: TestResultsHeaderProps) => (\n  <div\n    className={cn(\n      \"flex items-center justify-between border-b px-4 py-3\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type TestResultsDurationProps = HTMLAttributes<HTMLSpanElement>\n\nexport const TestResultsDuration = ({\n  className,\n  children,\n  ...props\n}: TestResultsDurationProps) => {\n  const { summary } = useContext(TestResultsContext)\n\n  if (!summary?.duration) {\n    return null\n  }\n\n  return (\n    <span className={cn(\"text-muted-foreground text-sm\", className)} {...props}>\n      {children ?? formatDuration(summary.duration)}\n    </span>\n  )\n}\n\nexport type TestResultsSummaryProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestResultsSummary = ({\n  className,\n  children,\n  ...props\n}: TestResultsSummaryProps) => {\n  const { summary } = useContext(TestResultsContext)\n\n  if (!summary) {\n    return null\n  }\n\n  return (\n    <div className={cn(\"flex items-center gap-3\", className)} {...props}>\n      {children ?? (\n        <>\n          <Badge\n            className=\"gap-1 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\"\n            variant=\"secondary\"\n          >\n            <CheckCircle2Icon className=\"size-3\" />\n            {summary.passed} passed\n          </Badge>\n          {summary.failed > 0 && (\n            <Badge\n              className=\"gap-1 bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400\"\n              variant=\"secondary\"\n            >\n              <XCircleIcon className=\"size-3\" />\n              {summary.failed} failed\n            </Badge>\n          )}\n          {summary.skipped > 0 && (\n            <Badge\n              className=\"gap-1 bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400\"\n              variant=\"secondary\"\n            >\n              <CircleIcon className=\"size-3\" />\n              {summary.skipped} skipped\n            </Badge>\n          )}\n        </>\n      )}\n    </div>\n  )\n}\n\nexport type TestResultsProps = HTMLAttributes<HTMLDivElement> & {\n  summary?: TestResultsSummary\n}\n\nexport const TestResults = ({\n  summary,\n  className,\n  children,\n  ...props\n}: TestResultsProps) => {\n  const contextValue = useMemo(() => ({ summary }), [summary])\n\n  return (\n    <TestResultsContext.Provider value={contextValue}>\n      <div\n        className={cn(\"bg-background rounded-lg border\", className)}\n        {...props}\n      >\n        {children ??\n          (summary && (\n            <TestResultsHeader>\n              <TestResultsSummary />\n              <TestResultsDuration />\n            </TestResultsHeader>\n          ))}\n      </div>\n    </TestResultsContext.Provider>\n  )\n}\n\nexport type TestResultsProgressProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestResultsProgress = ({\n  className,\n  children,\n  ...props\n}: TestResultsProgressProps) => {\n  const { summary } = useContext(TestResultsContext)\n\n  if (!summary) {\n    return null\n  }\n\n  const passedPercent = (summary.passed / summary.total) * 100\n  const failedPercent = (summary.failed / summary.total) * 100\n\n  return (\n    <div className={cn(\"space-y-2\", className)} {...props}>\n      {children ?? (\n        <>\n          <div className=\"bg-muted flex h-2 overflow-hidden rounded-full\">\n            <div\n              className=\"bg-green-500 transition-all\"\n              style={{ width: `${passedPercent}%` }}\n            />\n            <div\n              className=\"bg-red-500 transition-all\"\n              style={{ width: `${failedPercent}%` }}\n            />\n          </div>\n          <div className=\"text-muted-foreground flex justify-between text-xs\">\n            <span>\n              {summary.passed}/{summary.total} tests passed\n            </span>\n            <span>{passedPercent.toFixed(0)}%</span>\n          </div>\n        </>\n      )}\n    </div>\n  )\n}\n\nexport type TestResultsContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestResultsContent = ({\n  className,\n  children,\n  ...props\n}: TestResultsContentProps) => (\n  <div className={cn(\"space-y-2 p-4\", className)} {...props}>\n    {children}\n  </div>\n)\n\ninterface TestSuiteContextType {\n  name: string\n  status: TestStatus\n}\n\nconst TestSuiteContext = createContext<TestSuiteContextType>({\n  name: \"\",\n  status: \"passed\",\n})\n\nconst statusStyles: Record<TestStatus, string> = {\n  failed: \"text-red-600 dark:text-red-400\",\n  passed: \"text-green-600 dark:text-green-400\",\n  running: \"text-blue-600 dark:text-blue-400\",\n  skipped: \"text-yellow-600 dark:text-yellow-400\",\n}\n\nconst statusIcons: Record<TestStatus, React.ReactNode> = {\n  failed: <XCircleIcon className=\"size-4\" />,\n  passed: <CheckCircle2Icon className=\"size-4\" />,\n  running: <CircleDotIcon className=\"size-4 animate-pulse\" />,\n  skipped: <CircleIcon className=\"size-4\" />,\n}\n\nconst TestStatusIcon = ({ status }: { status: TestStatus }) => (\n  <span className={cn(\"shrink-0\", statusStyles[status])}>\n    {statusIcons[status]}\n  </span>\n)\n\nexport type TestSuiteProps = ComponentProps<typeof Collapsible> & {\n  name: string\n  status: TestStatus\n}\n\nexport const TestSuite = ({\n  name,\n  status,\n  className,\n  children,\n  ...props\n}: TestSuiteProps) => {\n  const contextValue = useMemo(() => ({ name, status }), [name, status])\n\n  return (\n    <TestSuiteContext.Provider value={contextValue}>\n      <Collapsible className={cn(\"rounded-lg border\", className)} {...props}>\n        {children}\n      </Collapsible>\n    </TestSuiteContext.Provider>\n  )\n}\n\nexport type TestSuiteNameProps = ComponentProps<typeof CollapsibleTrigger>\n\nexport const TestSuiteName = ({\n  className,\n  children,\n  ...props\n}: TestSuiteNameProps) => {\n  const { name, status } = useContext(TestSuiteContext)\n\n  return (\n    <CollapsibleTrigger\n      className={cn(\n        \"group hover:bg-muted/50 flex w-full items-center gap-2 px-4 py-3 text-left transition-colors\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronRightIcon className=\"text-muted-foreground size-4 shrink-0 transition-transform group-data-[state=open]:rotate-90\" />\n      <TestStatusIcon status={status} />\n      <span className=\"text-sm font-medium\">{children ?? name}</span>\n    </CollapsibleTrigger>\n  )\n}\n\nexport type TestSuiteStatsProps = HTMLAttributes<HTMLDivElement> & {\n  passed?: number\n  failed?: number\n  skipped?: number\n}\n\nexport const TestSuiteStats = ({\n  passed = 0,\n  failed = 0,\n  skipped = 0,\n  className,\n  children,\n  ...props\n}: TestSuiteStatsProps) => (\n  <div\n    className={cn(\"ml-auto flex items-center gap-2 text-xs\", className)}\n    {...props}\n  >\n    {children ?? (\n      <>\n        {passed > 0 && (\n          <span className=\"text-green-600 dark:text-green-400\">\n            {passed} passed\n          </span>\n        )}\n        {failed > 0 && (\n          <span className=\"text-red-600 dark:text-red-400\">\n            {failed} failed\n          </span>\n        )}\n        {skipped > 0 && (\n          <span className=\"text-yellow-600 dark:text-yellow-400\">\n            {skipped} skipped\n          </span>\n        )}\n      </>\n    )}\n  </div>\n)\n\nexport type TestSuiteContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const TestSuiteContent = ({\n  className,\n  children,\n  ...props\n}: TestSuiteContentProps) => (\n  <CollapsibleContent className={cn(\"border-t\", className)} {...props}>\n    <div className=\"divide-y\">{children}</div>\n  </CollapsibleContent>\n)\n\ninterface TestContextType {\n  name: string\n  status: TestStatus\n  duration?: number\n}\n\nconst TestContext = createContext<TestContextType>({\n  name: \"\",\n  status: \"passed\",\n})\n\nexport type TestNameProps = HTMLAttributes<HTMLSpanElement>\n\nexport const TestName = ({ className, children, ...props }: TestNameProps) => {\n  const { name } = useContext(TestContext)\n\n  return (\n    <span className={cn(\"flex-1\", className)} {...props}>\n      {children ?? name}\n    </span>\n  )\n}\n\nexport type TestDurationProps = HTMLAttributes<HTMLSpanElement>\n\nexport const TestDuration = ({\n  className,\n  children,\n  ...props\n}: TestDurationProps) => {\n  const { duration } = useContext(TestContext)\n\n  if (duration === undefined) {\n    return null\n  }\n\n  return (\n    <span\n      className={cn(\"text-muted-foreground ml-auto text-xs\", className)}\n      {...props}\n    >\n      {children ?? `${duration}ms`}\n    </span>\n  )\n}\n\nexport type TestStatusProps = HTMLAttributes<HTMLSpanElement>\n\nexport const TestStatus = ({\n  className,\n  children,\n  ...props\n}: TestStatusProps) => {\n  const { status } = useContext(TestContext)\n\n  return (\n    <span\n      className={cn(\"shrink-0\", statusStyles[status], className)}\n      {...props}\n    >\n      {children ?? statusIcons[status]}\n    </span>\n  )\n}\n\nexport type TestProps = HTMLAttributes<HTMLDivElement> & {\n  name: string\n  status: TestStatus\n  duration?: number\n}\n\nexport const Test = ({\n  name,\n  status,\n  duration,\n  className,\n  children,\n  ...props\n}: TestProps) => {\n  const contextValue = useMemo(\n    () => ({ duration, name, status }),\n    [duration, name, status]\n  )\n\n  return (\n    <TestContext.Provider value={contextValue}>\n      <div\n        className={cn(\"flex items-center gap-2 px-4 py-2 text-sm\", className)}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <TestStatus />\n            <TestName />\n            {duration !== undefined && <TestDuration />}\n          </>\n        )}\n      </div>\n    </TestContext.Provider>\n  )\n}\n\nexport type TestErrorProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestError = ({\n  className,\n  children,\n  ...props\n}: TestErrorProps) => (\n  <div\n    className={cn(\n      \"mt-2 rounded-md bg-red-50 p-3 dark:bg-red-900/20\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type TestErrorMessageProps = HTMLAttributes<HTMLParagraphElement>\n\nexport const TestErrorMessage = ({\n  className,\n  children,\n  ...props\n}: TestErrorMessageProps) => (\n  <p\n    className={cn(\n      \"text-sm font-medium text-red-700 dark:text-red-400\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </p>\n)\n\nexport type TestErrorStackProps = HTMLAttributes<HTMLPreElement>\n\nexport const TestErrorStack = ({\n  className,\n  children,\n  ...props\n}: TestErrorStackProps) => (\n  <pre\n    className={cn(\n      \"mt-2 overflow-auto font-mono text-xs text-red-600 dark:text-red-400\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </pre>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "components/beautiful-ui/code-block.tsx",
          "target": "@components/beautiful-ui/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Copy } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport type CodeBlockVariant = \"code\" | \"diff\"\nexport interface CodePiece {\n  text: string\n  change?: \"add\" | \"del\"\n}\nexport interface CodeDiffRow {\n  oldLine: number | null\n  newLine: number | null\n  type: \"context\" | \"add\" | \"remove\"\n  pieces: CodePiece[]\n}\nexport interface CodeBlockLabels {\n  copy: string\n  copied: string\n}\nexport interface CodeBlockProps {\n  code: string\n  language?: string\n  variant?: CodeBlockVariant\n  filename?: string\n  diff?: CodeDiffRow[]\n  labels?: Partial<CodeBlockLabels>\n  onCopy?: (code: string) => void\n  className?: string\n}\n\nfunction inferredDiff(code: string): CodeDiffRow[] {\n  let oldLine = 1\n  let newLine = 1\n  return code.split(\"\\n\").map((line) => {\n    if (line.startsWith(\"+\") && !line.startsWith(\"+++\"))\n      return {\n        oldLine: null,\n        newLine: newLine++,\n        type: \"add\" as const,\n        pieces: [{ text: line.slice(1), change: \"add\" as const }],\n      }\n    if (line.startsWith(\"-\") && !line.startsWith(\"---\"))\n      return {\n        oldLine: oldLine++,\n        newLine: null,\n        type: \"remove\" as const,\n        pieces: [{ text: line.slice(1), change: \"del\" as const }],\n      }\n    const text = line.startsWith(\" \") ? line.slice(1) : line\n    return {\n      oldLine: oldLine++,\n      newLine: newLine++,\n      type: \"context\" as const,\n      pieces: [{ text }],\n    }\n  })\n}\n\nfunction Pieces({ pieces }: { pieces: CodePiece[] }) {\n  return (\n    <>\n      {pieces.map((piece, index) => (\n        <span\n          key={index}\n          className={cx(\n            piece.change === \"add\" && \"rounded-sm bg-green-500/15\",\n            piece.change === \"del\" && \"rounded-sm bg-red-500/15\"\n          )}\n        >\n          {piece.text}\n        </span>\n      ))}\n    </>\n  )\n}\n\nexport function CodeBlock({\n  code,\n  language = \"text\",\n  variant = \"code\",\n  filename,\n  diff,\n  labels,\n  onCopy,\n  className,\n}: CodeBlockProps) {\n  const [copied, setCopied] = React.useState(false)\n  const text = { copy: \"Copy\", copied: \"Copied\", ...labels }\n  const rows = React.useMemo(() => diff ?? inferredDiff(code), [code, diff])\n  const additions = rows.filter((row) => row.type === \"add\").length\n  const removals = rows.filter((row) => row.type === \"remove\").length\n  const copy = async () => {\n    await navigator.clipboard.writeText(code)\n    setCopied(true)\n    onCopy?.(code)\n    window.setTimeout(() => setCopied(false), 1500)\n  }\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border text-text-secondary flex h-11 items-center gap-3 border-b px-4 text-xs\">\n        <span className=\"text-text-primary min-w-0 truncate font-mono\">\n          {filename ?? language}\n        </span>\n        {variant === \"diff\" ? (\n          <span className=\"ml-auto flex gap-2 font-mono tabular-nums\">\n            <span className=\"text-green-700 dark:text-green-400\">\n              +{additions}\n            </span>\n            <span className=\"text-red-700 dark:text-red-400\">-{removals}</span>\n          </span>\n        ) : (\n          <Button\n            className=\"ml-auto\"\n            variant=\"ghost\"\n            size=\"xs\"\n            leadingIcon={copied ? Check : Copy}\n            onClick={copy}\n          >\n            {copied ? text.copied : text.copy}\n          </Button>\n        )}\n      </header>\n      <div className=\"max-h-96 overflow-auto py-3 font-mono text-[13px] leading-5\">\n        {variant === \"diff\"\n          ? rows.map((row, index) => (\n              <div\n                key={index}\n                data-change={row.type}\n                data-old-line={row.oldLine ?? undefined}\n                data-new-line={row.newLine ?? undefined}\n                className={cx(\n                  \"grid grid-cols-[2rem_2rem_1.25rem_minmax(0,1fr)] px-2\",\n                  row.type === \"add\" && \"bg-green-500/10\",\n                  row.type === \"remove\" && \"bg-red-500/10\"\n                )}\n              >\n                <span className=\"text-text-tertiary text-right text-xs tabular-nums select-none\">\n                  {row.oldLine ?? \"\"}\n                </span>\n                <span className=\"text-text-tertiary text-right text-xs tabular-nums select-none\">\n                  {row.newLine ?? \"\"}\n                </span>\n                <span\n                  className={cx(\n                    \"text-center select-none\",\n                    row.type === \"add\" && \"text-green-700 dark:text-green-400\",\n                    row.type === \"remove\" && \"text-red-700 dark:text-red-400\"\n                  )}\n                >\n                  {row.type === \"add\" ? \"+\" : row.type === \"remove\" ? \"-\" : \"\"}\n                </span>\n                <code className=\"min-w-0 pl-1 break-words whitespace-pre-wrap\">\n                  <Pieces pieces={row.pieces} />\n                </code>\n              </div>\n            ))\n          : code.split(\"\\n\").map((line, index) => (\n              <div\n                key={index}\n                className=\"grid grid-cols-[2.5rem_minmax(0,1fr)] px-2\"\n              >\n                <span className=\"border-separator-border text-text-tertiary border-r pr-2 text-right text-xs tabular-nums select-none\">\n                  {index + 1}\n                </span>\n                <code className=\"min-w-0 pl-3 break-words whitespace-pre-wrap\">\n                  {line || \" \"}\n                </code>\n              </div>\n            ))}\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/prompt-kit/prompt-input.tsx",
          "target": "@components/prompt-kit/prompt-input.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Textarea } from \"@/components/ui/textarea\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport React, {\n  createContext,\n  useContext,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\"\n\ntype PromptInputContextType = {\n  isLoading: boolean\n  value: string\n  setValue: (value: string) => void\n  maxHeight: number | string\n  onSubmit?: () => void\n  disabled?: boolean\n  textareaRef: React.RefObject<HTMLTextAreaElement | null>\n}\n\nconst PromptInputContext = createContext<PromptInputContextType>({\n  isLoading: false,\n  value: \"\",\n  setValue: () => {},\n  maxHeight: 240,\n  onSubmit: undefined,\n  disabled: false,\n  textareaRef: React.createRef<HTMLTextAreaElement>(),\n})\n\nfunction usePromptInput() {\n  return useContext(PromptInputContext)\n}\n\nexport type PromptInputProps = {\n  isLoading?: boolean\n  value?: string\n  onValueChange?: (value: string) => void\n  maxHeight?: number | string\n  onSubmit?: () => void\n  children: React.ReactNode\n  className?: string\n  disabled?: boolean\n} & React.ComponentProps<\"div\">\n\nfunction PromptInput({\n  className,\n  isLoading = false,\n  maxHeight = 240,\n  value,\n  onValueChange,\n  onSubmit,\n  children,\n  disabled = false,\n  onClick,\n  ...props\n}: PromptInputProps) {\n  const [internalValue, setInternalValue] = useState(value || \"\")\n  const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n  const handleChange = (newValue: string) => {\n    setInternalValue(newValue)\n    onValueChange?.(newValue)\n  }\n\n  const handleClick: React.MouseEventHandler<HTMLDivElement> = (event) => {\n    if (!disabled) textareaRef.current?.focus()\n    onClick?.(event)\n  }\n\n  return (\n    <TooltipProvider>\n      <PromptInputContext.Provider\n        value={{\n          isLoading,\n          value: value ?? internalValue,\n          setValue: onValueChange ?? handleChange,\n          maxHeight,\n          onSubmit,\n          disabled,\n          textareaRef,\n        }}\n      >\n        <div\n          onClick={handleClick}\n          className={cn(\n            \"border-input bg-background cursor-text rounded-3xl border p-2 shadow-xs\",\n            disabled && \"cursor-not-allowed opacity-60\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </div>\n      </PromptInputContext.Provider>\n    </TooltipProvider>\n  )\n}\n\nexport type PromptInputTextareaProps = {\n  disableAutosize?: boolean\n} & React.ComponentProps<typeof Textarea>\n\nfunction PromptInputTextarea({\n  className,\n  onKeyDown,\n  disableAutosize = false,\n  ...props\n}: PromptInputTextareaProps) {\n  const { value, setValue, maxHeight, onSubmit, disabled, textareaRef } =\n    usePromptInput()\n\n  const adjustHeight = (element: HTMLTextAreaElement | null) => {\n    if (!element || disableAutosize) return\n    element.style.height = \"auto\"\n    element.style.height =\n      typeof maxHeight === \"number\"\n        ? `${Math.min(element.scrollHeight, maxHeight)}px`\n        : `min(${element.scrollHeight}px, ${maxHeight})`\n  }\n\n  const handleRef = (element: HTMLTextAreaElement | null) => {\n    textareaRef.current = element\n    adjustHeight(element)\n  }\n\n  useLayoutEffect(() => {\n    adjustHeight(textareaRef.current)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [value, maxHeight, disableAutosize])\n\n  const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n    adjustHeight(event.target)\n    setValue(event.target.value)\n  }\n\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n      e.preventDefault()\n      onSubmit?.()\n    }\n    onKeyDown?.(e)\n  }\n\n  return (\n    <Textarea\n      ref={handleRef}\n      value={value}\n      onChange={handleChange}\n      onKeyDown={handleKeyDown}\n      className={cn(\n        \"text-primary min-h-[44px] w-full resize-none border-none bg-transparent shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0\",\n        className\n      )}\n      rows={1}\n      disabled={disabled}\n      {...props}\n    />\n  )\n}\n\nexport type PromptInputActionsProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction PromptInputActions({\n  children,\n  className,\n  ...props\n}: PromptInputActionsProps) {\n  return (\n    <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n      {children}\n    </div>\n  )\n}\n\nexport type PromptInputActionProps = {\n  className?: string\n  tooltip: React.ReactNode\n  children: React.ReactNode\n  side?: \"top\" | \"bottom\" | \"left\" | \"right\"\n} & React.ComponentProps<typeof Tooltip>\n\nfunction PromptInputAction({\n  tooltip,\n  children,\n  className,\n  side = \"top\",\n  ...props\n}: PromptInputActionProps) {\n  const { disabled } = usePromptInput()\n\n  return (\n    <Tooltip {...props}>\n      <TooltipTrigger\n        asChild\n        disabled={disabled}\n        onClick={(event) => event.stopPropagation()}\n      >\n        {children}\n      </TooltipTrigger>\n      <TooltipContent side={side} className={className}>\n        {tooltip}\n      </TooltipContent>\n    </Tooltip>\n  )\n}\n\nexport {\n  PromptInput,\n  PromptInputTextarea,\n  PromptInputActions,\n  PromptInputAction,\n}\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "components/ui/tooltip.tsx",
          "target": "@components/ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 4,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-gray-900 text-gray-50 dark:bg-gray-50 dark:text-gray-900 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-w-sm rounded-md px-3 py-1.5 text-xs\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"fill-gray-900 dark:fill-gray-50 z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/examples/coding-workflow.ts",
          "target": "@components/examples/coding-workflow.ts",
          "type": "registry:component",
          "content": "export type PatchDecision = \"pending\" | \"accepted\" | \"rejected\"\n\nexport const codingFiles = [\n  {\n    path: \"src/routes/visits.ts\",\n    name: \"visits.ts\",\n    task: \"Validate the visit limit\",\n    test: \"clamps the limit to an integer between 1 and 100\",\n    before:\n      \"export function visitLimit(value: string) {\\n  return Number(value)\\n}\\n\",\n    after:\n      \"export function visitLimit(value: string) {\\n  const parsed = Math.trunc(Number(value)) || 20\\n  return Math.max(1, Math.min(parsed, 100))\\n}\\n\",\n  },\n  {\n    path: \"src/components/visit-card.tsx\",\n    name: \"visit-card.tsx\",\n    task: \"Improve the empty state\",\n    test: \"announces the empty state to assistive technology\",\n    before: \"export function EmptyVisits() {\\n  return <p>No visits</p>\\n}\\n\",\n    after:\n      'export function EmptyVisits() {\\n  return <p role=\"status\">No field visits scheduled.</p>\\n}\\n',\n  },\n] as const\n\nexport function workingCode(index: number, decisions: PatchDecision[]) {\n  const file = codingFiles[index]\n  return decisions[index] === \"accepted\" ? file.after : file.before\n}\n\n// Local fixture checks inspect accepted snapshots, without executing code.\nexport function checkWorkingFiles(decisions: PatchDecision[]) {\n  return codingFiles.map((file, index) => ({\n    name: file.test,\n    passed: workingCode(index, decisions) === file.after,\n    path: file.path,\n  }))\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "App examples"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "voice-agent-session",
      "type": "registry:block",
      "title": "Voice Agent Session",
      "description": "Controlled voice session combining LiveKit media controls and transcript with the ElevenLabs Orb.",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "radix-ui@1.6.7",
        "streamdown@2.4.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "three@0.149.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/session.tsx",
          "target": "@components/voice-agents/session.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport type { AgentState, ReceivedMessage } from \"@livekit/components-react\"\nimport { MessageSquare, PhoneOff, Volume2, VolumeX } from \"lucide-react\"\nimport { useState } from \"react\"\nimport { Orb } from \"./elevenlabs/orb\"\nimport { AgentChatTranscript } from \"./livekit/agent-chat-transcript\"\nimport { AgentTrackToggle } from \"./livekit/agent-track-toggle\"\nimport { voiceOrbState, type VoiceSessionState } from \"./state\"\n\nexport { voiceOrbState, type VoiceSessionState } from \"./state\"\n\nexport interface VoiceAgentSessionProps {\n  name?: string\n  state: VoiceSessionState\n  messages?: ReceivedMessage[]\n  microphoneEnabled: boolean\n  speakerEnabled: boolean\n  inputLevel?: number\n  outputLevel?: number\n  onMicrophoneChange: (enabled: boolean) => void\n  onSpeakerChange: (enabled: boolean) => void\n  onDisconnect: () => void\n  onConnect?: () => void\n  showTranscript?: boolean\n  onTranscriptChange?: (visible: boolean) => void\n  statusText?: string\n  className?: string\n}\n\n/** Controlled composition: the host owns connection, capture, playback, and agent execution. */\nexport function VoiceAgentSession({\n  name = \"Voice assistant\",\n  state,\n  messages = [],\n  microphoneEnabled,\n  speakerEnabled,\n  inputLevel = 0,\n  outputLevel = 0,\n  onMicrophoneChange,\n  onSpeakerChange,\n  onDisconnect,\n  onConnect,\n  showTranscript: controlledShowTranscript,\n  onTranscriptChange,\n  statusText,\n  className,\n}: VoiceAgentSessionProps) {\n  const [uncontrolledShowTranscript, setUncontrolledShowTranscript] =\n    useState(true)\n  const showTranscript = controlledShowTranscript ?? uncontrolledShowTranscript\n  const setShowTranscript = (visible: boolean) => {\n    if (controlledShowTranscript === undefined) {\n      setUncontrolledShowTranscript(visible)\n    }\n    onTranscriptChange?.(visible)\n  }\n  const connected = ![\"idle\", \"disconnected\", \"failed\"].includes(state)\n  const labels: Record<VoiceSessionState, string> = {\n    idle: \"Ready when you are\",\n    connecting: \"Connecting\",\n    listening: \"Listening\",\n    thinking: \"Thinking\",\n    speaking: \"Speaking\",\n    disconnected: \"Session ended\",\n    failed: \"Connection interrupted\",\n  }\n  return (\n    <section\n      className={cn(\n        \"border-border bg-background w-full overflow-hidden rounded-[14px] border\",\n        className\n      )}\n      aria-label={`${name} session`}\n    >\n      <header className=\"border-border flex items-center justify-between gap-3 border-b px-4 py-3\">\n        <span className=\"text-sm font-medium\">{name}</span>\n        <span className=\"text-muted-foreground text-xs\" aria-live=\"polite\">\n          {labels[state]}\n        </span>\n      </header>\n      <div\n        className={cn(\n          \"grid\",\n          showTranscript && \"min-[700px]:grid-cols-[1fr_1fr]\"\n        )}\n      >\n        <div className=\"flex min-h-80 flex-col items-center justify-center gap-4 p-5\">\n          <div className=\"size-40\" aria-hidden=\"true\">\n            <Orb\n              agentState={voiceOrbState(state)}\n              volumeMode=\"manual\"\n              manualInput={microphoneEnabled ? inputLevel : 0}\n              manualOutput={speakerEnabled ? outputLevel : 0}\n              seed={13}\n            />\n          </div>\n          <p className=\"text-muted-foreground text-center text-[13px]\">\n            {statusText ?? labels[state]}\n          </p>\n          {!connected && onConnect && (\n            <Button\n              type=\"button\"\n              size=\"sm\"\n              onClick={onConnect}\n              className=\"rounded-lg\"\n            >\n              {state === \"failed\" ? \"Reconnect\" : \"Start session\"}\n            </Button>\n          )}\n          <div\n            className=\"flex items-center justify-center gap-2\"\n            role=\"group\"\n            aria-label=\"Voice session controls\"\n          >\n            <AgentTrackToggle\n              source=\"microphone\"\n              size=\"default\"\n              pressed={microphoneEnabled}\n              onPressedChange={onMicrophoneChange}\n              disabled={!connected}\n              className=\"rounded-lg\"\n            />\n            <Button\n              type=\"button\"\n              variant=\"outline\"\n              size=\"icon\"\n              aria-label={speakerEnabled ? \"Mute speaker\" : \"Unmute speaker\"}\n              aria-pressed={speakerEnabled}\n              onClick={() => onSpeakerChange(!speakerEnabled)}\n              disabled={!connected}\n              className=\"rounded-lg\"\n            >\n              {speakerEnabled ? <Volume2 /> : <VolumeX />}\n            </Button>\n            <Button\n              type=\"button\"\n              variant=\"outline\"\n              size=\"icon\"\n              aria-label=\"Show transcript\"\n              aria-pressed={showTranscript}\n              onClick={() => setShowTranscript(!showTranscript)}\n              className=\"rounded-lg\"\n            >\n              <MessageSquare />\n            </Button>\n            <Button\n              type=\"button\"\n              variant=\"destructive\"\n              size=\"icon\"\n              aria-label=\"End session\"\n              onClick={onDisconnect}\n              disabled={!connected}\n              className=\"rounded-lg\"\n            >\n              <PhoneOff />\n            </Button>\n          </div>\n        </div>\n        {showTranscript && (\n          <div className=\"border-border min-w-0 border-t min-[700px]:border-t-0 min-[700px]:border-l\">\n            <p className=\"text-muted-foreground border-border border-b px-4 py-3 text-xs\">\n              Transcript\n            </p>\n            <AgentChatTranscript\n              messages={messages}\n              agentState={state as AgentState}\n              className=\"h-64 p-4\"\n            />\n          </div>\n        )}\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/orb.tsx",
          "target": "@components/voice-agents/elevenlabs/orb.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useEffect, useRef, useState, type RefObject } from \"react\"\nimport * as THREE from \"three\"\n\nexport type AgentState = null | \"thinking\" | \"listening\" | \"talking\"\n\nexport type OrbProps = {\n  colors?: [string, string]\n  colorsRef?: RefObject<[string, string]>\n  resizeDebounce?: number\n  seed?: number\n  agentState?: AgentState\n  volumeMode?: \"auto\" | \"manual\"\n  manualInput?: number\n  manualOutput?: number\n  inputVolumeRef?: RefObject<number>\n  outputVolumeRef?: RefObject<number>\n  getInputVolume?: () => number\n  getOutputVolume?: () => number\n  className?: string\n}\n\nexport function Orb({\n  colors = [\"#CADCFC\", \"#A0B9D1\"],\n  colorsRef,\n  resizeDebounce = 100,\n  seed,\n  agentState = null,\n  volumeMode = \"auto\",\n  manualInput,\n  manualOutput,\n  inputVolumeRef,\n  outputVolumeRef,\n  getInputVolume,\n  getOutputVolume,\n  className,\n}: OrbProps) {\n  const hostRef = useRef<HTMLDivElement>(null)\n  const liveRef = useRef({\n    colors,\n    colorsRef,\n    agentState,\n    volumeMode,\n    manualInput,\n    manualOutput,\n    inputVolumeRef,\n    outputVolumeRef,\n    getInputVolume,\n    getOutputVolume,\n  })\n  const [failed, setFailed] = useState(false)\n\n  liveRef.current = {\n    colors,\n    colorsRef,\n    agentState,\n    volumeMode,\n    manualInput,\n    manualOutput,\n    inputVolumeRef,\n    outputVolumeRef,\n    getInputVolume,\n    getOutputVolume,\n  }\n\n  useEffect(() => {\n    const host = hostRef.current\n    if (!host) return\n\n    let renderer: THREE.WebGLRenderer\n    try {\n      renderer = new THREE.WebGLRenderer({\n        alpha: true,\n        antialias: true,\n        premultipliedAlpha: true,\n      })\n      renderer.outputEncoding = THREE.sRGBEncoding\n      renderer.toneMapping = THREE.ACESFilmicToneMapping\n    } catch {\n      setFailed(true)\n      return\n    }\n\n    const scene = new THREE.Scene()\n    const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 100)\n    camera.position.z = 5\n\n    const random = splitmix32(seed ?? Math.floor(Math.random() * 2 ** 32))\n    const initialColors = liveRef.current.colors\n    const offsets = new Float32Array(\n      Array.from({ length: 7 }, () => random() * Math.PI * 2)\n    )\n    const perlinNoiseTexture = createFallbackNoiseTexture(random)\n    perlinNoiseTexture.wrapS = THREE.RepeatWrapping\n    perlinNoiseTexture.wrapT = THREE.RepeatWrapping\n    let disposed = false\n\n    new THREE.TextureLoader().load(\n      \"https://storage.googleapis.com/eleven-public-cdn/images/perlin-noise.png\",\n      (texture) => {\n        if (disposed) {\n          texture.dispose()\n          return\n        }\n        texture.wrapS = THREE.RepeatWrapping\n        texture.wrapT = THREE.RepeatWrapping\n        material.uniforms.uPerlinTexture.value = texture\n      }\n    )\n\n    const isDark = () => document.documentElement.classList.contains(\"dark\")\n    const uniforms = {\n      uColor1: new THREE.Uniform(createManagedColor(initialColors[0])),\n      uColor2: new THREE.Uniform(createManagedColor(initialColors[1])),\n      uOffsets: { value: offsets },\n      uPerlinTexture: new THREE.Uniform(perlinNoiseTexture),\n      uTime: new THREE.Uniform(0),\n      uAnimation: new THREE.Uniform(0.1),\n      uInverted: new THREE.Uniform(isDark() ? 1 : 0),\n      uInputVolume: new THREE.Uniform(0),\n      uOutputVolume: new THREE.Uniform(0),\n      uOpacity: new THREE.Uniform(0),\n    }\n    const geometry = new THREE.CircleGeometry(3.5, 64)\n    const material = new THREE.ShaderMaterial({\n      uniforms,\n      fragmentShader,\n      vertexShader,\n      transparent: true,\n    })\n    const mesh = new THREE.Mesh(geometry, material)\n    scene.add(mesh)\n\n    renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2))\n    renderer.setClearColor(0x000000, 0)\n    renderer.domElement.setAttribute(\"aria-hidden\", \"true\")\n    renderer.domElement.style.width = \"100%\"\n    renderer.domElement.style.height = \"100%\"\n    renderer.domElement.style.display = \"block\"\n    host.appendChild(renderer.domElement)\n\n    let resizeTimer: ReturnType<typeof setTimeout> | undefined\n    const resize = () => {\n      clearTimeout(resizeTimer)\n      resizeTimer = setTimeout(() => {\n        const { width, height } = host.getBoundingClientRect()\n        if (!width || !height) return\n        renderer.setSize(width, height, false)\n        camera.aspect = width / height\n        camera.updateProjectionMatrix()\n      }, resizeDebounce)\n    }\n    const resizeObserver = new ResizeObserver(resize)\n    resizeObserver.observe(host)\n    resize()\n\n    const themeObserver = new MutationObserver(() => {\n      uniforms.uInverted.value = isDark() ? 1 : 0\n    })\n    themeObserver.observe(document.documentElement, {\n      attributes: true,\n      attributeFilter: [\"class\"],\n    })\n\n    let visible = true\n    const intersectionObserver = new IntersectionObserver(([entry]) => {\n      visible = entry?.isIntersecting ?? true\n    })\n    intersectionObserver.observe(host)\n\n    const reducedMotion = window.matchMedia(\n      \"(prefers-reduced-motion: reduce)\"\n    ).matches\n    const targetColor1 = createManagedColor(initialColors[0])\n    const targetColor2 = createManagedColor(initialColors[1])\n    let currentInput = 0\n    let currentOutput = 0\n    let animationSpeed = 0.1\n    let previous = performance.now()\n    let frameId = 0\n\n    const render = (now: number) => {\n      frameId = requestAnimationFrame(render)\n      if (!visible) {\n        previous = now\n        return\n      }\n\n      const delta = Math.min((now - previous) / 1000, 0.1)\n      previous = now\n      const live = liveRef.current\n      const liveColors = live.colorsRef?.current ?? live.colors\n      if (liveColors[0]) setManagedColor(targetColor1, liveColors[0])\n      if (liveColors[1]) setManagedColor(targetColor2, liveColors[1])\n\n      uniforms.uTime.value += reducedMotion ? 0 : delta * 0.5\n      uniforms.uOpacity.value = Math.min(1, uniforms.uOpacity.value + delta * 2)\n\n      let targetInput = 0\n      let targetOutput = 0.3\n      if (live.volumeMode === \"manual\") {\n        targetInput = clamp01(\n          live.manualInput ??\n            live.inputVolumeRef?.current ??\n            live.getInputVolume?.() ??\n            0\n        )\n        targetOutput = clamp01(\n          live.manualOutput ??\n            live.outputVolumeRef?.current ??\n            live.getOutputVolume?.() ??\n            0\n        )\n      } else if (!reducedMotion) {\n        const time = uniforms.uTime.value * 2\n        if (live.agentState === \"listening\") {\n          targetInput = clamp01(0.55 + Math.sin(time * 3.2) * 0.35)\n          targetOutput = 0.45\n        } else if (live.agentState === \"talking\") {\n          targetInput = clamp01(0.65 + Math.sin(time * 4.8) * 0.22)\n          targetOutput = clamp01(0.75 + Math.sin(time * 3.6) * 0.22)\n        } else if (live.agentState === \"thinking\") {\n          const base = 0.38 + 0.07 * Math.sin(time * 0.7)\n          const wander =\n            0.05 * Math.sin(time * 2.1) * Math.sin(time * 0.37 + 1.2)\n          targetInput = clamp01(base + wander)\n          targetOutput = clamp01(0.48 + 0.12 * Math.sin(time * 1.05 + 0.6))\n        }\n      }\n\n      currentInput += (targetInput - currentInput) * 0.2\n      currentOutput += (targetOutput - currentOutput) * 0.2\n      const targetSpeed = 0.1 + (1 - Math.pow(currentOutput - 1, 2)) * 0.9\n      animationSpeed += (targetSpeed - animationSpeed) * 0.12\n\n      uniforms.uAnimation.value += reducedMotion ? 0 : delta * animationSpeed\n      uniforms.uInputVolume.value = currentInput\n      uniforms.uOutputVolume.value = currentOutput\n      uniforms.uColor1.value.lerp(targetColor1, 0.08)\n      uniforms.uColor2.value.lerp(targetColor2, 0.08)\n      renderer.render(scene, camera)\n    }\n    frameId = requestAnimationFrame(render)\n\n    const onContextLost = (event: Event) => {\n      event.preventDefault()\n      setFailed(true)\n    }\n    renderer.domElement.addEventListener(\"webglcontextlost\", onContextLost)\n\n    return () => {\n      disposed = true\n      cancelAnimationFrame(frameId)\n      clearTimeout(resizeTimer)\n      resizeObserver.disconnect()\n      intersectionObserver.disconnect()\n      themeObserver.disconnect()\n      renderer.domElement.removeEventListener(\"webglcontextlost\", onContextLost)\n      geometry.dispose()\n      material.dispose()\n      const loadedTexture = material.uniforms.uPerlinTexture\n        .value as THREE.Texture\n      loadedTexture.dispose()\n      if (loadedTexture !== perlinNoiseTexture) perlinNoiseTexture.dispose()\n      renderer.dispose()\n      renderer.domElement.remove()\n    }\n  }, [resizeDebounce, seed])\n\n  return (\n    <div\n      ref={hostRef}\n      className={className ?? \"relative h-full w-full\"}\n      data-orb-renderer={failed ? \"fallback\" : \"webgl\"}\n    >\n      {failed ? (\n        <div\n          aria-hidden\n          className=\"h-full w-full rounded-full bg-[radial-gradient(circle_at_35%_30%,var(--background),#cadcfc_38%,#a0b9d1_72%,transparent_73%)]\"\n        />\n      ) : null}\n    </div>\n  )\n}\n\nfunction splitmix32(a: number) {\n  return function () {\n    a |= 0\n    a = (a + 0x9e3779b9) | 0\n    let t = a ^ (a >>> 16)\n    t = Math.imul(t, 0x21f0aaad)\n    t = t ^ (t >>> 15)\n    t = Math.imul(t, 0x735a2d97)\n    return ((t = t ^ (t >>> 15)) >>> 0) / 4294967296\n  }\n}\n\nfunction clamp01(n: number) {\n  if (!Number.isFinite(n)) return 0\n  return Math.min(1, Math.max(0, n))\n}\n\nfunction createManagedColor(value: string) {\n  return setManagedColor(new THREE.Color(), value)\n}\n\nfunction setManagedColor(color: THREE.Color, value: string) {\n  color.set(value)\n  if (THREE.ColorManagement.legacyMode) color.convertSRGBToLinear()\n  return color\n}\n\nfunction createFallbackNoiseTexture(random: () => number) {\n  const size = 32\n  const pixels = new Uint8Array(size * size * 4)\n  const phases = Array.from({ length: 6 }, () => random() * Math.PI * 2)\n  for (let y = 0; y < size; y++) {\n    for (let x = 0; x < size; x++) {\n      const px = (x / size) * Math.PI * 2\n      const py = (y / size) * Math.PI * 2\n      const noise =\n        0.5 +\n        0.2 * Math.sin(px + phases[0]) * Math.cos(py + phases[1]) +\n        0.12 * Math.sin(px * 2 + py + phases[2]) +\n        0.08 * Math.cos(px - py * 3 + phases[3]) +\n        0.05 * Math.sin(px * 4 + phases[4]) * Math.cos(py * 4 + phases[5])\n      const value = Math.round(clamp01(noise) * 255)\n      const offset = (y * size + x) * 4\n      pixels[offset] = value\n      pixels[offset + 1] = value\n      pixels[offset + 2] = value\n      pixels[offset + 3] = 255\n    }\n  }\n  const texture = new THREE.DataTexture(\n    pixels,\n    size,\n    size,\n    THREE.RGBAFormat,\n    THREE.UnsignedByteType\n  )\n  texture.minFilter = THREE.LinearFilter\n  texture.magFilter = THREE.LinearFilter\n  texture.needsUpdate = true\n  return texture\n}\nconst vertexShader = /* glsl */ `\nuniform float uTime;\nuniform sampler2D uPerlinTexture;\nvarying vec2 vUv;\n\nvoid main() {\n  vUv = uv;\n  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`\n\nconst fragmentShader = /* glsl */ `\nuniform float uTime;\nuniform float uAnimation;\nuniform float uInverted;\nuniform float uOffsets[7];\nuniform vec3 uColor1;\nuniform vec3 uColor2;\nuniform float uInputVolume;\nuniform float uOutputVolume;\nuniform float uOpacity;\nuniform sampler2D uPerlinTexture;\nvarying vec2 vUv;\n\nconst float PI = 3.14159265358979323846;\n\n// Draw a single oval with soft edges and calculate its gradient color\nbool drawOval(vec2 polarUv, vec2 polarCenter, float a, float b, bool reverseGradient, float softness, out vec4 color) {\n    vec2 p = polarUv - polarCenter;\n    float oval = (p.x * p.x) / (a * a) + (p.y * p.y) / (b * b);\n\n    float edge = smoothstep(1.0, 1.0 - softness, oval);\n\n    if (edge > 0.0) {\n        float gradient = reverseGradient ? (1.0 - (p.x / a + 1.0) / 2.0) : ((p.x / a + 1.0) / 2.0);\n        // Flatten gradient toward middle value for more uniform appearance\n        gradient = mix(0.5, gradient, 0.1);\n        color = vec4(vec3(gradient), 0.85 * edge);\n        return true;\n    }\n    return false;\n}\n\n// Map grayscale value to a 4-color ramp (color1, color2, color3, color4)\nvec3 colorRamp(float grayscale, vec3 color1, vec3 color2, vec3 color3, vec3 color4) {\n    if (grayscale < 0.33) {\n        return mix(color1, color2, grayscale * 3.0);\n    } else if (grayscale < 0.66) {\n        return mix(color2, color3, (grayscale - 0.33) * 3.0);\n    } else {\n        return mix(color3, color4, (grayscale - 0.66) * 3.0);\n    }\n}\n\nvec2 hash2(vec2 p) {\n    return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);\n}\n\n// 2D noise for the ring\nfloat noise2D(vec2 p) {\n    vec2 i = floor(p);\n    vec2 f = fract(p);\n    \n    vec2 u = f * f * (3.0 - 2.0 * f);\n    float n = mix(\n        mix(dot(hash2(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),\n            dot(hash2(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)), u.x),\n        mix(dot(hash2(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),\n            dot(hash2(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)), u.x),\n        u.y\n    );\n\n    return 0.5 + 0.5 * n;\n}\n\nfloat sharpRing(vec3 decomposed, float time) {\n    float ringStart = 1.0;\n    float ringWidth = 0.3;\n    float noiseScale = 5.0;\n\n    float noise = mix(\n        noise2D(vec2(decomposed.x, time) * noiseScale),\n        noise2D(vec2(decomposed.y, time) * noiseScale),\n        decomposed.z\n    );\n\n    noise = (noise - 0.5) * 2.5;\n\n    return ringStart + noise * ringWidth * 1.5;\n}\n\nfloat smoothRing(vec3 decomposed, float time) {\n    float ringStart = 0.9;\n    float ringWidth = 0.2;\n    float noiseScale = 6.0;\n\n    float noise = mix(\n        noise2D(vec2(decomposed.x, time) * noiseScale),\n        noise2D(vec2(decomposed.y, time) * noiseScale),\n        decomposed.z\n    );\n\n    noise = (noise - 0.5) * 5.0;\n\n    return ringStart + noise * ringWidth;\n}\n\nfloat flow(vec3 decomposed, float time) {\n    return mix(\n        texture(uPerlinTexture, vec2(time, decomposed.x / 2.0)).r,\n        texture(uPerlinTexture, vec2(time, decomposed.y / 2.0)).r,\n        decomposed.z\n    );\n}\n\nvoid main() {\n    // Normalize vUv to be centered around (0.0, 0.0)\n    vec2 uv = vUv * 2.0 - 1.0;\n\n    // Convert uv to polar coordinates\n    float radius = length(uv);\n    float theta = atan(uv.y, uv.x);\n    if (theta < 0.0) theta += 2.0 * PI; // Normalize theta to [0, 2*PI]\n\n    // Decomposed angle is used for sampling noise textures without seams:\n    // float noise = mix(sample(decomposed.x), sample(decomposed.y), decomposed.z);\n    vec3 decomposed = vec3(\n        // angle in the range [0, 1]\n        theta / (2.0 * PI),\n        // angle offset by 180 degrees in the range [1, 2]\n        mod(theta / (2.0 * PI) + 0.5, 1.0) + 1.0,\n        // mixing factor between two noises\n        abs(theta / PI - 1.0)\n    );\n\n    // Add noise to the angle for a flow-like distortion (reduced for flatter look)\n    float noise = flow(decomposed, radius * 0.03 - uAnimation * 0.2) - 0.5;\n    theta += noise * mix(0.08, 0.25, uOutputVolume);\n\n    // Initialize the base color to white\n    vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\n\n    // Original parameters for the ovals in polar coordinates\n    float originalCenters[7] = float[7](0.0, 0.5 * PI, 1.0 * PI, 1.5 * PI, 2.0 * PI, 2.5 * PI, 3.0 * PI);\n\n    // Parameters for the animated centers in polar coordinates\n    float centers[7];\n    for (int i = 0; i < 7; i++) {\n        centers[i] = originalCenters[i] + 0.5 * sin(uTime / 20.0 + uOffsets[i]);\n    }\n\n    float a, b;\n    vec4 ovalColor;\n\n    // Check if the pixel is inside any of the ovals\n    for (int i = 0; i < 7; i++) {\n        float noise = texture(uPerlinTexture, vec2(mod(centers[i] + uTime * 0.05, 1.0), 0.5)).r;\n        a = 0.5 + noise * 0.3; // Increased for more coverage\n        b = noise * mix(3.5, 2.5, uInputVolume); // Increased height for fuller appearance\n        bool reverseGradient = (i % 2 == 1); // Reverse gradient for every second oval\n\n        // Calculate the distance in polar coordinates\n        float distTheta = min(\n            abs(theta - centers[i]),\n            min(\n                abs(theta + 2.0 * PI - centers[i]),\n                abs(theta - 2.0 * PI - centers[i])\n            )\n        );\n        float distRadius = radius;\n\n        float softness = 0.6; // Increased softness for flatter, less pronounced edges\n\n        // Check if the pixel is inside the oval in polar coordinates\n        if (drawOval(vec2(distTheta, distRadius), vec2(0.0, 0.0), a, b, reverseGradient, softness, ovalColor)) {\n            // Blend the oval color with the existing color\n            color.rgb = mix(color.rgb, ovalColor.rgb, ovalColor.a);\n            color.a = max(color.a, ovalColor.a); // Max alpha\n        }\n    }\n    \n    // Calculate both noisy rings\n    float ringRadius1 = sharpRing(decomposed, uTime * 0.1);\n    float ringRadius2 = smoothRing(decomposed, uTime * 0.1);\n    \n    // Adjust rings based on input volume (reduced for flatter appearance)\n    float inputRadius1 = radius + uInputVolume * 0.2;\n    float inputRadius2 = radius + uInputVolume * 0.15;\n    float opacity1 = mix(0.2, 0.6, uInputVolume);\n    float opacity2 = mix(0.15, 0.45, uInputVolume);\n\n    // Blend both rings\n    float ringAlpha1 = (inputRadius2 >= ringRadius1) ? opacity1 : 0.0;\n    float ringAlpha2 = smoothstep(ringRadius2 - 0.05, ringRadius2 + 0.05, inputRadius1) * opacity2;\n    \n    float totalRingAlpha = max(ringAlpha1, ringAlpha2);\n    \n    // Apply screen blend mode for combined rings\n    vec3 ringColor = vec3(1.0); // White ring color\n    color.rgb = 1.0 - (1.0 - color.rgb) * (1.0 - ringColor * totalRingAlpha);\n\n    // Define colours to ramp against greyscale (could increase the amount of colours in the ramp)\n    vec3 color1 = vec3(0.0, 0.0, 0.0); // Black\n    vec3 color2 = uColor1; // Darker Color\n    vec3 color3 = uColor2; // Lighter Color\n    vec3 color4 = vec3(1.0, 1.0, 1.0); // White\n\n    // Convert grayscale color to the color ramp\n    float luminance = mix(color.r, 1.0 - color.r, uInverted);\n    color.rgb = colorRamp(luminance, color1, color2, color3, color4); // Apply the color ramp\n\n    // Apply fade-in opacity\n    color.a *= uOpacity;\n\n    gl_FragColor = color;\n}\n`\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-chat-transcript.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-transcript.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Bubble,\n  BubbleContent,\n} from \"@/components/voice-agents/livekit/_ui/bubble\"\nimport {\n  Marker,\n  MarkerContent,\n  MarkerIcon,\n} from \"@/components/voice-agents/livekit/_ui/marker\"\nimport {\n  Message,\n  MessageContent,\n} from \"@/components/voice-agents/livekit/_ui/message\"\nimport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n} from \"@/components/voice-agents/livekit/_ui/message-scroller\"\nimport { AgentChatIndicator } from \"@/components/voice-agents/livekit/agent-chat-indicator\"\nimport {\n  type AgentState,\n  type ReceivedMessage,\n} from \"@livekit/components-react\"\nimport { type ComponentProps } from \"react\"\nimport { Streamdown } from \"streamdown\"\n\n/**\n * Props for the AgentChatTranscript component.\n */\nexport interface AgentChatTranscriptProps\n  extends ComponentProps<\"div\">,\n    ComponentProps<typeof MessageScrollerProvider>,\n    ComponentProps<typeof MessageScrollerViewport>,\n    ComponentProps<typeof MessageScrollerContent> {\n  /**\n   * Whether to automatically scroll to the bottom of the transcript when new messages are added.\n   * @defaultValue true\n   */\n  autoScroll?: boolean\n  /**\n   * The scroll anchor to use when auto-scrolling.\n   * @defaultValue false\n   */\n  scrollAnchor?: boolean | \"user\" | \"other\" | \"any\"\n  /**\n   * The scroll button render function\n   */\n  scrollButtonRender?: ComponentProps<typeof MessageScrollerButton>[\"render\"]\n  /**\n   * The scroll button behavior\n   */\n  scrollButtonBehavior?: ComponentProps<\n    typeof MessageScrollerButton\n  >[\"behavior\"]\n  /**\n   * The scroll button direction\n   */\n  scrollButtonDirection?: ComponentProps<\n    typeof MessageScrollerButton\n  >[\"direction\"]\n  /**\n   * The current state of the agent. When 'thinking', displays a loading indicator.\n   */\n  agentState?: AgentState\n  /**\n   * Array of messages to display in the transcript.\n   * @defaultValue []\n   */\n  messages?: ReceivedMessage[]\n  /**\n   * Additional CSS class names to apply to the conversation container.\n   */\n  className?: string\n}\n\n/**\n * A chat transcript component that displays a conversation between the user and agent.\n * Shows messages with timestamps and origin indicators, plus a thinking indicator\n * when the agent is processing.\n *\n * @extends ComponentProps<'div'>, ComponentProps<typeof MessageScrollerProvider>, ComponentProps<typeof MessageScrollerViewport>, ComponentProps<typeof MessageScrollerContent>\n *\n *\n * @example\n * ```tsx\n * <AgentChatTranscript\n *   agentState={agentState}\n *   messages={chatMessages}\n * />\n * ```\n */\nexport function AgentChatTranscript({\n  scrollAnchor,\n  autoScroll = true,\n  scrollMargin,\n  scrollEdgeThreshold,\n  preserveScrollOnPrepend,\n  scrollPreviousItemPeek,\n  defaultScrollPosition = \"last-anchor\",\n  scrollButtonRender,\n  scrollButtonBehavior,\n  scrollButtonDirection,\n  spacerClassName,\n  agentState,\n  messages = [],\n  className,\n  ...props\n}: AgentChatTranscriptProps) {\n  return (\n    <MessageScrollerProvider\n      autoScroll={autoScroll}\n      scrollMargin={scrollMargin}\n      defaultScrollPosition={defaultScrollPosition}\n      scrollEdgeThreshold={scrollEdgeThreshold}\n      scrollPreviousItemPeek={scrollPreviousItemPeek}\n    >\n      <MessageScroller className={className} {...props}>\n        <MessageScrollerViewport\n          preserveScrollOnPrepend={preserveScrollOnPrepend}\n        >\n          <MessageScrollerContent\n            spacerClassName={spacerClassName}\n            aria-busy={agentState === \"thinking\"}\n          >\n            {messages.map((receivedMessage) => {\n              const { id, timestamp, from, message } = receivedMessage\n              const time = new Date(timestamp)\n              const isUser = from?.isLocal\n              const locale =\n                typeof navigator !== \"undefined\" ? navigator.language : \"en-US\"\n              const title = time.toLocaleTimeString(locale, {\n                timeStyle: \"full\",\n              })\n              let _scrollAnchor = false\n\n              if (\n                scrollAnchor === \"any\" ||\n                (scrollAnchor === \"user\" && isUser) ||\n                (scrollAnchor === \"other\" && !isUser)\n              ) {\n                _scrollAnchor = true\n              }\n\n              return (\n                <MessageScrollerItem\n                  key={id}\n                  messageId={id}\n                  scrollAnchor={_scrollAnchor}\n                >\n                  <Message align={isUser ? \"end\" : \"start\"} title={title}>\n                    <MessageContent>\n                      <Bubble\n                        align={isUser ? \"end\" : \"start\"}\n                        variant={isUser ? \"secondary\" : \"ghost\"}\n                      >\n                        <BubbleContent>\n                          <Streamdown>{message}</Streamdown>\n                        </BubbleContent>\n                      </Bubble>\n                    </MessageContent>\n                  </Message>\n                </MessageScrollerItem>\n              )\n            })}\n\n            {/* Agent is thinking indicator */}\n            {agentState === \"thinking\" && (\n              <MessageScrollerItem>\n                <Marker role=\"status\">\n                  <MarkerIcon>\n                    <AgentChatIndicator size=\"sm\" />\n                  </MarkerIcon>\n                  <MarkerContent className=\"shimmer\">Thinking...</MarkerContent>\n                </Marker>\n              </MessageScrollerItem>\n            )}\n          </MessageScrollerContent>\n        </MessageScrollerViewport>\n\n        {/* Scroll to bottom button */}\n        <MessageScrollerButton\n          variant=\"outline\"\n          className=\"rounded-full\"\n          render={scrollButtonRender}\n          behavior={scrollButtonBehavior}\n          direction={scrollButtonDirection}\n        />\n      </MessageScroller>\n    </MessageScrollerProvider>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/bubble.tsx",
          "target": "@components/voice-agents/livekit/_ui/bubble.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction BubbleGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"bubble-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nconst bubbleVariants = cva(\n  \"group/bubble relative flex w-fit max-w-[80%] min-w-0 flex-col gap-1 group-data-[align=end]/message:self-end data-[align=end]:self-end data-[variant=ghost]:max-w-full\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80\",\n        secondary:\n          \"*:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]\",\n        muted:\n          \"*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]\",\n        tinted:\n          \"*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]\",\n        outline:\n          \"*:data-[slot=bubble-content]:border-border *:data-[slot=bubble-content]:bg-background [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30\",\n        ghost:\n          \"border-none *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50\",\n        destructive:\n          \"*:data-[slot=bubble-content]:bg-destructive/10 *:data-[slot=bubble-content]:text-destructive dark:*:data-[slot=bubble-content]:bg-destructive/20 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Bubble({\n  variant = \"default\",\n  align = \"start\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof bubbleVariants> & {\n    align?: \"start\" | \"end\"\n  }) {\n  return (\n    <div\n      data-slot=\"bubble\"\n      data-variant={variant}\n      data-align={align}\n      className={cn(bubbleVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BubbleContent({\n  asChild = false,\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  asChild?: boolean\n}) {\n  const Comp = asChild ? Slot.Root : \"div\"\n\n  return (\n    <Comp\n      data-slot=\"bubble-content\"\n      className={cn(\n        \"[button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-ring/50 w-fit max-w-full min-w-0 overflow-hidden rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed wrap-break-word group-data-[align=end]/bubble:self-end [button]:text-left [button,a]:transition-colors [button,a]:outline-none [button,a]:focus-visible:ring-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst bubbleReactionsVariants = cva(\n  \"absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm ring-3 ring-card has-[button]:p-0\",\n  {\n    variants: {\n      side: {\n        top: \"top-0 -translate-y-3/4\",\n        bottom: \"bottom-0 translate-y-3/4\",\n      },\n      align: {\n        start: \"left-3\",\n        end: \"right-3\",\n      },\n    },\n    defaultVariants: {\n      side: \"bottom\",\n      align: \"end\",\n    },\n  }\n)\n\nfunction BubbleReactions({\n  side = \"bottom\",\n  align = \"end\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  align?: \"start\" | \"end\"\n  side?: \"top\" | \"bottom\"\n}) {\n  return (\n    <div\n      data-slot=\"bubble-reactions\"\n      data-align={align}\n      data-side={side}\n      className={cn(bubbleReactionsVariants({ side, align }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { BubbleGroup, Bubble, BubbleContent, BubbleReactions }\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/marker.tsx",
          "target": "@components/voice-agents/livekit/_ui/marker.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst markerVariants = cva(\n  \"group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground\",\n  {\n    variants: {\n      variant: {\n        default: \"\",\n        separator:\n          \"before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border\",\n        border: \"border-b border-border pb-2\",\n      },\n    },\n  }\n)\n\nfunction Marker({\n  className,\n  variant = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof markerVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"div\"\n\n  return (\n    <Comp\n      data-slot=\"marker\"\n      data-variant={variant}\n      className={cn(markerVariants({ variant, className }))}\n      {...props}\n    />\n  )\n}\n\nfunction MarkerIcon({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"marker-icon\"\n      aria-hidden=\"true\"\n      className={cn(\n        \"size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MarkerContent({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"marker-content\"\n      className={cn(\n        \"*:[a]:hover:text-foreground min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Marker, MarkerIcon, MarkerContent, markerVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/message.tsx",
          "target": "@components/voice-agents/livekit/_ui/message.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction MessageGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction Message({\n  className,\n  align = \"start\",\n  ...props\n}: React.ComponentProps<\"div\"> & { align?: \"start\" | \"end\" }) {\n  return (\n    <div\n      data-slot=\"message\"\n      data-align={align}\n      className={cn(\n        \"group/message relative flex w-full min-w-0 gap-2 text-sm data-[align=end]:flex-row-reverse\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageAvatar({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-avatar\"\n      className={cn(\n        \"bg-muted flex w-fit min-w-8 shrink-0 items-center justify-center self-end overflow-hidden rounded-full group-has-data-[slot=message-footer]/message:-translate-y-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-content\"\n      className={cn(\n        \"flex w-full min-w-0 flex-col gap-2.5 wrap-break-word group-data-[align=end]/message:*:data-slot:self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-header\"\n      className={cn(\n        \"text-muted-foreground flex max-w-full min-w-0 items-center px-3 text-xs font-medium group-has-data-[variant=ghost]/message:px-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-footer\"\n      className={cn(\n        \"text-muted-foreground flex max-w-full min-w-0 items-center px-3 text-xs font-medium group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  MessageGroup,\n  Message,\n  MessageAvatar,\n  MessageContent,\n  MessageFooter,\n  MessageHeader,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/message-scroller.tsx",
          "target": "@components/voice-agents/livekit/_ui/message-scroller.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ArrowDownIcon } from \"lucide-react\"\nimport * as React from \"react\"\nimport { Button } from \"./button\"\n\ntype ScrollerContextValue = {\n  autoScroll: boolean\n  atEnd: boolean\n  atEndRef: React.RefObject<boolean>\n  atStart: boolean\n  defaultScrollPosition: \"first\" | \"last\" | \"last-anchor\"\n  scrollEdgeThreshold: number\n  scrollMargin: number\n  scrollPreviousItemPeek: number\n  setAtEnd: (atEnd: boolean) => void\n  setAtStart: (atStart: boolean) => void\n  viewportRef: React.RefObject<HTMLDivElement | null>\n}\n\nconst ScrollerContext = React.createContext<ScrollerContextValue | null>(null)\n\nexport interface MessageScrollerProviderProps {\n  children?: React.ReactNode\n  autoScroll?: boolean\n  scrollMargin?: number\n  defaultScrollPosition?: \"first\" | \"last\" | \"last-anchor\"\n  scrollEdgeThreshold?: number\n  scrollPreviousItemPeek?: number\n}\n\nfunction MessageScrollerProvider({\n  children,\n  autoScroll = true,\n  defaultScrollPosition = \"last-anchor\",\n  scrollEdgeThreshold = 8,\n  scrollMargin = 0,\n  scrollPreviousItemPeek = 0,\n}: MessageScrollerProviderProps) {\n  const viewportRef = React.useRef<HTMLDivElement>(null)\n  const atEndRef = React.useRef(true)\n  const [atEnd, setAtEnd] = React.useState(true)\n  const [atStart, setAtStart] = React.useState(true)\n  const updateAtEnd = React.useCallback((nextAtEnd: boolean) => {\n    atEndRef.current = nextAtEnd\n    setAtEnd(nextAtEnd)\n  }, [])\n  return (\n    <ScrollerContext.Provider\n      value={{\n        autoScroll,\n        atEnd,\n        atEndRef,\n        atStart,\n        defaultScrollPosition,\n        scrollEdgeThreshold,\n        scrollMargin,\n        scrollPreviousItemPeek,\n        setAtEnd: updateAtEnd,\n        setAtStart,\n        viewportRef,\n      }}\n    >\n      {children}\n    </ScrollerContext.Provider>\n  )\n}\n\nfunction useScroller() {\n  const context = React.useContext(ScrollerContext)\n  if (!context) {\n    throw new Error(\n      \"MessageScroller components require MessageScrollerProvider\"\n    )\n  }\n  return context\n}\n\nfunction MessageScroller({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-scroller\"\n      className={cn(\n        \"group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageScrollerViewport({\n  className,\n  preserveScrollOnPrepend = false,\n  onScroll,\n  style,\n  ...props\n}: React.ComponentProps<\"div\"> & { preserveScrollOnPrepend?: boolean }) {\n  const {\n    atEndRef,\n    autoScroll,\n    defaultScrollPosition,\n    scrollEdgeThreshold,\n    scrollMargin,\n    scrollPreviousItemPeek,\n    setAtEnd,\n    setAtStart,\n    viewportRef,\n  } = useScroller()\n\n  React.useLayoutEffect(() => {\n    const viewport = viewportRef.current\n    if (!viewport) return\n    const update = () => {\n      const atEnd =\n        viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <=\n        scrollEdgeThreshold\n      setAtEnd(atEnd)\n      setAtStart(viewport.scrollTop <= scrollEdgeThreshold)\n    }\n    if (defaultScrollPosition === \"last-anchor\") {\n      const anchors = viewport.querySelectorAll<HTMLElement>(\n        '[data-scroll-anchor=\"true\"]'\n      )\n      const anchor = anchors.item(anchors.length - 1)\n      if (anchor) anchor.scrollIntoView({ block: \"end\" })\n      else viewport.scrollTop = viewport.scrollHeight\n    } else if (defaultScrollPosition === \"last\") {\n      viewport.scrollTop = viewport.scrollHeight\n    }\n    let previousScrollHeight = viewport.scrollHeight\n    const observer = new MutationObserver((records) => {\n      const nextScrollHeight = viewport.scrollHeight\n      const prepended = records.some(\n        (record) =>\n          record.type === \"childList\" &&\n          record.addedNodes.length > 0 &&\n          (record.previousSibling === null ||\n            (record.previousSibling instanceof HTMLElement &&\n              record.previousSibling.dataset.slot ===\n                \"message-scroller-spacer\"))\n      )\n      if (preserveScrollOnPrepend && prepended) {\n        viewport.scrollTop += nextScrollHeight - previousScrollHeight\n      } else if (autoScroll && atEndRef.current) {\n        viewport.scrollTo({ top: nextScrollHeight })\n      }\n      previousScrollHeight = nextScrollHeight\n      update()\n    })\n    observer.observe(viewport, { childList: true, subtree: true })\n    update()\n    return () => observer.disconnect()\n  }, [\n    atEndRef,\n    autoScroll,\n    defaultScrollPosition,\n    preserveScrollOnPrepend,\n    scrollEdgeThreshold,\n    setAtEnd,\n    setAtStart,\n    viewportRef,\n  ])\n\n  return (\n    <div\n      ref={viewportRef}\n      data-slot=\"message-scroller-viewport\"\n      className={cn(\n        \"size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain\",\n        className\n      )}\n      style={{\n        scrollPaddingBlockStart: scrollPreviousItemPeek,\n        scrollPaddingBlockEnd: scrollMargin,\n        ...style,\n      }}\n      onScroll={(event) => {\n        const viewport = event.currentTarget\n        setAtEnd(\n          viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <=\n            scrollEdgeThreshold\n        )\n        setAtStart(viewport.scrollTop <= scrollEdgeThreshold)\n        onScroll?.(event)\n      }}\n      {...props}\n    />\n  )\n}\n\nfunction MessageScrollerContent({\n  className,\n  spacerClassName,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & { spacerClassName?: string }) {\n  return (\n    <div\n      data-slot=\"message-scroller-content\"\n      className={cn(\"flex min-h-full flex-col gap-8\", className)}\n      {...props}\n    >\n      {spacerClassName ? (\n        <div\n          aria-hidden=\"true\"\n          data-slot=\"message-scroller-spacer\"\n          className={cn(\"flex-1\", spacerClassName)}\n        />\n      ) : null}\n      {children}\n    </div>\n  )\n}\n\nfunction MessageScrollerItem({\n  className,\n  messageId,\n  scrollAnchor,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  messageId?: string\n  scrollAnchor?: boolean\n}) {\n  return (\n    <div\n      data-slot=\"message-scroller-item\"\n      data-message-id={messageId}\n      data-scroll-anchor={scrollAnchor || undefined}\n      className={cn(\"min-w-0 shrink-0\", className)}\n      {...props}\n    />\n  )\n}\n\nexport interface MessageScrollerButtonProps\n  extends Omit<React.ComponentProps<typeof Button>, \"children\"> {\n  behavior?: ScrollBehavior\n  direction?: \"start\" | \"end\"\n  render?: React.ReactElement\n  children?: React.ReactNode\n}\n\nfunction MessageScrollerButton({\n  behavior = \"smooth\",\n  direction = \"end\",\n  className,\n  children,\n  render,\n  onClick,\n  ...props\n}: MessageScrollerButtonProps) {\n  const { atEnd, atStart, viewportRef } = useScroller()\n  const inactive = direction === \"end\" ? atEnd : atStart\n  return (\n    <Button\n      asChild={Boolean(render)}\n      type=\"button\"\n      aria-hidden={inactive}\n      tabIndex={inactive ? -1 : 0}\n      className={cn(\n        \"bg-background absolute left-1/2 -translate-x-1/2 border transition-[opacity,transform] duration-200\",\n        direction === \"end\" ? \"bottom-4\" : \"top-4\",\n        inactive && \"pointer-events-none translate-y-2 opacity-0\",\n        className\n      )}\n      onClick={(event) => {\n        const viewport = viewportRef.current\n        viewport?.scrollTo({\n          top: direction === \"end\" ? viewport.scrollHeight : 0,\n          behavior,\n        })\n        onClick?.(event)\n      }}\n      {...props}\n    >\n      {render ?? (\n        <>\n          {children ?? (\n            <ArrowDownIcon\n              className={cn(direction === \"start\" && \"rotate-180\")}\n            />\n          )}\n          <span className=\"sr-only\">\n            {direction === \"end\" ? \"Scroll to end\" : \"Scroll to start\"}\n          </span>\n        </>\n      )}\n    </Button>\n  )\n}\n\nexport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/button.tsx",
          "target": "@components/voice-agents/livekit/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-chat-indicator.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-indicator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { motion, useReducedMotion, type MotionProps } from \"motion/react\"\nimport { type ComponentProps, type Ref } from \"react\"\n\nconst motionAnimationProps = {\n  variants: {\n    hidden: {\n      opacity: 0,\n      scale: 0.1,\n      transition: {\n        duration: 0.1,\n        ease: \"linear\" as const,\n      },\n    },\n    visible: {\n      opacity: [0.5, 1],\n      scale: [0.9, 1],\n      transition: {\n        type: \"spring\" as const,\n        bounce: 0,\n        duration: 0.5,\n        repeat: Infinity,\n        repeatType: \"mirror\" as const,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\nconst agentChatIndicatorVariants = cva(\n  \"bg-muted-foreground inline-block size-2.5 rounded-full\",\n  {\n    variants: {\n      size: {\n        sm: \"size-3\",\n        md: \"size-4\",\n        lg: \"size-6\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentChatIndicator component.\n */\nexport interface AgentChatIndicatorProps extends MotionProps {\n  /**\n   * The size of the indicator dot.\n   * @defaultValue 'md'\n   */\n  size?: \"sm\" | \"md\" | \"lg\"\n  /**\n   * Additional CSS class names to apply to the indicator.\n   */\n  className?: string\n  /**\n   * Allows getting a ref to the component instance.\\nOnce the component unmounts, React will set `ref.current` to `null`\\n(or call the ref with `null` if you passed a callback ref).\\n@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}\n   */\n  ref?: Ref<HTMLSpanElement>\n}\n\n/**\n * An animated indicator that shows the agent is processing or thinking.\n * Displays as a pulsing dot, typically used in chat interfaces.\n *\n * @extends ComponentProps<'span'>\n *\n * @example\n * ```tsx\n * {agentState === 'thinking' && <AgentChatIndicator size=\"md\" />}\n * ```\n */\nexport function AgentChatIndicator({\n  size = \"md\",\n  className,\n  ...props\n}: AgentChatIndicatorProps &\n  ComponentProps<\"span\"> &\n  VariantProps<typeof agentChatIndicatorVariants>) {\n  const prefersReducedMotion = useReducedMotion()\n\n  return (\n    <motion.span\n      {...(prefersReducedMotion\n        ? { initial: false, animate: { opacity: 1, scale: 1 } }\n        : motionAnimationProps)}\n      transition={{ duration: 0.1, ease: \"linear\" as const }}\n      className={cn(agentChatIndicatorVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-toggle.tsx",
          "target": "@components/voice-agents/livekit/agent-track-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Track } from \"livekit-client\"\nimport {\n  LoaderIcon,\n  MicIcon,\n  MicOffIcon,\n  MonitorOffIcon,\n  MonitorUpIcon,\n  VideoIcon,\n  VideoOffIcon,\n} from \"lucide-react\"\nimport { Fragment, useMemo, useState, type ComponentProps } from \"react\"\n\nexport const agentTrackToggleVariants = cva([\"size-9\"], {\n  variants: {\n    size: {\n      default: \"h-9 px-2 min-w-9\",\n      sm: \"h-8 px-1.5 min-w-8\",\n      lg: \"h-10 px-2.5 min-w-10\",\n    },\n    variant: {\n      default: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive\",\n        \"data-[state=off]:hover:bg-destructive/15\",\n        \"data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n        \"data-[state=on]:hover:bg-foreground/10\",\n      ],\n      outline: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive data-[state=off]:border-destructive/20\",\n        \"data-[state=off]:hover:bg-destructive/15 data-[state=off]:hover:text-destructive\",\n        \"data-[state=off]:focus:text-destructive\",\n        \"data-[state=off]:focus-visible:border-destructive data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:hover:bg-foreground/10 data-[state=on]:hover:border-foreground/12\",\n        \"dark:data-[state=on]:hover:bg-foreground/10\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n})\n\nfunction getSourceIcon(\n  source: Track.Source,\n  enabled: boolean,\n  pending = false\n) {\n  if (pending) {\n    return LoaderIcon\n  }\n\n  switch (source) {\n    case Track.Source.Microphone:\n      return enabled ? MicIcon : MicOffIcon\n    case Track.Source.Camera:\n      return enabled ? VideoIcon : VideoOffIcon\n    case Track.Source.ScreenShare:\n      return enabled ? MonitorUpIcon : MonitorOffIcon\n    default:\n      return Fragment\n  }\n}\n\n/**\n * Props for the AgentTrackToggle component.\n */\nexport type AgentTrackToggleProps = VariantProps<\n  typeof agentTrackToggleVariants\n> &\n  ComponentProps<\"button\"> & {\n    /**\n     * The size of the toggle.\n     */\n    size?: \"sm\" | \"default\" | \"lg\"\n    /**\n     * The variant of the toggle.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\"\n    /**\n     * The track source to toggle (Microphone, Camera, or ScreenShare).\n     */\n    source: \"camera\" | \"microphone\" | \"screen_share\"\n    /**\n     * Whether the toggle is in a pending/loading state.\n     * When true, displays a loading spinner icon.\n     * @defaultValue false\n     */\n    pending?: boolean\n    /**\n     * Whether the toggle is currently pressed/enabled.\n     * @defaultValue false\n     */\n    pressed?: boolean\n    /**\n     * The default pressed state when uncontrolled.\n     * @defaultValue false\n     */\n    defaultPressed?: boolean\n    /**\n     * Callback fired when the pressed state changes.\n     */\n    onPressedChange?: (pressed: boolean) => void\n  }\n\n/**\n * A toggle button for controlling track publishing state.\n * Displays appropriate icons based on the track source and state.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentTrackToggle\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n * />\n * ```\n */\nexport function AgentTrackToggle({\n  size = \"default\",\n  variant = \"default\",\n  source,\n  pending = false,\n  pressed,\n  defaultPressed = false,\n  className,\n  onPressedChange,\n  ...props\n}: AgentTrackToggleProps) {\n  const [uncontrolledPressed, setUncontrolledPressed] = useState(\n    defaultPressed ?? false\n  )\n  const isControlled = pressed !== undefined\n  const resolvedPressed = useMemo(\n    () => (isControlled ? pressed : uncontrolledPressed) ?? false,\n    [isControlled, pressed, uncontrolledPressed]\n  )\n  const IconComponent = getSourceIcon(\n    source as Track.Source,\n    resolvedPressed,\n    pending\n  )\n  const handlePressedChange = (nextPressed: boolean) => {\n    if (!isControlled) {\n      setUncontrolledPressed(nextPressed)\n    }\n    onPressedChange?.(nextPressed)\n  }\n\n  return (\n    <Toggle\n      size={size}\n      variant={variant}\n      pressed={isControlled ? pressed : undefined}\n      defaultPressed={isControlled ? undefined : defaultPressed}\n      aria-label={`Toggle ${source}`}\n      onPressedChange={handlePressedChange}\n      className={cn(\n        agentTrackToggleVariants({\n          size,\n          variant: variant ?? \"default\",\n          className,\n        })\n      )}\n      {...props}\n    >\n      <IconComponent className={cn(pending && \"animate-spin\")} />\n      {props.children}\n    </Toggle>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/toggle.tsx",
          "target": "@components/voice-agents/livekit/_ui/toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline:\n          \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-9 min-w-9 px-2\",\n        sm: \"h-8 min-w-8 px-1.5\",\n        lg: \"h-10 min-w-10 px-2.5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n  VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      className={cn(toggleVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
        },
        {
          "path": "components/voice-agents/state.ts",
          "target": "@components/voice-agents/state.ts",
          "type": "registry:component",
          "content": "export type VoiceSessionState =\n  | \"idle\"\n  | \"connecting\"\n  | \"listening\"\n  | \"thinking\"\n  | \"speaking\"\n  | \"disconnected\"\n  | \"failed\"\n\nexport function voiceOrbState(state: VoiceSessionState) {\n  if (state === \"speaking\") return \"talking\"\n  if (state === \"listening\") return \"listening\"\n  if (state === \"thinking\" || state === \"connecting\") return \"thinking\"\n  return null\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-disconnect-button",
      "type": "registry:block",
      "title": "Livekit Agent Disconnect Button",
      "description": "Agent Disconnect Button",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-disconnect-button.tsx",
          "target": "@components/voice-agents/livekit/agent-disconnect-button.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Button,\n  type buttonVariants,\n} from \"@/components/voice-agents/livekit/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { useSessionContext } from \"@livekit/components-react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { PhoneOffIcon } from \"lucide-react\"\nimport { type ComponentProps } from \"react\"\n\n/**\n * Props for the AgentDisconnectButton component.\n */\nexport interface AgentDisconnectButtonProps\n  extends ComponentProps<\"button\">,\n    VariantProps<typeof buttonVariants> {\n  /**\n   * Custom icon to display. Defaults to PhoneOffIcon.\n   */\n  icon?: React.ReactNode\n  /**\n   * The size of the button.\n   * @default 'default'\n   */\n  size?: \"default\" | \"sm\" | \"lg\" | \"icon\"\n  /**\n   * The variant of the button.\n   * @default 'destructive'\n   */\n  variant?: \"default\" | \"outline\" | \"destructive\" | \"ghost\" | \"link\"\n  /**\n   * The children to render.\n   */\n  children?: React.ReactNode\n  /**\n   * The callback for when the button is clicked.\n   */\n  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\n/**\n * A button to disconnect from the current agent session.\n * Calls the session's end() method when clicked.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentDisconnectButton onClick={() => console.log('Disconnecting...')} />\n * ```\n */\nexport function AgentDisconnectButton({\n  icon,\n  size = \"default\",\n  variant = \"destructive\",\n  children,\n  onClick,\n  ...props\n}: AgentDisconnectButtonProps) {\n  const { end } = useSessionContext()\n  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n    onClick?.(event)\n    if (typeof end === \"function\") {\n      end()\n    }\n  }\n\n  return (\n    <Button size={size} variant={variant} onClick={handleClick} {...props}>\n      {icon ?? <PhoneOffIcon />}\n      {children ?? (\n        <span className={cn(size?.includes(\"icon\") && \"sr-only\")}>\n          End call\n        </span>\n      )}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/button.tsx",
          "target": "@components/voice-agents/livekit/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-track-toggle",
      "type": "registry:block",
      "title": "Livekit Agent Track Toggle",
      "description": "Agent Track Toggle",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-track-toggle.tsx",
          "target": "@components/voice-agents/livekit/agent-track-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Track } from \"livekit-client\"\nimport {\n  LoaderIcon,\n  MicIcon,\n  MicOffIcon,\n  MonitorOffIcon,\n  MonitorUpIcon,\n  VideoIcon,\n  VideoOffIcon,\n} from \"lucide-react\"\nimport { Fragment, useMemo, useState, type ComponentProps } from \"react\"\n\nexport const agentTrackToggleVariants = cva([\"size-9\"], {\n  variants: {\n    size: {\n      default: \"h-9 px-2 min-w-9\",\n      sm: \"h-8 px-1.5 min-w-8\",\n      lg: \"h-10 px-2.5 min-w-10\",\n    },\n    variant: {\n      default: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive\",\n        \"data-[state=off]:hover:bg-destructive/15\",\n        \"data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n        \"data-[state=on]:hover:bg-foreground/10\",\n      ],\n      outline: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive data-[state=off]:border-destructive/20\",\n        \"data-[state=off]:hover:bg-destructive/15 data-[state=off]:hover:text-destructive\",\n        \"data-[state=off]:focus:text-destructive\",\n        \"data-[state=off]:focus-visible:border-destructive data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:hover:bg-foreground/10 data-[state=on]:hover:border-foreground/12\",\n        \"dark:data-[state=on]:hover:bg-foreground/10\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n})\n\nfunction getSourceIcon(\n  source: Track.Source,\n  enabled: boolean,\n  pending = false\n) {\n  if (pending) {\n    return LoaderIcon\n  }\n\n  switch (source) {\n    case Track.Source.Microphone:\n      return enabled ? MicIcon : MicOffIcon\n    case Track.Source.Camera:\n      return enabled ? VideoIcon : VideoOffIcon\n    case Track.Source.ScreenShare:\n      return enabled ? MonitorUpIcon : MonitorOffIcon\n    default:\n      return Fragment\n  }\n}\n\n/**\n * Props for the AgentTrackToggle component.\n */\nexport type AgentTrackToggleProps = VariantProps<\n  typeof agentTrackToggleVariants\n> &\n  ComponentProps<\"button\"> & {\n    /**\n     * The size of the toggle.\n     */\n    size?: \"sm\" | \"default\" | \"lg\"\n    /**\n     * The variant of the toggle.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\"\n    /**\n     * The track source to toggle (Microphone, Camera, or ScreenShare).\n     */\n    source: \"camera\" | \"microphone\" | \"screen_share\"\n    /**\n     * Whether the toggle is in a pending/loading state.\n     * When true, displays a loading spinner icon.\n     * @defaultValue false\n     */\n    pending?: boolean\n    /**\n     * Whether the toggle is currently pressed/enabled.\n     * @defaultValue false\n     */\n    pressed?: boolean\n    /**\n     * The default pressed state when uncontrolled.\n     * @defaultValue false\n     */\n    defaultPressed?: boolean\n    /**\n     * Callback fired when the pressed state changes.\n     */\n    onPressedChange?: (pressed: boolean) => void\n  }\n\n/**\n * A toggle button for controlling track publishing state.\n * Displays appropriate icons based on the track source and state.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentTrackToggle\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n * />\n * ```\n */\nexport function AgentTrackToggle({\n  size = \"default\",\n  variant = \"default\",\n  source,\n  pending = false,\n  pressed,\n  defaultPressed = false,\n  className,\n  onPressedChange,\n  ...props\n}: AgentTrackToggleProps) {\n  const [uncontrolledPressed, setUncontrolledPressed] = useState(\n    defaultPressed ?? false\n  )\n  const isControlled = pressed !== undefined\n  const resolvedPressed = useMemo(\n    () => (isControlled ? pressed : uncontrolledPressed) ?? false,\n    [isControlled, pressed, uncontrolledPressed]\n  )\n  const IconComponent = getSourceIcon(\n    source as Track.Source,\n    resolvedPressed,\n    pending\n  )\n  const handlePressedChange = (nextPressed: boolean) => {\n    if (!isControlled) {\n      setUncontrolledPressed(nextPressed)\n    }\n    onPressedChange?.(nextPressed)\n  }\n\n  return (\n    <Toggle\n      size={size}\n      variant={variant}\n      pressed={isControlled ? pressed : undefined}\n      defaultPressed={isControlled ? undefined : defaultPressed}\n      aria-label={`Toggle ${source}`}\n      onPressedChange={handlePressedChange}\n      className={cn(\n        agentTrackToggleVariants({\n          size,\n          variant: variant ?? \"default\",\n          className,\n        })\n      )}\n      {...props}\n    >\n      <IconComponent className={cn(pending && \"animate-spin\")} />\n      {props.children}\n    </Toggle>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/toggle.tsx",
          "target": "@components/voice-agents/livekit/_ui/toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline:\n          \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-9 min-w-9 px-2\",\n        sm: \"h-8 min-w-8 px-1.5\",\n        lg: \"h-10 min-w-10 px-2.5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n  VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      className={cn(toggleVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-track-control",
      "type": "registry:block",
      "title": "Livekit Agent Track Control",
      "description": "Agent Track Control",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-track-control.tsx",
          "target": "@components/voice-agents/livekit/agent-track-control.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/voice-agents/livekit/_ui/select\"\nimport { type toggleVariants } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { AgentAudioVisualizerBar } from \"@/components/voice-agents/livekit/agent-audio-visualizer-bar\"\nimport { AgentTrackToggle } from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMaybeRoomContext,\n  useMediaDeviceSelect,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { useEffect, useMemo, useState } from \"react\"\n\nconst selectVariants = cva(\n  [\n    \"rounded-l-none shadow-none pl-2 \",\n    \"text-foreground hover:text-muted-foreground\",\n    \"peer-data-[state=on]/track:bg-muted peer-data-[state=on]/track:hover:bg-foreground/10\",\n    \"peer-data-[state=off]/track:text-destructive\",\n    \"peer-data-[state=off]/track:focus-visible:border-destructive peer-data-[state=off]/track:focus-visible:ring-destructive/30\",\n    \"[&_svg]:opacity-100\",\n  ],\n  {\n    variants: {\n      variant: {\n        default: [\n          \"border-none\",\n          \"peer-data-[state=off]/track:bg-destructive/10\",\n          \"peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"peer-data-[state=off]/track:[&_svg]:text-destructive!\",\n\n          \"dark:peer-data-[state=on]/track:bg-accent\",\n          \"dark:peer-data-[state=on]/track:hover:bg-foreground/10\",\n          \"dark:peer-data-[state=off]/track:bg-destructive/10\",\n          \"dark:peer-data-[state=off]/track:hover:bg-destructive/15\",\n        ],\n        outline: [\n          \"border border-l-0\",\n          \"peer-data-[state=off]/track:border-destructive/20\",\n          \"peer-data-[state=off]/track:bg-destructive/10\",\n          \"peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"peer-data-[state=off]/track:[&_svg]:text-destructive!\",\n          \"peer-data-[state=on]/track:hover:border-foreground/12\",\n\n          \"dark:peer-data-[state=off]/track:bg-destructive/10\",\n          \"dark:peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"dark:peer-data-[state=on]/track:bg-accent\",\n          \"dark:peer-data-[state=on]/track:hover:bg-foreground/10\",\n        ],\n      },\n      size: {\n        default: \"w-[180px]\",\n        sm: \"w-auto\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\n/**\n * Props for the TrackDeviceSelect component. */\ntype TrackDeviceSelectProps = React.ComponentProps<typeof SelectTrigger> &\n  VariantProps<typeof selectVariants> & {\n    /**\n     * The type of media device (audioinput or videoinput).\n     */\n    kind: MediaDeviceKind\n    /**\n     * Array of available devices\n     */\n    devices: MediaDeviceInfo[]\n    /**\n     * Active device ID\n     */\n    activeDeviceId?: string\n    /**\n     * The size of the select.\n     * @defaultValue 'default'\n     */\n    size?: \"default\" | \"sm\"\n    /**\n     * The variant of the select.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\" | null\n    /**\n     * Whether to request permissions for the media device.\n     */\n    requestPermissions?: boolean\n    /**\n     * Callback when the select is opened or closed.\n     */\n    onOpen: (open: boolean) => void\n    /**\n     * Callback when the active device changes.\n     */\n    onActiveDeviceChange?: (deviceId: string) => void\n  }\n\n/**\n * A select component for selecting a media device.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <TrackDeviceSelect\n *   size=\"sm\"\n *   variant=\"outline\"\n *   kind=\"audioinput\"\n *   devices={devices}\n *   activeDeviceId={activeDeviceId}\n *   onOpen={setOpen}\n *   onActiveDeviceChange={setActiveDeviceId}\n * />\n * ```\n */\nfunction TrackDeviceSelect({\n  kind,\n  devices,\n  activeDeviceId,\n  size = \"default\",\n  variant = \"default\",\n  className,\n  onOpen,\n  onActiveDeviceChange,\n  ...props\n}: TrackDeviceSelectProps) {\n  const [open, setOpen] = useState(false)\n\n  const handleOpenChange = (open: boolean) => {\n    setOpen(open)\n    onOpen(open)\n  }\n\n  if (devices.length < 2) {\n    return null\n  }\n\n  return (\n    <Select\n      open={open}\n      value={activeDeviceId}\n      onOpenChange={handleOpenChange}\n      onValueChange={onActiveDeviceChange}\n    >\n      <SelectTrigger\n        className={cn(selectVariants({ size, variant }), className)}\n        {...props}\n      >\n        {size !== \"sm\" && (\n          <SelectValue\n            className=\"font-mono text-sm\"\n            placeholder={`Select a ${kind}`}\n          />\n        )}\n      </SelectTrigger>\n      <SelectContent position=\"popper\">\n        {devices.map((device) => (\n          <SelectItem\n            key={device.deviceId}\n            value={device.deviceId}\n            className=\"font-mono text-xs\"\n          >\n            {device.label}\n          </SelectItem>\n        ))}\n      </SelectContent>\n    </Select>\n  )\n}\n\n/**\n * Props for the AgentTrackControl component.\n */\nexport type AgentTrackControlProps = VariantProps<typeof toggleVariants> & {\n  /**\n   * The type of media device (audioinput or videoinput).\n   */\n  kind: MediaDeviceKind\n  /**\n   * The track source to control (Microphone, Camera, or ScreenShare).\n   */\n  source: \"camera\" | \"microphone\" | \"screen_share\"\n  /**\n   * Whether the track is currently enabled/published.\n   */\n  pressed?: boolean\n  /**\n   * Whether the control is in a pending/loading state.\n   */\n  pending?: boolean\n  /**\n   * Whether the control is disabled.\n   */\n  disabled?: boolean\n  /**\n   * The audio track reference for visualization (only for microphone).\n   */\n  audioTrack?: TrackReferenceOrPlaceholder\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Callback when the pressed state changes.\n   */\n  onPressedChange?: (pressed: boolean) => void\n  /**\n   * Callback when a media device error occurs.\n   */\n  onMediaDeviceError?: (error: Error) => void\n  /**\n   * Callback when the active device changes.\n   */\n  onActiveDeviceChange?: (deviceId: string) => void\n}\n\n/**\n * A combined track toggle and device selector control.\n * Includes a toggle button and a dropdown to select the active device.\n * For microphone tracks, displays an audio visualizer.\n *\n * @example\n * ```tsx\n * <AgentTrackControl\n *   kind=\"audioinput\"\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   audioTrack={micTrackRef}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n *   onActiveDeviceChange={(deviceId) => setMicDevice(deviceId)}\n * />\n * ```\n */\nexport function AgentTrackControl({\n  kind,\n  variant = \"default\",\n  source,\n  pressed,\n  pending,\n  disabled,\n  className,\n  audioTrack,\n  onPressedChange,\n  onMediaDeviceError,\n  onActiveDeviceChange,\n}: AgentTrackControlProps) {\n  const room = useMaybeRoomContext()\n  const [requestPermissionsState, setRequestPermissionsState] = useState(false)\n  const { devices, activeDeviceId, setActiveMediaDevice } =\n    useMediaDeviceSelect({\n      room,\n      kind,\n      requestPermissions: requestPermissionsState,\n      onError: onMediaDeviceError,\n    })\n\n  useEffect(() => {\n    // A track was already acquired elsewhere (e.g. session.start()), so permission is already\n    // granted — safe to fetch labeled devices without a second getUserMedia prompt. Without\n    // this, the list stays label-less until a page reload, since the device observer only\n    // re-fetches when `requestPermissions` changes value. Screen share has no `kind` and no\n    // associated device list, so it should never trigger a mic/camera permission request.\n    if (pressed && kind) {\n      setRequestPermissionsState(true)\n    }\n  }, [pressed, kind])\n\n  const handleOpenChange = (open: boolean) => {\n    if (open) {\n      setRequestPermissionsState(true)\n    }\n  }\n\n  const handleActiveDeviceChange = (deviceId: string) => {\n    setActiveMediaDevice(deviceId)\n    onActiveDeviceChange?.(deviceId)\n  }\n\n  const filteredDevices = useMemo(\n    () => devices.filter((d) => d.deviceId !== \"\"),\n    [devices]\n  )\n  // Before permission is granted, the browser reports devices with blank ids, which get filtered\n  // out here — that's an *unknown* device count, not a confirmed empty one. Only treat it as\n  // \"no devices\" once a permission-gated check has actually run and still come up empty;\n  // otherwise the toggle disables itself before the user ever gets a chance to grant permission.\n  const noDevices =\n    Boolean(kind) && requestPermissionsState && filteredDevices.length === 0\n  const resolvedPressed = pressed && !noDevices\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center gap-0 rounded-md\",\n        variant === \"outline\" && \"shadow-xs [&_button]:shadow-none\",\n        className\n      )}\n    >\n      <AgentTrackToggle\n        source={source}\n        pending={pending}\n        variant={variant ?? \"default\"}\n        pressed={resolvedPressed}\n        disabled={noDevices || disabled}\n        onPressedChange={onPressedChange}\n        className=\"peer/track group/track focus:z-10 has-[.audiovisualizer]:w-auto has-[.audiovisualizer]:px-3 has-[~_button]:rounded-r-none has-[~_button]:border-r-0 has-[~_button]:pr-2 has-[~_button]:pl-3\"\n      >\n        {audioTrack && (\n          <AgentAudioVisualizerBar\n            size=\"icon\"\n            barCount={3}\n            state={resolvedPressed ? \"speaking\" : \"disconnected\"}\n            audioTrack={resolvedPressed ? audioTrack : undefined}\n            className=\"audiovisualizer flex h-6 w-auto items-center justify-center gap-0.5\"\n          >\n            <span\n              className={cn([\n                \"h-full min-h-0.5 w-0.5 origin-center\",\n                \"group-data-[state=on]/track:bg-foreground group-data-[state=off]/track:bg-destructive\",\n                \"data-lk-muted:bg-muted\",\n              ])}\n            />\n          </AgentAudioVisualizerBar>\n        )}\n      </AgentTrackToggle>\n      {kind && (\n        <TrackDeviceSelect\n          size=\"sm\"\n          kind={kind}\n          variant={variant}\n          devices={filteredDevices}\n          activeDeviceId={activeDeviceId}\n          onOpen={handleOpenChange}\n          onActiveDeviceChange={handleActiveDeviceChange}\n          className={cn([\n            \"relative\",\n            'before:bg-border before:absolute before:inset-y-0 before:left-0 before:my-2.5 before:w-px has-[~_button]:before:content-[\"\"]',\n            !resolvedPressed && \"before:bg-destructive/20\",\n          ])}\n        />\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/select.tsx",
          "target": "@components/voice-agents/livekit/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='text-'])]:text-muted-foreground flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"item-aligned\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span\n        data-slot=\"select-item-indicator\"\n        className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n      >\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/toggle.tsx",
          "target": "@components/voice-agents/livekit/_ui/toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline:\n          \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-9 min-w-9 px-2\",\n        sm: \"h-8 min-w-8 px-1.5\",\n        lg: \"h-10 min-w-10 px-2.5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n  VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      className={cn(toggleVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerBarAnimator } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { type LocalAudioTrack, type RemoteAudioTrack } from \"livekit-client\"\nimport React, {\n  Children,\n  cloneElement,\n  isValidElement,\n  useMemo,\n  type ComponentProps,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nfunction cloneSingleChild(\n  children: ReactNode | ReactNode[],\n  props?: Record<string, unknown>,\n  key?: unknown\n) {\n  return Children.map(children, (child) => {\n    // Checking isValidElement is the safe way and avoids a typescript error too.\n    if (isValidElement(child) && Children.only(children)) {\n      const childProps = child.props as Record<string, unknown>\n      if (childProps.className) {\n        // make sure we retain classnames of both passed props and child\n        props ??= {}\n        props.className = cn(\n          childProps.className as string,\n          props.className as string\n        )\n        props.style = {\n          ...(childProps.style as CSSProperties),\n          ...(props.style as CSSProperties),\n        }\n      }\n      return cloneElement(child, {\n        ...props,\n        key: key ? String(key) : undefined,\n      })\n    }\n    return child\n  })\n}\n\nexport const AgentAudioVisualizerBarElementVariants = cva(\n  [\n    \"rounded-full transition-colors duration-250 ease-linear\",\n    \"bg-current/10 data-[lk-highlighted=true]:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: \"w-[4px] min-h-[4px]\",\n        sm: \"w-[8px] min-h-[8px]\",\n        md: \"w-[16px] min-h-[16px]\",\n        lg: \"w-[32px] min-h-[32px]\",\n        xl: \"w-[64px] min-h-[64px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\nexport const AgentAudioVisualizerBarVariants = cva(\n  \"relative flex items-center justify-center\",\n  {\n    variants: {\n      size: {\n        icon: \"h-[24px] gap-[2px]\",\n        sm: \"h-[56px] gap-[4px]\",\n        md: \"h-[112px] gap-[8px]\",\n        lg: \"h-[224px] gap-[16px]\",\n        xl: \"h-[448px] gap-[32px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentAudioVisualizerBar component.\n */\nexport interface AgentAudioVisualizerBarProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the bars in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The number of bars to display in the visualizer.\n   * If not provided, defaults based on size: 3 for 'icon'/'sm', 5 for others.\n   */\n  barCount?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match barCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Custom div element to render as grid cells. Each child receives data-lk-index,\n   * data-lk-highlighted props and style props for height. Must be a single div element.\n   */\n  children?: ReactNode\n}\n\n/**\n * A bar-style audio visualizer that responds to agent state and audio levels.\n * Displays animated bars that react to the current agent state (connecting, thinking, speaking, etc.)\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerBar\n *   size=\"md\"\n *   state=\"speaking\"\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerBar({\n  size = \"md\",\n  state = \"connecting\",\n  color,\n  barCount,\n  audioTrack,\n  volumeBands,\n  className,\n  children,\n  style,\n  ...props\n}: AgentAudioVisualizerBarProps &\n  VariantProps<typeof AgentAudioVisualizerBarVariants> &\n  ComponentProps<\"div\">) {\n  const _barCount = useMemo(() => {\n    if (barCount) {\n      return barCount\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 3\n      default:\n        return 5\n    }\n  }, [barCount, size])\n\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: _barCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, _barCount)\n    : multibandVolume\n\n  const sequencerInterval = useMemo(() => {\n    switch (state) {\n      case \"connecting\":\n        return 2000 / _barCount\n      case \"initializing\":\n        return 2000\n      case \"listening\":\n        return 500\n      case \"thinking\":\n        return 150\n      default:\n        return 1000\n    }\n  }, [state, _barCount])\n\n  const highlightedIndices = useAgentAudioVisualizerBarAnimator(\n    state,\n    _barCount,\n    sequencerInterval\n  )\n\n  const bands = useMemo(\n    () =>\n      state === \"speaking\" ? resolvedVolumeBands : new Array(_barCount).fill(0),\n    [state, resolvedVolumeBands, _barCount]\n  )\n\n  if (children && Array.isArray(children)) {\n    throw new Error(\n      \"AgentAudioVisualizerBar children must be a single element.\"\n    )\n  }\n\n  return (\n    <div\n      data-lk-state={state}\n      style={{ ...style, color } as CSSProperties}\n      className={cn(AgentAudioVisualizerBarVariants({ size }), className)}\n      {...props}\n    >\n      {bands.map((band: number, idx: number) =>\n        children ? (\n          <React.Fragment key={idx}>\n            {cloneSingleChild(children, {\n              \"data-lk-index\": idx,\n              \"data-lk-highlighted\": highlightedIndices.includes(idx),\n              style: { height: `${band * 100}%` },\n            })}\n          </React.Fragment>\n        ) : (\n          <div\n            key={idx}\n            data-lk-index={idx}\n            data-lk-highlighted={highlightedIndices.includes(idx)}\n            style={{ height: `${band * 100}%` }}\n            className={cn(AgentAudioVisualizerBarElementVariants({ size }))}\n          />\n        )\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nfunction generateConnectingSequenceBar(columns: number): number[][] {\n  const seq = []\n\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, columns - 1 - x])\n  }\n\n  return seq\n}\n\nfunction generateListeningSequenceBar(columns: number): number[][] {\n  const center = Math.floor(columns / 2)\n  const noIndex = -1\n\n  return [[center], [noIndex]]\n}\n\nexport function useAgentAudioVisualizerBarAnimator(\n  state: AgentState | undefined,\n  columns: number,\n  interval: number\n): number[] {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<number[][]>([[]])\n\n  useEffect(() => {\n    if (state === \"thinking\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      const sequence = [...generateConnectingSequenceBar(columns)]\n      setSequence(sequence)\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === undefined || state === \"speaking\") {\n      setSequence([new Array(columns).fill(0).map((_, idx) => idx)])\n    } else {\n      setSequence([[]])\n    }\n    setIndex(0)\n  }, [state, columns])\n\n  const animationFrameId = useRef<number | null>(null)\n  useEffect(() => {\n    if (prefersReducedMotion || sequence.length <= 1) return\n\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        setIndex((prev) => prev + 1)\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, columns, state, sequence.length, prefersReducedMotion])\n\n  return sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? []\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-toggle.tsx",
          "target": "@components/voice-agents/livekit/agent-track-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Track } from \"livekit-client\"\nimport {\n  LoaderIcon,\n  MicIcon,\n  MicOffIcon,\n  MonitorOffIcon,\n  MonitorUpIcon,\n  VideoIcon,\n  VideoOffIcon,\n} from \"lucide-react\"\nimport { Fragment, useMemo, useState, type ComponentProps } from \"react\"\n\nexport const agentTrackToggleVariants = cva([\"size-9\"], {\n  variants: {\n    size: {\n      default: \"h-9 px-2 min-w-9\",\n      sm: \"h-8 px-1.5 min-w-8\",\n      lg: \"h-10 px-2.5 min-w-10\",\n    },\n    variant: {\n      default: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive\",\n        \"data-[state=off]:hover:bg-destructive/15\",\n        \"data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n        \"data-[state=on]:hover:bg-foreground/10\",\n      ],\n      outline: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive data-[state=off]:border-destructive/20\",\n        \"data-[state=off]:hover:bg-destructive/15 data-[state=off]:hover:text-destructive\",\n        \"data-[state=off]:focus:text-destructive\",\n        \"data-[state=off]:focus-visible:border-destructive data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:hover:bg-foreground/10 data-[state=on]:hover:border-foreground/12\",\n        \"dark:data-[state=on]:hover:bg-foreground/10\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n})\n\nfunction getSourceIcon(\n  source: Track.Source,\n  enabled: boolean,\n  pending = false\n) {\n  if (pending) {\n    return LoaderIcon\n  }\n\n  switch (source) {\n    case Track.Source.Microphone:\n      return enabled ? MicIcon : MicOffIcon\n    case Track.Source.Camera:\n      return enabled ? VideoIcon : VideoOffIcon\n    case Track.Source.ScreenShare:\n      return enabled ? MonitorUpIcon : MonitorOffIcon\n    default:\n      return Fragment\n  }\n}\n\n/**\n * Props for the AgentTrackToggle component.\n */\nexport type AgentTrackToggleProps = VariantProps<\n  typeof agentTrackToggleVariants\n> &\n  ComponentProps<\"button\"> & {\n    /**\n     * The size of the toggle.\n     */\n    size?: \"sm\" | \"default\" | \"lg\"\n    /**\n     * The variant of the toggle.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\"\n    /**\n     * The track source to toggle (Microphone, Camera, or ScreenShare).\n     */\n    source: \"camera\" | \"microphone\" | \"screen_share\"\n    /**\n     * Whether the toggle is in a pending/loading state.\n     * When true, displays a loading spinner icon.\n     * @defaultValue false\n     */\n    pending?: boolean\n    /**\n     * Whether the toggle is currently pressed/enabled.\n     * @defaultValue false\n     */\n    pressed?: boolean\n    /**\n     * The default pressed state when uncontrolled.\n     * @defaultValue false\n     */\n    defaultPressed?: boolean\n    /**\n     * Callback fired when the pressed state changes.\n     */\n    onPressedChange?: (pressed: boolean) => void\n  }\n\n/**\n * A toggle button for controlling track publishing state.\n * Displays appropriate icons based on the track source and state.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentTrackToggle\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n * />\n * ```\n */\nexport function AgentTrackToggle({\n  size = \"default\",\n  variant = \"default\",\n  source,\n  pending = false,\n  pressed,\n  defaultPressed = false,\n  className,\n  onPressedChange,\n  ...props\n}: AgentTrackToggleProps) {\n  const [uncontrolledPressed, setUncontrolledPressed] = useState(\n    defaultPressed ?? false\n  )\n  const isControlled = pressed !== undefined\n  const resolvedPressed = useMemo(\n    () => (isControlled ? pressed : uncontrolledPressed) ?? false,\n    [isControlled, pressed, uncontrolledPressed]\n  )\n  const IconComponent = getSourceIcon(\n    source as Track.Source,\n    resolvedPressed,\n    pending\n  )\n  const handlePressedChange = (nextPressed: boolean) => {\n    if (!isControlled) {\n      setUncontrolledPressed(nextPressed)\n    }\n    onPressedChange?.(nextPressed)\n  }\n\n  return (\n    <Toggle\n      size={size}\n      variant={variant}\n      pressed={isControlled ? pressed : undefined}\n      defaultPressed={isControlled ? undefined : defaultPressed}\n      aria-label={`Toggle ${source}`}\n      onPressedChange={handlePressedChange}\n      className={cn(\n        agentTrackToggleVariants({\n          size,\n          variant: variant ?? \"default\",\n          className,\n        })\n      )}\n      {...props}\n    >\n      <IconComponent className={cn(pending && \"animate-spin\")} />\n      {props.children}\n    </Toggle>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-control-bar",
      "type": "registry:block",
      "title": "Livekit Agent Control Bar",
      "description": "Agent Control Bar",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-control-bar.tsx",
          "target": "@components/voice-agents/livekit/agent-control-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/voice-agents/livekit/_ui/button\"\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { AgentDisconnectButton } from \"@/components/voice-agents/livekit/agent-disconnect-button\"\nimport { AgentTrackControl } from \"@/components/voice-agents/livekit/agent-track-control\"\nimport {\n  AgentTrackToggle,\n  agentTrackToggleVariants,\n} from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport {\n  useInputControls,\n  usePublishPermissions,\n  type UseInputControlsProps,\n} from \"@/components/voice-agents/livekit/hooks/use-agent-control-bar\"\nimport { cn } from \"@/lib/utils\"\nimport { useChat } from \"@livekit/components-react\"\nimport { Track } from \"livekit-client\"\nimport { Loader, MessageSquareTextIcon, SendHorizontal } from \"lucide-react\"\nimport { motion, type MotionProps } from \"motion/react\"\nimport { useEffect, useRef, useState, type ComponentProps } from \"react\"\n\nconst LK_TOGGLE_VARIANT_1 = [\n  \"data-[state=off]:bg-accent data-[state=off]:hover:bg-foreground/10\",\n  \"data-[state=off]:[&_~_button]:bg-accent data-[state=off]:[&_~_button]:hover:bg-foreground/10\",\n  \"data-[state=off]:border-border data-[state=off]:hover:border-foreground/12\",\n  \"data-[state=off]:[&_~_button]:border-border data-[state=off]:[&_~_button]:hover:border-foreground/12\",\n  \"data-[state=off]:text-destructive data-[state=off]:hover:text-destructive data-[state=off]:focus:text-destructive\",\n  \"data-[state=off]:focus-visible:ring-foreground/12 data-[state=off]:focus-visible:border-ring\",\n  \"dark:data-[state=off]:[&_~_button]:bg-accent dark:data-[state=off]:[&_~_button]:hover:bg-foreground/10\",\n]\n\nconst LK_TOGGLE_VARIANT_2 = [\n  \"data-[state=off]:bg-accent data-[state=off]:hover:bg-foreground/10\",\n  \"data-[state=off]:border-border data-[state=off]:hover:border-foreground/12\",\n  \"data-[state=off]:focus-visible:border-ring data-[state=off]:focus-visible:ring-foreground/12\",\n  \"data-[state=off]:text-foreground data-[state=off]:hover:text-foreground data-[state=off]:focus:text-foreground\",\n  \"data-[state=on]:bg-blue-500/20 data-[state=on]:hover:bg-blue-500/30\",\n  \"data-[state=on]:border-blue-700/10 data-[state=on]:text-blue-700 data-[state=on]:ring-blue-700/30\",\n  \"data-[state=on]:focus-visible:border-blue-700/50\",\n  \"dark:data-[state=on]:bg-blue-500/20 dark:data-[state=on]:text-blue-300\",\n]\n\nconst MOTION_PROPS: MotionProps = {\n  variants: {\n    hidden: {\n      height: 0,\n      opacity: 0,\n      marginBottom: 0,\n    },\n    visible: {\n      height: \"auto\",\n      opacity: 1,\n      marginBottom: 12,\n    },\n  },\n  initial: \"hidden\",\n  transition: {\n    duration: 0.3,\n    ease: \"easeOut\",\n  },\n}\n\ninterface AgentChatInputProps {\n  chatOpen: boolean\n  onSend?: (message: string) => void\n  className?: string\n}\n\nfunction AgentChatInput({\n  chatOpen,\n  onSend = async () => {},\n  className,\n}: AgentChatInputProps) {\n  const inputRef = useRef<HTMLTextAreaElement>(null)\n  const [isSending, setIsSending] = useState(false)\n  const [message, setMessage] = useState<string>(\"\")\n  const isDisabled = isSending || message.trim().length === 0\n\n  const handleSend = async () => {\n    if (isDisabled) {\n      return\n    }\n\n    try {\n      setIsSending(true)\n      await onSend(message.trim())\n      setMessage(\"\")\n    } catch (error) {\n      console.error(error)\n    } finally {\n      setIsSending(false)\n    }\n  }\n\n  const handleKeyDown = async (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === \"Enter\" && !e.shiftKey) {\n      e.preventDefault()\n      handleSend()\n    }\n  }\n\n  const handleButtonClick = async () => {\n    if (isDisabled) return\n    await handleSend()\n  }\n\n  useEffect(() => {\n    if (chatOpen) return\n    // when not disabled refocus on input\n    inputRef.current?.focus()\n  }, [chatOpen])\n\n  return (\n    <div\n      className={cn(\n        \"mb-3 flex grow items-end gap-2 rounded-md pl-1 text-sm\",\n        className\n      )}\n    >\n      <textarea\n        autoFocus\n        ref={inputRef}\n        value={message}\n        disabled={!chatOpen || isSending}\n        placeholder=\"Type something...\"\n        onKeyDown={handleKeyDown}\n        onChange={(e) => setMessage(e.target.value)}\n        className=\"field-sizing-content max-h-16 min-h-8 flex-1 resize-none py-2 [scrollbar-width:thin] focus:outline-none disabled:cursor-not-allowed disabled:opacity-50\"\n      />\n      <Button\n        size=\"icon\"\n        type=\"button\"\n        disabled={isDisabled}\n        variant={isDisabled ? \"secondary\" : \"default\"}\n        title={isSending ? \"Sending...\" : \"Send\"}\n        onClick={handleButtonClick}\n        className=\"self-end disabled:cursor-not-allowed\"\n      >\n        {isSending ? <Loader className=\"animate-spin\" /> : <SendHorizontal />}\n      </Button>\n    </div>\n  )\n}\n\n/** Configuration for which controls to display in the AgentControlBar. */\nexport interface AgentControlBarControls {\n  /**\n   * Whether to show the leave/disconnect button.\n   *\n   * @defaultValue true\n   */\n  leave?: boolean\n  /**\n   * Whether to show the camera toggle control.\n   *\n   * @defaultValue true (if camera publish permission is granted)\n   */\n  camera?: boolean\n  /**\n   * Whether to show the microphone toggle control.\n   *\n   * @defaultValue true (if microphone publish permission is granted)\n   */\n  microphone?: boolean\n  /**\n   * Whether to show the screen share toggle control.\n   *\n   * @defaultValue true (if screen share publish permission is granted)\n   */\n  screenShare?: boolean\n  /**\n   * Whether to show the chat toggle control.\n   *\n   * @defaultValue true (if data publish permission is granted)\n   */\n  chat?: boolean\n}\n\nexport interface AgentControlBarProps extends UseInputControlsProps {\n  /**\n   * The visual style of the control bar.\n   *\n   * @default 'default'\n   */\n  variant?: \"default\" | \"outline\" | \"livekit\"\n  /**\n   * This takes an object with the following keys: `leave`, `microphone`, `screenShare`, `camera`,\n   * `chat`. Each key maps to a boolean value that determines whether the control is displayed.\n   *\n   * @default\n   * {\n   *   leave: true,\n   *   microphone: true,\n   *   screenShare: true,\n   *   camera: true,\n   *   chat: true,\n   * }\n   */\n  controls?: AgentControlBarControls\n  /**\n   * Whether to save user choices.\n   *\n   * @default true\n   */\n  saveUserChoices?: boolean\n  /**\n   * Whether the agent is connected to a session.\n   *\n   * @default false\n   */\n  isConnected?: boolean\n  /**\n   * Whether the chat input interface is open.\n   *\n   * @default false\n   */\n  isChatOpen?: boolean\n  /** The callback for when the user disconnects. */\n  onDisconnect?: () => void\n  /** The callback for when the chat is opened or closed. */\n  onIsChatOpenChange?: (open: boolean) => void\n  /** The callback for when a device error occurs. */\n  onDeviceError?: (error: { source: Track.Source; error: Error }) => void\n}\n\n/**\n * A control bar specifically designed for voice assistant interfaces. Provides controls for\n * microphone, camera, screen share, chat, and disconnect. Includes an expandable chat input for\n * text-based interaction with the agent.\n *\n * @example\n *\n * ```tsx\n * <AgentControlBar\n *   variant=\"livekit\"\n *   isConnected={true}\n *   onDisconnect={() => handleDisconnect()}\n *   controls={{\n *     microphone: true,\n *     camera: true,\n *     screenShare: false,\n *     chat: true,\n *     leave: true,\n *   }}\n * />;\n * ```\n *\n * @extends ComponentProps<'div'>\n */\nexport function AgentControlBar({\n  variant = \"default\",\n  controls,\n  isChatOpen = false,\n  isConnected = false,\n  saveUserChoices = true,\n  onDisconnect,\n  onDeviceError,\n  onIsChatOpenChange,\n  className,\n  ...props\n}: AgentControlBarProps & ComponentProps<\"div\">) {\n  const { send } = useChat()\n  const publishPermissions = usePublishPermissions()\n  const [isChatOpenUncontrolled, setIsChatOpenUncontrolled] =\n    useState(isChatOpen)\n  const {\n    microphoneTrack,\n    cameraToggle,\n    microphoneToggle,\n    screenShareToggle,\n    handleAudioDeviceChange,\n    handleVideoDeviceChange,\n    handleMicrophoneDeviceSelectError,\n    handleCameraDeviceSelectError,\n  } = useInputControls({ onDeviceError, saveUserChoices })\n\n  const handleSendMessage = async (message: string) => {\n    await send(message)\n  }\n\n  const visibleControls = {\n    leave: controls?.leave ?? true,\n    microphone: controls?.microphone ?? publishPermissions.microphone,\n    screenShare: controls?.screenShare ?? publishPermissions.screenShare,\n    camera: controls?.camera ?? publishPermissions.camera,\n    chat: controls?.chat ?? publishPermissions.data,\n  }\n\n  const isEmpty = Object.values(visibleControls).every((value) => !value)\n\n  if (isEmpty) {\n    console.warn(\n      \"AgentControlBar: `visibleControls` contains only false values.\"\n    )\n    return null\n  }\n\n  return (\n    <div\n      aria-label=\"Voice assistant controls\"\n      className={cn(\n        \"bg-background border-input/50 dark:border-muted @container/agent-control-bar flex flex-col border p-3 drop-shadow-md/3\",\n        variant === \"livekit\" ? \"rounded-[31px]\" : \"rounded-lg\",\n        className\n      )}\n      {...props}\n    >\n      <motion.div\n        {...MOTION_PROPS}\n        inert={!(isChatOpen || isChatOpenUncontrolled)}\n        animate={isChatOpen || isChatOpenUncontrolled ? \"visible\" : \"hidden\"}\n        className=\"border-input/50 flex w-full items-start overflow-hidden border-b\"\n      >\n        <AgentChatInput\n          chatOpen={isChatOpen || isChatOpenUncontrolled}\n          onSend={handleSendMessage}\n          className={cn(variant === \"livekit\" && \"[&_button]:rounded-full\")}\n        />\n      </motion.div>\n\n      <div className=\"flex gap-1\">\n        <div className=\"flex grow gap-1\">\n          {/* Toggle Microphone */}\n          {visibleControls.microphone && (\n            <AgentTrackControl\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              kind=\"audioinput\"\n              aria-label=\"Toggle microphone\"\n              source={Track.Source.Microphone}\n              pressed={microphoneToggle.enabled}\n              disabled={microphoneToggle.pending}\n              audioTrack={microphoneTrack}\n              onPressedChange={microphoneToggle.toggle}\n              onActiveDeviceChange={handleAudioDeviceChange}\n              onMediaDeviceError={handleMicrophoneDeviceSelectError}\n              className={cn(\n                variant === \"livekit\" && [\n                  LK_TOGGLE_VARIANT_1,\n                  \"rounded-full [&_button:first-child]:rounded-l-full [&_button:last-child]:rounded-r-full\",\n                ]\n              )}\n            />\n          )}\n\n          {/* Toggle Camera */}\n          {visibleControls.camera && (\n            <AgentTrackControl\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              kind=\"videoinput\"\n              aria-label=\"Toggle camera\"\n              source={Track.Source.Camera}\n              pressed={cameraToggle.enabled}\n              pending={cameraToggle.pending}\n              disabled={cameraToggle.pending}\n              onPressedChange={cameraToggle.toggle}\n              onMediaDeviceError={handleCameraDeviceSelectError}\n              onActiveDeviceChange={handleVideoDeviceChange}\n              className={cn(\n                variant === \"livekit\" && [\n                  LK_TOGGLE_VARIANT_1,\n                  \"rounded-full [&_button:first-child]:rounded-l-full [&_button:last-child]:rounded-r-full\",\n                ]\n              )}\n            />\n          )}\n\n          {/* Toggle Screen Share */}\n          {visibleControls.screenShare && (\n            <AgentTrackToggle\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              aria-label=\"Toggle screen share\"\n              source={Track.Source.ScreenShare}\n              pressed={screenShareToggle.enabled}\n              disabled={screenShareToggle.pending}\n              onPressedChange={screenShareToggle.toggle}\n              className={cn(\n                variant === \"livekit\" && [LK_TOGGLE_VARIANT_2, \"rounded-full\"]\n              )}\n            />\n          )}\n\n          {/* Toggle Transcript */}\n          {visibleControls.chat && (\n            <Toggle\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              pressed={isChatOpen || isChatOpenUncontrolled}\n              aria-label=\"Toggle transcript\"\n              onPressedChange={(state) => {\n                if (!onIsChatOpenChange) setIsChatOpenUncontrolled(state)\n                else onIsChatOpenChange(state)\n              }}\n              className={agentTrackToggleVariants({\n                variant: variant === \"outline\" ? \"outline\" : \"default\",\n                className: cn(\n                  variant === \"livekit\" && [LK_TOGGLE_VARIANT_2, \"rounded-full\"]\n                ),\n              })}\n            >\n              <MessageSquareTextIcon />\n            </Toggle>\n          )}\n        </div>\n\n        {/* Disconnect */}\n        {visibleControls.leave && (\n          <AgentDisconnectButton\n            onClick={onDisconnect}\n            disabled={!isConnected}\n            className={cn(\n              variant === \"livekit\" &&\n                \"bg-destructive/10 dark:bg-destructive/10 text-destructive hover:bg-destructive/20 dark:hover:bg-destructive/20 focus:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/4 rounded-full font-mono text-xs font-bold tracking-wider\"\n            )}\n          >\n            <span className=\"sr-only uppercase @sm/agent-control-bar:not-sr-only\">\n              End{\" \"}\n              <span className=\"sr-only @md/agent-control-bar:not-sr-only\">\n                call\n              </span>\n            </span>\n          </AgentDisconnectButton>\n        )}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/button.tsx",
          "target": "@components/voice-agents/livekit/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/toggle.tsx",
          "target": "@components/voice-agents/livekit/_ui/toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline:\n          \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-9 min-w-9 px-2\",\n        sm: \"h-8 min-w-8 px-1.5\",\n        lg: \"h-10 min-w-10 px-2.5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n  VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      className={cn(toggleVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-disconnect-button.tsx",
          "target": "@components/voice-agents/livekit/agent-disconnect-button.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Button,\n  type buttonVariants,\n} from \"@/components/voice-agents/livekit/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { useSessionContext } from \"@livekit/components-react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { PhoneOffIcon } from \"lucide-react\"\nimport { type ComponentProps } from \"react\"\n\n/**\n * Props for the AgentDisconnectButton component.\n */\nexport interface AgentDisconnectButtonProps\n  extends ComponentProps<\"button\">,\n    VariantProps<typeof buttonVariants> {\n  /**\n   * Custom icon to display. Defaults to PhoneOffIcon.\n   */\n  icon?: React.ReactNode\n  /**\n   * The size of the button.\n   * @default 'default'\n   */\n  size?: \"default\" | \"sm\" | \"lg\" | \"icon\"\n  /**\n   * The variant of the button.\n   * @default 'destructive'\n   */\n  variant?: \"default\" | \"outline\" | \"destructive\" | \"ghost\" | \"link\"\n  /**\n   * The children to render.\n   */\n  children?: React.ReactNode\n  /**\n   * The callback for when the button is clicked.\n   */\n  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\n/**\n * A button to disconnect from the current agent session.\n * Calls the session's end() method when clicked.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentDisconnectButton onClick={() => console.log('Disconnecting...')} />\n * ```\n */\nexport function AgentDisconnectButton({\n  icon,\n  size = \"default\",\n  variant = \"destructive\",\n  children,\n  onClick,\n  ...props\n}: AgentDisconnectButtonProps) {\n  const { end } = useSessionContext()\n  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n    onClick?.(event)\n    if (typeof end === \"function\") {\n      end()\n    }\n  }\n\n  return (\n    <Button size={size} variant={variant} onClick={handleClick} {...props}>\n      {icon ?? <PhoneOffIcon />}\n      {children ?? (\n        <span className={cn(size?.includes(\"icon\") && \"sr-only\")}>\n          End call\n        </span>\n      )}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-control.tsx",
          "target": "@components/voice-agents/livekit/agent-track-control.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/voice-agents/livekit/_ui/select\"\nimport { type toggleVariants } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { AgentAudioVisualizerBar } from \"@/components/voice-agents/livekit/agent-audio-visualizer-bar\"\nimport { AgentTrackToggle } from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMaybeRoomContext,\n  useMediaDeviceSelect,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { useEffect, useMemo, useState } from \"react\"\n\nconst selectVariants = cva(\n  [\n    \"rounded-l-none shadow-none pl-2 \",\n    \"text-foreground hover:text-muted-foreground\",\n    \"peer-data-[state=on]/track:bg-muted peer-data-[state=on]/track:hover:bg-foreground/10\",\n    \"peer-data-[state=off]/track:text-destructive\",\n    \"peer-data-[state=off]/track:focus-visible:border-destructive peer-data-[state=off]/track:focus-visible:ring-destructive/30\",\n    \"[&_svg]:opacity-100\",\n  ],\n  {\n    variants: {\n      variant: {\n        default: [\n          \"border-none\",\n          \"peer-data-[state=off]/track:bg-destructive/10\",\n          \"peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"peer-data-[state=off]/track:[&_svg]:text-destructive!\",\n\n          \"dark:peer-data-[state=on]/track:bg-accent\",\n          \"dark:peer-data-[state=on]/track:hover:bg-foreground/10\",\n          \"dark:peer-data-[state=off]/track:bg-destructive/10\",\n          \"dark:peer-data-[state=off]/track:hover:bg-destructive/15\",\n        ],\n        outline: [\n          \"border border-l-0\",\n          \"peer-data-[state=off]/track:border-destructive/20\",\n          \"peer-data-[state=off]/track:bg-destructive/10\",\n          \"peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"peer-data-[state=off]/track:[&_svg]:text-destructive!\",\n          \"peer-data-[state=on]/track:hover:border-foreground/12\",\n\n          \"dark:peer-data-[state=off]/track:bg-destructive/10\",\n          \"dark:peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"dark:peer-data-[state=on]/track:bg-accent\",\n          \"dark:peer-data-[state=on]/track:hover:bg-foreground/10\",\n        ],\n      },\n      size: {\n        default: \"w-[180px]\",\n        sm: \"w-auto\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\n/**\n * Props for the TrackDeviceSelect component. */\ntype TrackDeviceSelectProps = React.ComponentProps<typeof SelectTrigger> &\n  VariantProps<typeof selectVariants> & {\n    /**\n     * The type of media device (audioinput or videoinput).\n     */\n    kind: MediaDeviceKind\n    /**\n     * Array of available devices\n     */\n    devices: MediaDeviceInfo[]\n    /**\n     * Active device ID\n     */\n    activeDeviceId?: string\n    /**\n     * The size of the select.\n     * @defaultValue 'default'\n     */\n    size?: \"default\" | \"sm\"\n    /**\n     * The variant of the select.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\" | null\n    /**\n     * Whether to request permissions for the media device.\n     */\n    requestPermissions?: boolean\n    /**\n     * Callback when the select is opened or closed.\n     */\n    onOpen: (open: boolean) => void\n    /**\n     * Callback when the active device changes.\n     */\n    onActiveDeviceChange?: (deviceId: string) => void\n  }\n\n/**\n * A select component for selecting a media device.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <TrackDeviceSelect\n *   size=\"sm\"\n *   variant=\"outline\"\n *   kind=\"audioinput\"\n *   devices={devices}\n *   activeDeviceId={activeDeviceId}\n *   onOpen={setOpen}\n *   onActiveDeviceChange={setActiveDeviceId}\n * />\n * ```\n */\nfunction TrackDeviceSelect({\n  kind,\n  devices,\n  activeDeviceId,\n  size = \"default\",\n  variant = \"default\",\n  className,\n  onOpen,\n  onActiveDeviceChange,\n  ...props\n}: TrackDeviceSelectProps) {\n  const [open, setOpen] = useState(false)\n\n  const handleOpenChange = (open: boolean) => {\n    setOpen(open)\n    onOpen(open)\n  }\n\n  if (devices.length < 2) {\n    return null\n  }\n\n  return (\n    <Select\n      open={open}\n      value={activeDeviceId}\n      onOpenChange={handleOpenChange}\n      onValueChange={onActiveDeviceChange}\n    >\n      <SelectTrigger\n        className={cn(selectVariants({ size, variant }), className)}\n        {...props}\n      >\n        {size !== \"sm\" && (\n          <SelectValue\n            className=\"font-mono text-sm\"\n            placeholder={`Select a ${kind}`}\n          />\n        )}\n      </SelectTrigger>\n      <SelectContent position=\"popper\">\n        {devices.map((device) => (\n          <SelectItem\n            key={device.deviceId}\n            value={device.deviceId}\n            className=\"font-mono text-xs\"\n          >\n            {device.label}\n          </SelectItem>\n        ))}\n      </SelectContent>\n    </Select>\n  )\n}\n\n/**\n * Props for the AgentTrackControl component.\n */\nexport type AgentTrackControlProps = VariantProps<typeof toggleVariants> & {\n  /**\n   * The type of media device (audioinput or videoinput).\n   */\n  kind: MediaDeviceKind\n  /**\n   * The track source to control (Microphone, Camera, or ScreenShare).\n   */\n  source: \"camera\" | \"microphone\" | \"screen_share\"\n  /**\n   * Whether the track is currently enabled/published.\n   */\n  pressed?: boolean\n  /**\n   * Whether the control is in a pending/loading state.\n   */\n  pending?: boolean\n  /**\n   * Whether the control is disabled.\n   */\n  disabled?: boolean\n  /**\n   * The audio track reference for visualization (only for microphone).\n   */\n  audioTrack?: TrackReferenceOrPlaceholder\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Callback when the pressed state changes.\n   */\n  onPressedChange?: (pressed: boolean) => void\n  /**\n   * Callback when a media device error occurs.\n   */\n  onMediaDeviceError?: (error: Error) => void\n  /**\n   * Callback when the active device changes.\n   */\n  onActiveDeviceChange?: (deviceId: string) => void\n}\n\n/**\n * A combined track toggle and device selector control.\n * Includes a toggle button and a dropdown to select the active device.\n * For microphone tracks, displays an audio visualizer.\n *\n * @example\n * ```tsx\n * <AgentTrackControl\n *   kind=\"audioinput\"\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   audioTrack={micTrackRef}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n *   onActiveDeviceChange={(deviceId) => setMicDevice(deviceId)}\n * />\n * ```\n */\nexport function AgentTrackControl({\n  kind,\n  variant = \"default\",\n  source,\n  pressed,\n  pending,\n  disabled,\n  className,\n  audioTrack,\n  onPressedChange,\n  onMediaDeviceError,\n  onActiveDeviceChange,\n}: AgentTrackControlProps) {\n  const room = useMaybeRoomContext()\n  const [requestPermissionsState, setRequestPermissionsState] = useState(false)\n  const { devices, activeDeviceId, setActiveMediaDevice } =\n    useMediaDeviceSelect({\n      room,\n      kind,\n      requestPermissions: requestPermissionsState,\n      onError: onMediaDeviceError,\n    })\n\n  useEffect(() => {\n    // A track was already acquired elsewhere (e.g. session.start()), so permission is already\n    // granted — safe to fetch labeled devices without a second getUserMedia prompt. Without\n    // this, the list stays label-less until a page reload, since the device observer only\n    // re-fetches when `requestPermissions` changes value. Screen share has no `kind` and no\n    // associated device list, so it should never trigger a mic/camera permission request.\n    if (pressed && kind) {\n      setRequestPermissionsState(true)\n    }\n  }, [pressed, kind])\n\n  const handleOpenChange = (open: boolean) => {\n    if (open) {\n      setRequestPermissionsState(true)\n    }\n  }\n\n  const handleActiveDeviceChange = (deviceId: string) => {\n    setActiveMediaDevice(deviceId)\n    onActiveDeviceChange?.(deviceId)\n  }\n\n  const filteredDevices = useMemo(\n    () => devices.filter((d) => d.deviceId !== \"\"),\n    [devices]\n  )\n  // Before permission is granted, the browser reports devices with blank ids, which get filtered\n  // out here — that's an *unknown* device count, not a confirmed empty one. Only treat it as\n  // \"no devices\" once a permission-gated check has actually run and still come up empty;\n  // otherwise the toggle disables itself before the user ever gets a chance to grant permission.\n  const noDevices =\n    Boolean(kind) && requestPermissionsState && filteredDevices.length === 0\n  const resolvedPressed = pressed && !noDevices\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center gap-0 rounded-md\",\n        variant === \"outline\" && \"shadow-xs [&_button]:shadow-none\",\n        className\n      )}\n    >\n      <AgentTrackToggle\n        source={source}\n        pending={pending}\n        variant={variant ?? \"default\"}\n        pressed={resolvedPressed}\n        disabled={noDevices || disabled}\n        onPressedChange={onPressedChange}\n        className=\"peer/track group/track focus:z-10 has-[.audiovisualizer]:w-auto has-[.audiovisualizer]:px-3 has-[~_button]:rounded-r-none has-[~_button]:border-r-0 has-[~_button]:pr-2 has-[~_button]:pl-3\"\n      >\n        {audioTrack && (\n          <AgentAudioVisualizerBar\n            size=\"icon\"\n            barCount={3}\n            state={resolvedPressed ? \"speaking\" : \"disconnected\"}\n            audioTrack={resolvedPressed ? audioTrack : undefined}\n            className=\"audiovisualizer flex h-6 w-auto items-center justify-center gap-0.5\"\n          >\n            <span\n              className={cn([\n                \"h-full min-h-0.5 w-0.5 origin-center\",\n                \"group-data-[state=on]/track:bg-foreground group-data-[state=off]/track:bg-destructive\",\n                \"data-lk-muted:bg-muted\",\n              ])}\n            />\n          </AgentAudioVisualizerBar>\n        )}\n      </AgentTrackToggle>\n      {kind && (\n        <TrackDeviceSelect\n          size=\"sm\"\n          kind={kind}\n          variant={variant}\n          devices={filteredDevices}\n          activeDeviceId={activeDeviceId}\n          onOpen={handleOpenChange}\n          onActiveDeviceChange={handleActiveDeviceChange}\n          className={cn([\n            \"relative\",\n            'before:bg-border before:absolute before:inset-y-0 before:left-0 before:my-2.5 before:w-px has-[~_button]:before:content-[\"\"]',\n            !resolvedPressed && \"before:bg-destructive/20\",\n          ])}\n        />\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/select.tsx",
          "target": "@components/voice-agents/livekit/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='text-'])]:text-muted-foreground flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"item-aligned\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span\n        data-slot=\"select-item-indicator\"\n        className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n      >\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerBarAnimator } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { type LocalAudioTrack, type RemoteAudioTrack } from \"livekit-client\"\nimport React, {\n  Children,\n  cloneElement,\n  isValidElement,\n  useMemo,\n  type ComponentProps,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nfunction cloneSingleChild(\n  children: ReactNode | ReactNode[],\n  props?: Record<string, unknown>,\n  key?: unknown\n) {\n  return Children.map(children, (child) => {\n    // Checking isValidElement is the safe way and avoids a typescript error too.\n    if (isValidElement(child) && Children.only(children)) {\n      const childProps = child.props as Record<string, unknown>\n      if (childProps.className) {\n        // make sure we retain classnames of both passed props and child\n        props ??= {}\n        props.className = cn(\n          childProps.className as string,\n          props.className as string\n        )\n        props.style = {\n          ...(childProps.style as CSSProperties),\n          ...(props.style as CSSProperties),\n        }\n      }\n      return cloneElement(child, {\n        ...props,\n        key: key ? String(key) : undefined,\n      })\n    }\n    return child\n  })\n}\n\nexport const AgentAudioVisualizerBarElementVariants = cva(\n  [\n    \"rounded-full transition-colors duration-250 ease-linear\",\n    \"bg-current/10 data-[lk-highlighted=true]:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: \"w-[4px] min-h-[4px]\",\n        sm: \"w-[8px] min-h-[8px]\",\n        md: \"w-[16px] min-h-[16px]\",\n        lg: \"w-[32px] min-h-[32px]\",\n        xl: \"w-[64px] min-h-[64px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\nexport const AgentAudioVisualizerBarVariants = cva(\n  \"relative flex items-center justify-center\",\n  {\n    variants: {\n      size: {\n        icon: \"h-[24px] gap-[2px]\",\n        sm: \"h-[56px] gap-[4px]\",\n        md: \"h-[112px] gap-[8px]\",\n        lg: \"h-[224px] gap-[16px]\",\n        xl: \"h-[448px] gap-[32px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentAudioVisualizerBar component.\n */\nexport interface AgentAudioVisualizerBarProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the bars in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The number of bars to display in the visualizer.\n   * If not provided, defaults based on size: 3 for 'icon'/'sm', 5 for others.\n   */\n  barCount?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match barCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Custom div element to render as grid cells. Each child receives data-lk-index,\n   * data-lk-highlighted props and style props for height. Must be a single div element.\n   */\n  children?: ReactNode\n}\n\n/**\n * A bar-style audio visualizer that responds to agent state and audio levels.\n * Displays animated bars that react to the current agent state (connecting, thinking, speaking, etc.)\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerBar\n *   size=\"md\"\n *   state=\"speaking\"\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerBar({\n  size = \"md\",\n  state = \"connecting\",\n  color,\n  barCount,\n  audioTrack,\n  volumeBands,\n  className,\n  children,\n  style,\n  ...props\n}: AgentAudioVisualizerBarProps &\n  VariantProps<typeof AgentAudioVisualizerBarVariants> &\n  ComponentProps<\"div\">) {\n  const _barCount = useMemo(() => {\n    if (barCount) {\n      return barCount\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 3\n      default:\n        return 5\n    }\n  }, [barCount, size])\n\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: _barCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, _barCount)\n    : multibandVolume\n\n  const sequencerInterval = useMemo(() => {\n    switch (state) {\n      case \"connecting\":\n        return 2000 / _barCount\n      case \"initializing\":\n        return 2000\n      case \"listening\":\n        return 500\n      case \"thinking\":\n        return 150\n      default:\n        return 1000\n    }\n  }, [state, _barCount])\n\n  const highlightedIndices = useAgentAudioVisualizerBarAnimator(\n    state,\n    _barCount,\n    sequencerInterval\n  )\n\n  const bands = useMemo(\n    () =>\n      state === \"speaking\" ? resolvedVolumeBands : new Array(_barCount).fill(0),\n    [state, resolvedVolumeBands, _barCount]\n  )\n\n  if (children && Array.isArray(children)) {\n    throw new Error(\n      \"AgentAudioVisualizerBar children must be a single element.\"\n    )\n  }\n\n  return (\n    <div\n      data-lk-state={state}\n      style={{ ...style, color } as CSSProperties}\n      className={cn(AgentAudioVisualizerBarVariants({ size }), className)}\n      {...props}\n    >\n      {bands.map((band: number, idx: number) =>\n        children ? (\n          <React.Fragment key={idx}>\n            {cloneSingleChild(children, {\n              \"data-lk-index\": idx,\n              \"data-lk-highlighted\": highlightedIndices.includes(idx),\n              style: { height: `${band * 100}%` },\n            })}\n          </React.Fragment>\n        ) : (\n          <div\n            key={idx}\n            data-lk-index={idx}\n            data-lk-highlighted={highlightedIndices.includes(idx)}\n            style={{ height: `${band * 100}%` }}\n            className={cn(AgentAudioVisualizerBarElementVariants({ size }))}\n          />\n        )\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nfunction generateConnectingSequenceBar(columns: number): number[][] {\n  const seq = []\n\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, columns - 1 - x])\n  }\n\n  return seq\n}\n\nfunction generateListeningSequenceBar(columns: number): number[][] {\n  const center = Math.floor(columns / 2)\n  const noIndex = -1\n\n  return [[center], [noIndex]]\n}\n\nexport function useAgentAudioVisualizerBarAnimator(\n  state: AgentState | undefined,\n  columns: number,\n  interval: number\n): number[] {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<number[][]>([[]])\n\n  useEffect(() => {\n    if (state === \"thinking\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      const sequence = [...generateConnectingSequenceBar(columns)]\n      setSequence(sequence)\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === undefined || state === \"speaking\") {\n      setSequence([new Array(columns).fill(0).map((_, idx) => idx)])\n    } else {\n      setSequence([[]])\n    }\n    setIndex(0)\n  }, [state, columns])\n\n  const animationFrameId = useRef<number | null>(null)\n  useEffect(() => {\n    if (prefersReducedMotion || sequence.length <= 1) return\n\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        setIndex((prev) => prev + 1)\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, columns, state, sequence.length, prefersReducedMotion])\n\n  return sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? []\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-toggle.tsx",
          "target": "@components/voice-agents/livekit/agent-track-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Track } from \"livekit-client\"\nimport {\n  LoaderIcon,\n  MicIcon,\n  MicOffIcon,\n  MonitorOffIcon,\n  MonitorUpIcon,\n  VideoIcon,\n  VideoOffIcon,\n} from \"lucide-react\"\nimport { Fragment, useMemo, useState, type ComponentProps } from \"react\"\n\nexport const agentTrackToggleVariants = cva([\"size-9\"], {\n  variants: {\n    size: {\n      default: \"h-9 px-2 min-w-9\",\n      sm: \"h-8 px-1.5 min-w-8\",\n      lg: \"h-10 px-2.5 min-w-10\",\n    },\n    variant: {\n      default: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive\",\n        \"data-[state=off]:hover:bg-destructive/15\",\n        \"data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n        \"data-[state=on]:hover:bg-foreground/10\",\n      ],\n      outline: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive data-[state=off]:border-destructive/20\",\n        \"data-[state=off]:hover:bg-destructive/15 data-[state=off]:hover:text-destructive\",\n        \"data-[state=off]:focus:text-destructive\",\n        \"data-[state=off]:focus-visible:border-destructive data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:hover:bg-foreground/10 data-[state=on]:hover:border-foreground/12\",\n        \"dark:data-[state=on]:hover:bg-foreground/10\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n})\n\nfunction getSourceIcon(\n  source: Track.Source,\n  enabled: boolean,\n  pending = false\n) {\n  if (pending) {\n    return LoaderIcon\n  }\n\n  switch (source) {\n    case Track.Source.Microphone:\n      return enabled ? MicIcon : MicOffIcon\n    case Track.Source.Camera:\n      return enabled ? VideoIcon : VideoOffIcon\n    case Track.Source.ScreenShare:\n      return enabled ? MonitorUpIcon : MonitorOffIcon\n    default:\n      return Fragment\n  }\n}\n\n/**\n * Props for the AgentTrackToggle component.\n */\nexport type AgentTrackToggleProps = VariantProps<\n  typeof agentTrackToggleVariants\n> &\n  ComponentProps<\"button\"> & {\n    /**\n     * The size of the toggle.\n     */\n    size?: \"sm\" | \"default\" | \"lg\"\n    /**\n     * The variant of the toggle.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\"\n    /**\n     * The track source to toggle (Microphone, Camera, or ScreenShare).\n     */\n    source: \"camera\" | \"microphone\" | \"screen_share\"\n    /**\n     * Whether the toggle is in a pending/loading state.\n     * When true, displays a loading spinner icon.\n     * @defaultValue false\n     */\n    pending?: boolean\n    /**\n     * Whether the toggle is currently pressed/enabled.\n     * @defaultValue false\n     */\n    pressed?: boolean\n    /**\n     * The default pressed state when uncontrolled.\n     * @defaultValue false\n     */\n    defaultPressed?: boolean\n    /**\n     * Callback fired when the pressed state changes.\n     */\n    onPressedChange?: (pressed: boolean) => void\n  }\n\n/**\n * A toggle button for controlling track publishing state.\n * Displays appropriate icons based on the track source and state.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentTrackToggle\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n * />\n * ```\n */\nexport function AgentTrackToggle({\n  size = \"default\",\n  variant = \"default\",\n  source,\n  pending = false,\n  pressed,\n  defaultPressed = false,\n  className,\n  onPressedChange,\n  ...props\n}: AgentTrackToggleProps) {\n  const [uncontrolledPressed, setUncontrolledPressed] = useState(\n    defaultPressed ?? false\n  )\n  const isControlled = pressed !== undefined\n  const resolvedPressed = useMemo(\n    () => (isControlled ? pressed : uncontrolledPressed) ?? false,\n    [isControlled, pressed, uncontrolledPressed]\n  )\n  const IconComponent = getSourceIcon(\n    source as Track.Source,\n    resolvedPressed,\n    pending\n  )\n  const handlePressedChange = (nextPressed: boolean) => {\n    if (!isControlled) {\n      setUncontrolledPressed(nextPressed)\n    }\n    onPressedChange?.(nextPressed)\n  }\n\n  return (\n    <Toggle\n      size={size}\n      variant={variant}\n      pressed={isControlled ? pressed : undefined}\n      defaultPressed={isControlled ? undefined : defaultPressed}\n      aria-label={`Toggle ${source}`}\n      onPressedChange={handlePressedChange}\n      className={cn(\n        agentTrackToggleVariants({\n          size,\n          variant: variant ?? \"default\",\n          className,\n        })\n      )}\n      {...props}\n    >\n      <IconComponent className={cn(pending && \"animate-spin\")} />\n      {props.children}\n    </Toggle>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-control-bar.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-control-bar.ts",
          "type": "registry:component",
          "content": "import {\n  useLocalParticipantPermissions,\n  usePersistentUserChoices,\n  useSessionContext,\n  useTrackToggle,\n  type TrackReference,\n} from \"@livekit/components-react\"\nimport { Track } from \"livekit-client\"\nimport { useCallback } from \"react\"\n\nconst trackSourceToProtocol = (source: Track.Source) => {\n  // NOTE: this mapping avoids importing the protocol package as that leads to a significant bundle size increase\n  switch (source) {\n    case Track.Source.Camera:\n      return 1\n    case Track.Source.Microphone:\n      return 2\n    case Track.Source.ScreenShare:\n      return 3\n    default:\n      return 0\n  }\n}\n\nexport interface PublishPermissions {\n  camera: boolean\n  microphone: boolean\n  screenShare: boolean\n  data: boolean\n}\n\nexport function usePublishPermissions(): PublishPermissions {\n  const localPermissions = useLocalParticipantPermissions()\n\n  const canPublishSource = (source: Track.Source) => {\n    return (\n      !!localPermissions?.canPublish &&\n      (localPermissions.canPublishSources.length === 0 ||\n        localPermissions.canPublishSources.includes(\n          trackSourceToProtocol(source)\n        ))\n    )\n  }\n\n  return {\n    camera: canPublishSource(Track.Source.Camera),\n    microphone: canPublishSource(Track.Source.Microphone),\n    screenShare: canPublishSource(Track.Source.ScreenShare),\n    data: localPermissions?.canPublishData ?? false,\n  }\n}\n\nexport interface UseInputControlsProps {\n  saveUserChoices?: boolean\n  onDisconnect?: () => void\n  onDeviceError?: (error: { source: Track.Source; error: Error }) => void\n}\n\nexport interface UseInputControlsReturn {\n  microphoneTrack?: TrackReference\n  microphoneToggle: ReturnType<typeof useTrackToggle<Track.Source.Microphone>>\n  cameraToggle: ReturnType<typeof useTrackToggle<Track.Source.Camera>>\n  screenShareToggle: ReturnType<typeof useTrackToggle<Track.Source.ScreenShare>>\n  handleAudioDeviceChange: (deviceId: string) => void\n  handleVideoDeviceChange: (deviceId: string) => void\n  handleMicrophoneDeviceSelectError: (error: Error) => void\n  handleCameraDeviceSelectError: (error: Error) => void\n}\n\nexport function useInputControls({\n  saveUserChoices = true,\n  onDeviceError,\n}: UseInputControlsProps = {}): UseInputControlsReturn {\n  const {\n    local: { microphoneTrack },\n  } = useSessionContext()\n\n  const microphoneToggle = useTrackToggle({\n    source: Track.Source.Microphone,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.Microphone, error }),\n  })\n\n  const cameraToggle = useTrackToggle({\n    source: Track.Source.Camera,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.Camera, error }),\n  })\n\n  const screenShareToggle = useTrackToggle({\n    source: Track.Source.ScreenShare,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.ScreenShare, error }),\n  })\n\n  const {\n    saveAudioInputEnabled,\n    saveVideoInputEnabled,\n    saveAudioInputDeviceId,\n    saveVideoInputDeviceId,\n  } = usePersistentUserChoices({\n    preventLoad: !saveUserChoices,\n    preventSave: !saveUserChoices,\n  })\n\n  const handleAudioDeviceChange = useCallback(\n    (deviceId: string) => {\n      saveAudioInputDeviceId(deviceId ?? \"default\")\n    },\n    [saveAudioInputDeviceId]\n  )\n\n  const handleVideoDeviceChange = useCallback(\n    (deviceId: string) => {\n      saveVideoInputDeviceId(deviceId ?? \"default\")\n    },\n    [saveVideoInputDeviceId]\n  )\n\n  const handleToggleCamera = useCallback(\n    async (enabled?: boolean) => {\n      if (screenShareToggle.enabled) {\n        screenShareToggle.toggle(false)\n      }\n      await cameraToggle.toggle(enabled)\n      // persist video input enabled preference\n      saveVideoInputEnabled(!cameraToggle.enabled)\n    },\n    [cameraToggle, screenShareToggle, saveVideoInputEnabled]\n  )\n\n  const handleToggleMicrophone = useCallback(\n    async (enabled?: boolean) => {\n      await microphoneToggle.toggle(enabled)\n      // persist audio input enabled preference\n      saveAudioInputEnabled(!microphoneToggle.enabled)\n    },\n    [microphoneToggle, saveAudioInputEnabled]\n  )\n\n  const handleToggleScreenShare = useCallback(\n    async (enabled?: boolean) => {\n      if (cameraToggle.enabled) {\n        cameraToggle.toggle(false)\n      }\n      await screenShareToggle.toggle(enabled)\n    },\n    [cameraToggle, screenShareToggle]\n  )\n  const handleMicrophoneDeviceSelectError = useCallback(\n    (error: Error) =>\n      onDeviceError?.({ source: Track.Source.Microphone, error }),\n    [onDeviceError]\n  )\n\n  const handleCameraDeviceSelectError = useCallback(\n    (error: Error) => onDeviceError?.({ source: Track.Source.Camera, error }),\n    [onDeviceError]\n  )\n\n  return {\n    microphoneTrack,\n    cameraToggle: {\n      ...cameraToggle,\n      toggle: handleToggleCamera,\n    },\n    microphoneToggle: {\n      ...microphoneToggle,\n      toggle: handleToggleMicrophone,\n    },\n    screenShareToggle: {\n      ...screenShareToggle,\n      toggle: handleToggleScreenShare,\n    },\n    handleAudioDeviceChange,\n    handleVideoDeviceChange,\n    handleMicrophoneDeviceSelectError,\n    handleCameraDeviceSelectError,\n  }\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-audio-visualizer-bar",
      "type": "registry:block",
      "title": "Livekit Agent Audio Visualizer Bar",
      "description": "Agent Audio Visualizer Bar",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerBarAnimator } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { type LocalAudioTrack, type RemoteAudioTrack } from \"livekit-client\"\nimport React, {\n  Children,\n  cloneElement,\n  isValidElement,\n  useMemo,\n  type ComponentProps,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nfunction cloneSingleChild(\n  children: ReactNode | ReactNode[],\n  props?: Record<string, unknown>,\n  key?: unknown\n) {\n  return Children.map(children, (child) => {\n    // Checking isValidElement is the safe way and avoids a typescript error too.\n    if (isValidElement(child) && Children.only(children)) {\n      const childProps = child.props as Record<string, unknown>\n      if (childProps.className) {\n        // make sure we retain classnames of both passed props and child\n        props ??= {}\n        props.className = cn(\n          childProps.className as string,\n          props.className as string\n        )\n        props.style = {\n          ...(childProps.style as CSSProperties),\n          ...(props.style as CSSProperties),\n        }\n      }\n      return cloneElement(child, {\n        ...props,\n        key: key ? String(key) : undefined,\n      })\n    }\n    return child\n  })\n}\n\nexport const AgentAudioVisualizerBarElementVariants = cva(\n  [\n    \"rounded-full transition-colors duration-250 ease-linear\",\n    \"bg-current/10 data-[lk-highlighted=true]:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: \"w-[4px] min-h-[4px]\",\n        sm: \"w-[8px] min-h-[8px]\",\n        md: \"w-[16px] min-h-[16px]\",\n        lg: \"w-[32px] min-h-[32px]\",\n        xl: \"w-[64px] min-h-[64px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\nexport const AgentAudioVisualizerBarVariants = cva(\n  \"relative flex items-center justify-center\",\n  {\n    variants: {\n      size: {\n        icon: \"h-[24px] gap-[2px]\",\n        sm: \"h-[56px] gap-[4px]\",\n        md: \"h-[112px] gap-[8px]\",\n        lg: \"h-[224px] gap-[16px]\",\n        xl: \"h-[448px] gap-[32px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentAudioVisualizerBar component.\n */\nexport interface AgentAudioVisualizerBarProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the bars in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The number of bars to display in the visualizer.\n   * If not provided, defaults based on size: 3 for 'icon'/'sm', 5 for others.\n   */\n  barCount?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match barCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Custom div element to render as grid cells. Each child receives data-lk-index,\n   * data-lk-highlighted props and style props for height. Must be a single div element.\n   */\n  children?: ReactNode\n}\n\n/**\n * A bar-style audio visualizer that responds to agent state and audio levels.\n * Displays animated bars that react to the current agent state (connecting, thinking, speaking, etc.)\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerBar\n *   size=\"md\"\n *   state=\"speaking\"\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerBar({\n  size = \"md\",\n  state = \"connecting\",\n  color,\n  barCount,\n  audioTrack,\n  volumeBands,\n  className,\n  children,\n  style,\n  ...props\n}: AgentAudioVisualizerBarProps &\n  VariantProps<typeof AgentAudioVisualizerBarVariants> &\n  ComponentProps<\"div\">) {\n  const _barCount = useMemo(() => {\n    if (barCount) {\n      return barCount\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 3\n      default:\n        return 5\n    }\n  }, [barCount, size])\n\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: _barCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, _barCount)\n    : multibandVolume\n\n  const sequencerInterval = useMemo(() => {\n    switch (state) {\n      case \"connecting\":\n        return 2000 / _barCount\n      case \"initializing\":\n        return 2000\n      case \"listening\":\n        return 500\n      case \"thinking\":\n        return 150\n      default:\n        return 1000\n    }\n  }, [state, _barCount])\n\n  const highlightedIndices = useAgentAudioVisualizerBarAnimator(\n    state,\n    _barCount,\n    sequencerInterval\n  )\n\n  const bands = useMemo(\n    () =>\n      state === \"speaking\" ? resolvedVolumeBands : new Array(_barCount).fill(0),\n    [state, resolvedVolumeBands, _barCount]\n  )\n\n  if (children && Array.isArray(children)) {\n    throw new Error(\n      \"AgentAudioVisualizerBar children must be a single element.\"\n    )\n  }\n\n  return (\n    <div\n      data-lk-state={state}\n      style={{ ...style, color } as CSSProperties}\n      className={cn(AgentAudioVisualizerBarVariants({ size }), className)}\n      {...props}\n    >\n      {bands.map((band: number, idx: number) =>\n        children ? (\n          <React.Fragment key={idx}>\n            {cloneSingleChild(children, {\n              \"data-lk-index\": idx,\n              \"data-lk-highlighted\": highlightedIndices.includes(idx),\n              style: { height: `${band * 100}%` },\n            })}\n          </React.Fragment>\n        ) : (\n          <div\n            key={idx}\n            data-lk-index={idx}\n            data-lk-highlighted={highlightedIndices.includes(idx)}\n            style={{ height: `${band * 100}%` }}\n            className={cn(AgentAudioVisualizerBarElementVariants({ size }))}\n          />\n        )\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nfunction generateConnectingSequenceBar(columns: number): number[][] {\n  const seq = []\n\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, columns - 1 - x])\n  }\n\n  return seq\n}\n\nfunction generateListeningSequenceBar(columns: number): number[][] {\n  const center = Math.floor(columns / 2)\n  const noIndex = -1\n\n  return [[center], [noIndex]]\n}\n\nexport function useAgentAudioVisualizerBarAnimator(\n  state: AgentState | undefined,\n  columns: number,\n  interval: number\n): number[] {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<number[][]>([[]])\n\n  useEffect(() => {\n    if (state === \"thinking\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      const sequence = [...generateConnectingSequenceBar(columns)]\n      setSequence(sequence)\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === undefined || state === \"speaking\") {\n      setSequence([new Array(columns).fill(0).map((_, idx) => idx)])\n    } else {\n      setSequence([[]])\n    }\n    setIndex(0)\n  }, [state, columns])\n\n  const animationFrameId = useRef<number | null>(null)\n  useEffect(() => {\n    if (prefersReducedMotion || sequence.length <= 1) return\n\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        setIndex((prev) => prev + 1)\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, columns, state, sequence.length, prefersReducedMotion])\n\n  return sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? []\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-audio-visualizer-radial",
      "type": "registry:block",
      "title": "Livekit Agent Audio Visualizer Radial",
      "description": "Agent Audio Visualizer Radial",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-radial.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-radial.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerRadialAnimator } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { type LocalAudioTrack, type RemoteAudioTrack } from \"livekit-client\"\nimport { useMemo, type ComponentProps, type CSSProperties } from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nexport const AgentAudioVisualizerRadialVariants = cva(\n  [\n    \"relative flex items-center justify-center\",\n    \"**:data-lk-index:bg-current/10\",\n    \"**:data-lk-index:absolute **:data-lk-index:top-1/2 **:data-lk-index:left-1/2 **:data-lk-index:origin-bottom **:data-lk-index:-translate-x-1/2\",\n    \"**:data-lk-index:rounded-full **:data-lk-index:transition-colors **:data-lk-index:duration-150 **:data-lk-index:ease-linear **:data-lk-index:data-[lk-highlighted=true]:bg-current\",\n    \"has-data-[lk-state=connecting]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=initializing]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=listening]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=thinking]:animate-spin has-data-[lk-state=thinking]:[animation-duration:5s] motion-reduce:animate-none has-data-[lk-state=thinking]:**:data-lk-index:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: [\"h-[24px] gap-[2px]\"],\n        sm: [\"h-[56px] gap-[4px]\"],\n        md: [\"h-[112px] gap-[8px]\"],\n        lg: [\"h-[224px] gap-[16px]\"],\n        xl: [\"h-[448px] gap-[32px]\"],\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentAudioVisualizerRadial component.\n */\nexport interface AgentAudioVisualizerRadialProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the radial bars in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The radius (distance from center) for the radial bars.\n   * If not provided, defaults based on size.\n   */\n  radius?: number\n  /**\n   * The number of bars to display around the circle.\n   * Should be divisible by 4 for optimal visual results.\n   * If not provided, defaults to 12 for 'icon'/'sm', 24 for others.\n   */\n  barCount?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match barCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\n/**\n * A radial (circular) audio visualizer that responds to agent state and audio levels.\n * Displays animated bars arranged in a circle that react to the current agent state\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerRadial\n *   size=\"lg\"\n *   state=\"speaking\"\n *   barCount={24}\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerRadial({\n  size = \"md\",\n  state = \"connecting\",\n  color,\n  radius,\n  barCount,\n  audioTrack,\n  volumeBands,\n  className,\n  style,\n  ...props\n}: AgentAudioVisualizerRadialProps &\n  ComponentProps<\"div\"> &\n  VariantProps<typeof AgentAudioVisualizerRadialVariants>) {\n  const _barCount = useMemo(() => {\n    if (barCount) {\n      return barCount\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 12\n      default:\n        return 24\n    }\n  }, [barCount, size])\n\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: _barCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, _barCount)\n    : multibandVolume\n\n  const sequencerInterval = useMemo(() => {\n    switch (state) {\n      case \"connecting\":\n      case \"listening\":\n        return 500\n      case \"initializing\":\n        return 250\n      case \"thinking\":\n        return Infinity\n      default:\n        return 1000\n    }\n  }, [state])\n\n  const distanceFromCenter = useMemo(() => {\n    if (radius) {\n      return radius\n    }\n    switch (size) {\n      case \"icon\":\n        return 6\n      case \"xl\":\n        return 128\n      case \"lg\":\n        return 64\n      case \"sm\":\n        return 16\n      case \"md\":\n      default:\n        return 32\n    }\n  }, [size, radius])\n\n  if (_barCount % 4 !== 0) {\n    console.warn(\"barCount should be divisible by 4 for optimal visual results\")\n  }\n\n  const highlightedIndices = useAgentAudioVisualizerRadialAnimator(\n    state,\n    _barCount,\n    sequencerInterval\n  )\n\n  const dotSize = useMemo(() => {\n    return (distanceFromCenter * Math.PI) / _barCount\n  }, [distanceFromCenter, _barCount])\n\n  return (\n    <div\n      data-lk-state={state}\n      className={cn(\n        AgentAudioVisualizerRadialVariants({ size }),\n        \"relative\",\n        className\n      )}\n      style={{ ...style, color } as CSSProperties}\n      {...props}\n    >\n      {resolvedVolumeBands.map((band, idx) => {\n        const angle = (idx / _barCount) * Math.PI * 2\n\n        return (\n          <div\n            key={`${_barCount}-${idx}`}\n            data-lk-state={state}\n            className=\"absolute top-1/2 left-1/2 h-1 w-1 -translate-x-1/2 -translate-y-1/2\"\n            style={{\n              transformOrigin: \"center\",\n              transform: `rotate(${angle}rad) translateY(${distanceFromCenter}px)`,\n            }}\n          >\n            <div\n              data-lk-index={idx}\n              data-lk-highlighted={highlightedIndices.includes(idx)}\n              style={{\n                width: dotSize,\n                minHeight: dotSize,\n                height: state === \"speaking\" ? `${dotSize * 10 * band}px` : 0,\n              }}\n            />\n          </div>\n        )\n      })}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nfunction findGcdLessThan(columns: number, max: number = columns): number {\n  function gcd(a: number, b: number): number {\n    while (b !== 0) {\n      const t = b\n      b = a % b\n      a = t\n    }\n    return a\n  }\n  for (let i = max; i >= 1; i--) {\n    if (gcd(columns, i) === i) {\n      return i\n    }\n  }\n  return 1\n}\n\nfunction generateConnectingSequenceBar(columns: number): number[][] {\n  const seq = []\n  const center = Math.floor(columns / 2)\n\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, (x + center) % columns])\n  }\n\n  return seq\n}\n\nfunction generateListeningSequenceBar(columns: number): number[][] {\n  const divisor =\n    columns > 8\n      ? columns / findGcdLessThan(columns, 4)\n      : findGcdLessThan(columns, 2)\n\n  return Array.from({ length: divisor }, (_, idx) => [\n    ...Array(Math.floor(columns / divisor))\n      .fill(1)\n      .map((_, idx2) => idx2 * divisor + idx),\n  ])\n}\n\nexport const useAgentAudioVisualizerRadialAnimator = (\n  state: AgentState | undefined,\n  barCount: number,\n  interval: number\n): number[] => {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<number[][]>([[]])\n\n  useEffect(() => {\n    if (state === \"thinking\") {\n      setSequence(generateListeningSequenceBar(barCount))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      setSequence(generateConnectingSequenceBar(barCount))\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequenceBar(barCount))\n    } else if (state === undefined || state === \"speaking\") {\n      setSequence([new Array(barCount).fill(0).map((_, idx) => idx)])\n    } else {\n      setSequence([[]])\n    }\n    setIndex(0)\n  }, [state, barCount])\n\n  const animationFrameId = useRef<number | null>(null)\n  useEffect(() => {\n    if (\n      prefersReducedMotion ||\n      sequence.length <= 1 ||\n      !Number.isFinite(interval)\n    )\n      return\n\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        setIndex((prev) => prev + 1)\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, barCount, state, sequence.length, prefersReducedMotion])\n\n  return sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? []\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-audio-visualizer-grid",
      "type": "registry:block",
      "title": "Livekit Agent Audio Visualizer Grid",
      "description": "Agent Audio Visualizer Grid",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-grid.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-grid.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  useAgentAudioVisualizerGridAnimator,\n  type Coordinate,\n} from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport type { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport React, {\n  Children,\n  cloneElement,\n  isValidElement,\n  memo,\n  useMemo,\n  type ComponentProps,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nfunction cloneSingleChild(\n  children: ReactNode | ReactNode[],\n  props?: Record<string, unknown>,\n  key?: unknown\n) {\n  return Children.map(children, (child) => {\n    // Checking isValidElement is the safe way and avoids a typescript error too.\n    if (isValidElement(child) && Children.only(children)) {\n      const childProps = child.props as Record<string, unknown>\n      if (childProps.className) {\n        // make sure we retain classnames of both passed props and child\n        props ??= {}\n        props.className = cn(\n          childProps.className as string,\n          props.className as string\n        )\n        props.style = {\n          ...(childProps.style as CSSProperties),\n          ...(props.style as CSSProperties),\n        }\n      }\n      return cloneElement(child, {\n        ...props,\n        key: key ? String(key) : undefined,\n      })\n    }\n    return child\n  })\n}\n\nexport const AgentAudioVisualizerGridCellVariants = cva(\n  [\n    \"w-1 h-1 rounded-full bg-current/10 place-self-center transition-all ease-out\",\n    \"data-[lk-highlighted=true]:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: [\"w-[2px] h-[2px]\"],\n        sm: [\"w-[4px] h-[4px]\"],\n        md: [\"w-[8px] h-[8px]\"],\n        lg: [\"w-[12px] h-[12px]\"],\n        xl: [\"w-[16px] h-[16px]\"],\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\nexport const AgentAudioVisualizerGridVariants = cva(\"grid\", {\n  variants: {\n    size: {\n      icon: [\"gap-[2px]\"],\n      sm: [\"gap-[4px]\"],\n      md: [\"gap-[8px]\"],\n      lg: [\"gap-[12px]\"],\n      xl: [\"gap-[16px]\"],\n    },\n  },\n  defaultVariants: {\n    size: \"md\",\n  },\n})\n\n/**\n * Configuration options for the grid visualizer.\n */\nexport interface GridOptions {\n  /**\n   * The radius for the animation spread effect.\n   */\n  radius?: number\n  /**\n   * The interval in milliseconds between animation frames.\n   * @defaultValue 100\n   */\n  interval?: number\n  /**\n   * The number of rows in the grid.\n   * @defaultValue 5\n   */\n  rowCount?: number\n  /**\n   * The number of columns in the grid.\n   * @defaultValue 5\n   */\n  columnCount?: number\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\nconst sizeDefaults = {\n  icon: 3,\n  sm: 5,\n  md: 5,\n  lg: 5,\n  xl: 5,\n}\n\nfunction useGrid(\n  size: VariantProps<typeof AgentAudioVisualizerGridVariants>[\"size\"] = \"md\",\n  columnCount = sizeDefaults[size as keyof typeof sizeDefaults],\n  rowCount = sizeDefaults[size as keyof typeof sizeDefaults]\n) {\n  return useMemo(() => {\n    const _columnCount = columnCount\n    const _rowCount = rowCount ?? columnCount\n    const items = new Array(_columnCount * _rowCount)\n      .fill(0)\n      .map((_, idx) => idx)\n\n    return { columnCount: _columnCount, rowCount: _rowCount, items }\n  }, [columnCount, rowCount])\n}\n\ninterface GridCellProps {\n  index: number\n  state: AgentState\n  interval: number\n  rowCount: number\n  columnCount: number\n  volumeBands: number[]\n  highlightedCoordinate: Coordinate\n  children?: ReactNode\n}\n\nconst GridCell = memo(function GridCell({\n  index,\n  state,\n  interval,\n  rowCount,\n  columnCount,\n  volumeBands,\n  highlightedCoordinate,\n  children,\n}: GridCellProps) {\n  if (state === \"speaking\") {\n    const y = Math.floor(index / columnCount)\n    const rowMidPoint = Math.floor(rowCount / 2)\n    const volumeChunks = 1 / (rowMidPoint + 1)\n    const distanceToMid = Math.abs(rowMidPoint - y)\n    const threshold = distanceToMid * volumeChunks\n    const isHighlighted = (volumeBands[index % columnCount] ?? 0) >= threshold\n\n    return cloneSingleChild(children, {\n      \"data-lk-index\": index,\n      \"data-lk-highlighted\": isHighlighted,\n    })\n  }\n\n  const isHighlighted =\n    highlightedCoordinate.x === index % columnCount &&\n    highlightedCoordinate.y === Math.floor(index / columnCount)\n\n  const transitionDurationInSeconds = interval / (isHighlighted ? 1000 : 100)\n\n  return cloneSingleChild(children, {\n    \"data-lk-index\": index,\n    \"data-lk-highlighted\": isHighlighted,\n    style: {\n      transitionDuration: `${transitionDurationInSeconds}s`,\n    },\n  })\n})\n\n/**\n * Props for the AgentAudioVisualizerGrid component.\n */\nexport type AgentAudioVisualizerGridProps = GridOptions & {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the grid cells in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match columnCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Custom element to render as grid cells. Each child receives data-lk-index\n   * and data-lk-highlighted props.\n   */\n  children?: ReactNode\n} & VariantProps<typeof AgentAudioVisualizerGridVariants>\n\n/**\n * A grid-style audio visualizer that responds to agent state and audio levels.\n * Displays an animated grid of cells that react to the current agent state\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerGrid\n *   size=\"md\"\n *   state=\"speaking\"\n *   rowCount={5}\n *   columnCount={5}\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerGrid({\n  size = \"md\",\n  state = \"connecting\",\n  radius,\n  color,\n  rowCount: _rowCount = 5,\n  columnCount: _columnCount = 5,\n  interval = 100,\n  className,\n  children,\n  audioTrack,\n  volumeBands,\n  style,\n  ...props\n}: AgentAudioVisualizerGridProps & ComponentProps<\"div\">) {\n  const { columnCount, rowCount, items } = useGrid(\n    size,\n    _columnCount,\n    _rowCount\n  )\n  const highlightedCoordinate = useAgentAudioVisualizerGridAnimator(\n    state,\n    rowCount,\n    columnCount,\n    interval,\n    radius\n  )\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: columnCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, columnCount)\n    : multibandVolume\n\n  if (children && Array.isArray(children)) {\n    throw new Error(\n      \"AgentAudioVisualizerGrid children must be a single element.\"\n    )\n  }\n\n  return (\n    <div\n      data-lk-state={state}\n      className={cn(AgentAudioVisualizerGridVariants({ size }), className)}\n      style={\n        {\n          ...style,\n          gridTemplateColumns: `repeat(${columnCount}, 1fr)`,\n          color,\n        } as CSSProperties\n      }\n      {...props}\n    >\n      {items.map((idx) => (\n        <GridCell\n          key={idx}\n          index={idx}\n          state={state}\n          interval={interval}\n          rowCount={rowCount}\n          columnCount={columnCount}\n          volumeBands={resolvedVolumeBands}\n          highlightedCoordinate={highlightedCoordinate}\n        >\n          {children ?? (\n            <div className={AgentAudioVisualizerGridCellVariants({ size })} />\n          )}\n        </GridCell>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useState } from \"react\"\n\nexport interface Coordinate {\n  x: number\n  y: number\n}\n\nexport function generateConnectingSequence(\n  rows: number,\n  columns: number,\n  radius: number\n) {\n  const seq = []\n  const centerY = Math.floor(rows / 2)\n\n  // Calculate the boundaries of the ring based on the ring distance\n  const topLeft = {\n    x: Math.max(0, centerY - radius),\n    y: Math.max(0, centerY - radius),\n  }\n  const bottomRight = {\n    x: columns - 1 - topLeft.x,\n    y: Math.min(rows - 1, centerY + radius),\n  }\n\n  // Top edge\n  for (let x = topLeft.x; x <= bottomRight.x; x++) {\n    seq.push({ x, y: topLeft.y })\n  }\n\n  // Right edge\n  for (let y = topLeft.y + 1; y <= bottomRight.y; y++) {\n    seq.push({ x: bottomRight.x, y })\n  }\n\n  // Bottom edge\n  for (let x = bottomRight.x - 1; x >= topLeft.x; x--) {\n    seq.push({ x, y: bottomRight.y })\n  }\n\n  // Left edge\n  for (let y = bottomRight.y - 1; y > topLeft.y; y--) {\n    seq.push({ x: topLeft.x, y })\n  }\n\n  return seq\n}\n\nexport function generateListeningSequence(rows: number, columns: number) {\n  const center = { x: Math.floor(columns / 2), y: Math.floor(rows / 2) }\n  const noIndex = { x: -1, y: -1 }\n\n  return [\n    center,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n  ]\n}\n\nexport function generateThinkingSequence(rows: number, columns: number) {\n  const seq = []\n  const y = Math.floor(rows / 2)\n  for (let x = 0; x < columns; x++) {\n    seq.push({ x, y })\n  }\n  for (let x = columns - 1; x >= 0; x--) {\n    seq.push({ x, y })\n  }\n\n  return seq\n}\n\nexport function useAgentAudioVisualizerGridAnimator(\n  state: AgentState,\n  rows: number,\n  columns: number,\n  interval: number,\n  radius?: number\n): Coordinate {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<Coordinate[]>(() => [\n    {\n      x: Math.floor(columns / 2),\n      y: Math.floor(rows / 2),\n    },\n  ])\n\n  useEffect(() => {\n    const clampedRadius = radius\n      ? Math.min(radius, Math.floor(Math.max(rows, columns) / 2))\n      : Math.floor(Math.max(rows, columns) / 2)\n\n    if (state === \"thinking\") {\n      setSequence(generateThinkingSequence(rows, columns))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      const sequence = [\n        ...generateConnectingSequence(rows, columns, clampedRadius),\n      ]\n      setSequence(sequence)\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequence(rows, columns))\n    } else {\n      setSequence([{ x: Math.floor(columns / 2), y: Math.floor(rows / 2) }])\n    }\n    setIndex(0)\n  }, [state, rows, columns, radius])\n\n  useEffect(() => {\n    if (state === \"speaking\" || prefersReducedMotion) {\n      return\n    }\n\n    const indexInterval = setInterval(() => {\n      setIndex((prev) => {\n        return prev + 1\n      })\n    }, interval)\n\n    return () => clearInterval(indexInterval)\n  }, [interval, columns, rows, state, sequence.length, prefersReducedMotion])\n\n  return (\n    sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? {\n      x: Math.floor(columns / 2),\n      y: Math.floor(rows / 2),\n    }\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-session-provider",
      "type": "registry:block",
      "title": "Livekit Agent Session Provider",
      "description": "Agent Session Provider",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "livekit-client@2.22.3",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-session-provider.tsx",
          "target": "@components/voice-agents/livekit/agent-session-provider.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  RoomAudioRenderer,\n  SessionProvider,\n  type RoomAudioRendererProps,\n  type SessionProviderProps,\n  type UseSessionReturn,\n} from \"@livekit/components-react\"\nimport { type Room } from \"livekit-client\"\n\n/**\n * Props for the AgentSessionProvider component.\n * Combines SessionProviderProps with RoomAudioRendererProps.\n */\nexport type AgentSessionProviderProps = SessionProviderProps &\n  RoomAudioRendererProps & {\n    /**\n     * The room to provide.\n     */\n    room?: Room\n    /**\n     * The volume to set for the audio renderer.\n     */\n    volume?: number\n    /**\n     * Whether to mute the audio renderer.\n     */\n    muted?: boolean\n    /**\n     * The session to provide.\n     */\n    session: UseSessionReturn\n    /**\n     * The children to render.\n     */\n    children: React.ReactNode\n  }\n\n/**\n * A provider component for agent sessions that wraps SessionProvider\n * and includes RoomAudioRenderer for audio playback.\n *\n * @example\n * ```tsx\n * <AgentSessionProvider session={agentSession}>\n *   <AgentControlBar />\n *   <AgentChatTranscript />\n * </AgentSessionProvider>\n * ```\n */\nexport function AgentSessionProvider({\n  session,\n  children,\n  ...roomAudioRendererProps\n}: AgentSessionProviderProps) {\n  return (\n    <SessionProvider session={session}>\n      {children}\n      <RoomAudioRenderer {...roomAudioRendererProps} />\n    </SessionProvider>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-start-audio-button",
      "type": "registry:block",
      "title": "Livekit Start Audio Button",
      "description": "Start Audio Button",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/start-audio-button.tsx",
          "target": "@components/voice-agents/livekit/start-audio-button.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/voice-agents/livekit/_ui/button\"\nimport { useEnsureRoom, useStartAudio } from \"@livekit/components-react\"\nimport { type Room } from \"livekit-client\"\nimport { type ComponentProps } from \"react\"\n\n/**\n * Props for the StartAudioButton component.\n */\nexport interface StartAudioButtonProps extends ComponentProps<\"button\"> {\n  /**\n   * The size of the button.\n   * @defaultValue 'default'\n   */\n  size?: \"default\" | \"sm\" | \"lg\" | \"icon\" | \"icon-sm\" | \"icon-lg\"\n  /**\n   * The variant of the button.\n   * @defaultValue 'default'\n   */\n  variant?:\n    | \"default\"\n    | \"destructive\"\n    | \"outline\"\n    | \"secondary\"\n    | \"ghost\"\n    | \"link\"\n  /**\n   * The LiveKit room instance. If not provided, uses the room from context.\n   */\n  room?: Room\n  /**\n   * The label text to display on the button.\n   */\n  label: string\n}\n\n/**\n * A button that allows users to start audio playback.\n * Required for browsers that block autoplay of audio.\n * Only renders when audio playback is blocked.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <StartAudioButton label=\"Click to allow audio playback\" />\n * ```\n */\nexport function StartAudioButton({\n  size = \"default\",\n  variant = \"default\",\n  label,\n  room,\n  className,\n  ...props\n}: StartAudioButtonProps) {\n  const roomEnsured = useEnsureRoom(room)\n  const { mergedProps } = useStartAudio({ room: roomEnsured, props })\n\n  return (\n    <Button\n      size={size}\n      variant={variant}\n      {...props}\n      {...mergedProps}\n      // don't merge useStartAudio className\n      className={className}\n    >\n      {label}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/button.tsx",
          "target": "@components/voice-agents/livekit/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-chat-indicator",
      "type": "registry:block",
      "title": "Livekit Agent Chat Indicator",
      "description": "Agent Chat Indicator",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-chat-indicator.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-indicator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { motion, useReducedMotion, type MotionProps } from \"motion/react\"\nimport { type ComponentProps, type Ref } from \"react\"\n\nconst motionAnimationProps = {\n  variants: {\n    hidden: {\n      opacity: 0,\n      scale: 0.1,\n      transition: {\n        duration: 0.1,\n        ease: \"linear\" as const,\n      },\n    },\n    visible: {\n      opacity: [0.5, 1],\n      scale: [0.9, 1],\n      transition: {\n        type: \"spring\" as const,\n        bounce: 0,\n        duration: 0.5,\n        repeat: Infinity,\n        repeatType: \"mirror\" as const,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\nconst agentChatIndicatorVariants = cva(\n  \"bg-muted-foreground inline-block size-2.5 rounded-full\",\n  {\n    variants: {\n      size: {\n        sm: \"size-3\",\n        md: \"size-4\",\n        lg: \"size-6\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentChatIndicator component.\n */\nexport interface AgentChatIndicatorProps extends MotionProps {\n  /**\n   * The size of the indicator dot.\n   * @defaultValue 'md'\n   */\n  size?: \"sm\" | \"md\" | \"lg\"\n  /**\n   * Additional CSS class names to apply to the indicator.\n   */\n  className?: string\n  /**\n   * Allows getting a ref to the component instance.\\nOnce the component unmounts, React will set `ref.current` to `null`\\n(or call the ref with `null` if you passed a callback ref).\\n@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}\n   */\n  ref?: Ref<HTMLSpanElement>\n}\n\n/**\n * An animated indicator that shows the agent is processing or thinking.\n * Displays as a pulsing dot, typically used in chat interfaces.\n *\n * @extends ComponentProps<'span'>\n *\n * @example\n * ```tsx\n * {agentState === 'thinking' && <AgentChatIndicator size=\"md\" />}\n * ```\n */\nexport function AgentChatIndicator({\n  size = \"md\",\n  className,\n  ...props\n}: AgentChatIndicatorProps &\n  ComponentProps<\"span\"> &\n  VariantProps<typeof agentChatIndicatorVariants>) {\n  const prefersReducedMotion = useReducedMotion()\n\n  return (\n    <motion.span\n      {...(prefersReducedMotion\n        ? { initial: false, animate: { opacity: 1, scale: 1 } }\n        : motionAnimationProps)}\n      transition={{ duration: 0.1, ease: \"linear\" as const }}\n      className={cn(agentChatIndicatorVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-chat-transcript",
      "type": "registry:block",
      "title": "Livekit Agent Chat Transcript",
      "description": "Agent Chat Transcript",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "radix-ui@1.6.7",
        "streamdown@2.4.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-chat-transcript.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-transcript.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Bubble,\n  BubbleContent,\n} from \"@/components/voice-agents/livekit/_ui/bubble\"\nimport {\n  Marker,\n  MarkerContent,\n  MarkerIcon,\n} from \"@/components/voice-agents/livekit/_ui/marker\"\nimport {\n  Message,\n  MessageContent,\n} from \"@/components/voice-agents/livekit/_ui/message\"\nimport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n} from \"@/components/voice-agents/livekit/_ui/message-scroller\"\nimport { AgentChatIndicator } from \"@/components/voice-agents/livekit/agent-chat-indicator\"\nimport {\n  type AgentState,\n  type ReceivedMessage,\n} from \"@livekit/components-react\"\nimport { type ComponentProps } from \"react\"\nimport { Streamdown } from \"streamdown\"\n\n/**\n * Props for the AgentChatTranscript component.\n */\nexport interface AgentChatTranscriptProps\n  extends ComponentProps<\"div\">,\n    ComponentProps<typeof MessageScrollerProvider>,\n    ComponentProps<typeof MessageScrollerViewport>,\n    ComponentProps<typeof MessageScrollerContent> {\n  /**\n   * Whether to automatically scroll to the bottom of the transcript when new messages are added.\n   * @defaultValue true\n   */\n  autoScroll?: boolean\n  /**\n   * The scroll anchor to use when auto-scrolling.\n   * @defaultValue false\n   */\n  scrollAnchor?: boolean | \"user\" | \"other\" | \"any\"\n  /**\n   * The scroll button render function\n   */\n  scrollButtonRender?: ComponentProps<typeof MessageScrollerButton>[\"render\"]\n  /**\n   * The scroll button behavior\n   */\n  scrollButtonBehavior?: ComponentProps<\n    typeof MessageScrollerButton\n  >[\"behavior\"]\n  /**\n   * The scroll button direction\n   */\n  scrollButtonDirection?: ComponentProps<\n    typeof MessageScrollerButton\n  >[\"direction\"]\n  /**\n   * The current state of the agent. When 'thinking', displays a loading indicator.\n   */\n  agentState?: AgentState\n  /**\n   * Array of messages to display in the transcript.\n   * @defaultValue []\n   */\n  messages?: ReceivedMessage[]\n  /**\n   * Additional CSS class names to apply to the conversation container.\n   */\n  className?: string\n}\n\n/**\n * A chat transcript component that displays a conversation between the user and agent.\n * Shows messages with timestamps and origin indicators, plus a thinking indicator\n * when the agent is processing.\n *\n * @extends ComponentProps<'div'>, ComponentProps<typeof MessageScrollerProvider>, ComponentProps<typeof MessageScrollerViewport>, ComponentProps<typeof MessageScrollerContent>\n *\n *\n * @example\n * ```tsx\n * <AgentChatTranscript\n *   agentState={agentState}\n *   messages={chatMessages}\n * />\n * ```\n */\nexport function AgentChatTranscript({\n  scrollAnchor,\n  autoScroll = true,\n  scrollMargin,\n  scrollEdgeThreshold,\n  preserveScrollOnPrepend,\n  scrollPreviousItemPeek,\n  defaultScrollPosition = \"last-anchor\",\n  scrollButtonRender,\n  scrollButtonBehavior,\n  scrollButtonDirection,\n  spacerClassName,\n  agentState,\n  messages = [],\n  className,\n  ...props\n}: AgentChatTranscriptProps) {\n  return (\n    <MessageScrollerProvider\n      autoScroll={autoScroll}\n      scrollMargin={scrollMargin}\n      defaultScrollPosition={defaultScrollPosition}\n      scrollEdgeThreshold={scrollEdgeThreshold}\n      scrollPreviousItemPeek={scrollPreviousItemPeek}\n    >\n      <MessageScroller className={className} {...props}>\n        <MessageScrollerViewport\n          preserveScrollOnPrepend={preserveScrollOnPrepend}\n        >\n          <MessageScrollerContent\n            spacerClassName={spacerClassName}\n            aria-busy={agentState === \"thinking\"}\n          >\n            {messages.map((receivedMessage) => {\n              const { id, timestamp, from, message } = receivedMessage\n              const time = new Date(timestamp)\n              const isUser = from?.isLocal\n              const locale =\n                typeof navigator !== \"undefined\" ? navigator.language : \"en-US\"\n              const title = time.toLocaleTimeString(locale, {\n                timeStyle: \"full\",\n              })\n              let _scrollAnchor = false\n\n              if (\n                scrollAnchor === \"any\" ||\n                (scrollAnchor === \"user\" && isUser) ||\n                (scrollAnchor === \"other\" && !isUser)\n              ) {\n                _scrollAnchor = true\n              }\n\n              return (\n                <MessageScrollerItem\n                  key={id}\n                  messageId={id}\n                  scrollAnchor={_scrollAnchor}\n                >\n                  <Message align={isUser ? \"end\" : \"start\"} title={title}>\n                    <MessageContent>\n                      <Bubble\n                        align={isUser ? \"end\" : \"start\"}\n                        variant={isUser ? \"secondary\" : \"ghost\"}\n                      >\n                        <BubbleContent>\n                          <Streamdown>{message}</Streamdown>\n                        </BubbleContent>\n                      </Bubble>\n                    </MessageContent>\n                  </Message>\n                </MessageScrollerItem>\n              )\n            })}\n\n            {/* Agent is thinking indicator */}\n            {agentState === \"thinking\" && (\n              <MessageScrollerItem>\n                <Marker role=\"status\">\n                  <MarkerIcon>\n                    <AgentChatIndicator size=\"sm\" />\n                  </MarkerIcon>\n                  <MarkerContent className=\"shimmer\">Thinking...</MarkerContent>\n                </Marker>\n              </MessageScrollerItem>\n            )}\n          </MessageScrollerContent>\n        </MessageScrollerViewport>\n\n        {/* Scroll to bottom button */}\n        <MessageScrollerButton\n          variant=\"outline\"\n          className=\"rounded-full\"\n          render={scrollButtonRender}\n          behavior={scrollButtonBehavior}\n          direction={scrollButtonDirection}\n        />\n      </MessageScroller>\n    </MessageScrollerProvider>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/bubble.tsx",
          "target": "@components/voice-agents/livekit/_ui/bubble.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction BubbleGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"bubble-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nconst bubbleVariants = cva(\n  \"group/bubble relative flex w-fit max-w-[80%] min-w-0 flex-col gap-1 group-data-[align=end]/message:self-end data-[align=end]:self-end data-[variant=ghost]:max-w-full\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80\",\n        secondary:\n          \"*:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]\",\n        muted:\n          \"*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]\",\n        tinted:\n          \"*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]\",\n        outline:\n          \"*:data-[slot=bubble-content]:border-border *:data-[slot=bubble-content]:bg-background [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30\",\n        ghost:\n          \"border-none *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50\",\n        destructive:\n          \"*:data-[slot=bubble-content]:bg-destructive/10 *:data-[slot=bubble-content]:text-destructive dark:*:data-[slot=bubble-content]:bg-destructive/20 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Bubble({\n  variant = \"default\",\n  align = \"start\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof bubbleVariants> & {\n    align?: \"start\" | \"end\"\n  }) {\n  return (\n    <div\n      data-slot=\"bubble\"\n      data-variant={variant}\n      data-align={align}\n      className={cn(bubbleVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BubbleContent({\n  asChild = false,\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  asChild?: boolean\n}) {\n  const Comp = asChild ? Slot.Root : \"div\"\n\n  return (\n    <Comp\n      data-slot=\"bubble-content\"\n      className={cn(\n        \"[button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-ring/50 w-fit max-w-full min-w-0 overflow-hidden rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed wrap-break-word group-data-[align=end]/bubble:self-end [button]:text-left [button,a]:transition-colors [button,a]:outline-none [button,a]:focus-visible:ring-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst bubbleReactionsVariants = cva(\n  \"absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm ring-3 ring-card has-[button]:p-0\",\n  {\n    variants: {\n      side: {\n        top: \"top-0 -translate-y-3/4\",\n        bottom: \"bottom-0 translate-y-3/4\",\n      },\n      align: {\n        start: \"left-3\",\n        end: \"right-3\",\n      },\n    },\n    defaultVariants: {\n      side: \"bottom\",\n      align: \"end\",\n    },\n  }\n)\n\nfunction BubbleReactions({\n  side = \"bottom\",\n  align = \"end\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  align?: \"start\" | \"end\"\n  side?: \"top\" | \"bottom\"\n}) {\n  return (\n    <div\n      data-slot=\"bubble-reactions\"\n      data-align={align}\n      data-side={side}\n      className={cn(bubbleReactionsVariants({ side, align }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { BubbleGroup, Bubble, BubbleContent, BubbleReactions }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/marker.tsx",
          "target": "@components/voice-agents/livekit/_ui/marker.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst markerVariants = cva(\n  \"group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground\",\n  {\n    variants: {\n      variant: {\n        default: \"\",\n        separator:\n          \"before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border\",\n        border: \"border-b border-border pb-2\",\n      },\n    },\n  }\n)\n\nfunction Marker({\n  className,\n  variant = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof markerVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"div\"\n\n  return (\n    <Comp\n      data-slot=\"marker\"\n      data-variant={variant}\n      className={cn(markerVariants({ variant, className }))}\n      {...props}\n    />\n  )\n}\n\nfunction MarkerIcon({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"marker-icon\"\n      aria-hidden=\"true\"\n      className={cn(\n        \"size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MarkerContent({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"marker-content\"\n      className={cn(\n        \"*:[a]:hover:text-foreground min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Marker, MarkerIcon, MarkerContent, markerVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/message.tsx",
          "target": "@components/voice-agents/livekit/_ui/message.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction MessageGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction Message({\n  className,\n  align = \"start\",\n  ...props\n}: React.ComponentProps<\"div\"> & { align?: \"start\" | \"end\" }) {\n  return (\n    <div\n      data-slot=\"message\"\n      data-align={align}\n      className={cn(\n        \"group/message relative flex w-full min-w-0 gap-2 text-sm data-[align=end]:flex-row-reverse\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageAvatar({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-avatar\"\n      className={cn(\n        \"bg-muted flex w-fit min-w-8 shrink-0 items-center justify-center self-end overflow-hidden rounded-full group-has-data-[slot=message-footer]/message:-translate-y-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-content\"\n      className={cn(\n        \"flex w-full min-w-0 flex-col gap-2.5 wrap-break-word group-data-[align=end]/message:*:data-slot:self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-header\"\n      className={cn(\n        \"text-muted-foreground flex max-w-full min-w-0 items-center px-3 text-xs font-medium group-has-data-[variant=ghost]/message:px-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-footer\"\n      className={cn(\n        \"text-muted-foreground flex max-w-full min-w-0 items-center px-3 text-xs font-medium group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  MessageGroup,\n  Message,\n  MessageAvatar,\n  MessageContent,\n  MessageFooter,\n  MessageHeader,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/message-scroller.tsx",
          "target": "@components/voice-agents/livekit/_ui/message-scroller.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ArrowDownIcon } from \"lucide-react\"\nimport * as React from \"react\"\nimport { Button } from \"./button\"\n\ntype ScrollerContextValue = {\n  autoScroll: boolean\n  atEnd: boolean\n  atEndRef: React.RefObject<boolean>\n  atStart: boolean\n  defaultScrollPosition: \"first\" | \"last\" | \"last-anchor\"\n  scrollEdgeThreshold: number\n  scrollMargin: number\n  scrollPreviousItemPeek: number\n  setAtEnd: (atEnd: boolean) => void\n  setAtStart: (atStart: boolean) => void\n  viewportRef: React.RefObject<HTMLDivElement | null>\n}\n\nconst ScrollerContext = React.createContext<ScrollerContextValue | null>(null)\n\nexport interface MessageScrollerProviderProps {\n  children?: React.ReactNode\n  autoScroll?: boolean\n  scrollMargin?: number\n  defaultScrollPosition?: \"first\" | \"last\" | \"last-anchor\"\n  scrollEdgeThreshold?: number\n  scrollPreviousItemPeek?: number\n}\n\nfunction MessageScrollerProvider({\n  children,\n  autoScroll = true,\n  defaultScrollPosition = \"last-anchor\",\n  scrollEdgeThreshold = 8,\n  scrollMargin = 0,\n  scrollPreviousItemPeek = 0,\n}: MessageScrollerProviderProps) {\n  const viewportRef = React.useRef<HTMLDivElement>(null)\n  const atEndRef = React.useRef(true)\n  const [atEnd, setAtEnd] = React.useState(true)\n  const [atStart, setAtStart] = React.useState(true)\n  const updateAtEnd = React.useCallback((nextAtEnd: boolean) => {\n    atEndRef.current = nextAtEnd\n    setAtEnd(nextAtEnd)\n  }, [])\n  return (\n    <ScrollerContext.Provider\n      value={{\n        autoScroll,\n        atEnd,\n        atEndRef,\n        atStart,\n        defaultScrollPosition,\n        scrollEdgeThreshold,\n        scrollMargin,\n        scrollPreviousItemPeek,\n        setAtEnd: updateAtEnd,\n        setAtStart,\n        viewportRef,\n      }}\n    >\n      {children}\n    </ScrollerContext.Provider>\n  )\n}\n\nfunction useScroller() {\n  const context = React.useContext(ScrollerContext)\n  if (!context) {\n    throw new Error(\n      \"MessageScroller components require MessageScrollerProvider\"\n    )\n  }\n  return context\n}\n\nfunction MessageScroller({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-scroller\"\n      className={cn(\n        \"group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageScrollerViewport({\n  className,\n  preserveScrollOnPrepend = false,\n  onScroll,\n  style,\n  ...props\n}: React.ComponentProps<\"div\"> & { preserveScrollOnPrepend?: boolean }) {\n  const {\n    atEndRef,\n    autoScroll,\n    defaultScrollPosition,\n    scrollEdgeThreshold,\n    scrollMargin,\n    scrollPreviousItemPeek,\n    setAtEnd,\n    setAtStart,\n    viewportRef,\n  } = useScroller()\n\n  React.useLayoutEffect(() => {\n    const viewport = viewportRef.current\n    if (!viewport) return\n    const update = () => {\n      const atEnd =\n        viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <=\n        scrollEdgeThreshold\n      setAtEnd(atEnd)\n      setAtStart(viewport.scrollTop <= scrollEdgeThreshold)\n    }\n    if (defaultScrollPosition === \"last-anchor\") {\n      const anchors = viewport.querySelectorAll<HTMLElement>(\n        '[data-scroll-anchor=\"true\"]'\n      )\n      const anchor = anchors.item(anchors.length - 1)\n      if (anchor) anchor.scrollIntoView({ block: \"end\" })\n      else viewport.scrollTop = viewport.scrollHeight\n    } else if (defaultScrollPosition === \"last\") {\n      viewport.scrollTop = viewport.scrollHeight\n    }\n    let previousScrollHeight = viewport.scrollHeight\n    const observer = new MutationObserver((records) => {\n      const nextScrollHeight = viewport.scrollHeight\n      const prepended = records.some(\n        (record) =>\n          record.type === \"childList\" &&\n          record.addedNodes.length > 0 &&\n          (record.previousSibling === null ||\n            (record.previousSibling instanceof HTMLElement &&\n              record.previousSibling.dataset.slot ===\n                \"message-scroller-spacer\"))\n      )\n      if (preserveScrollOnPrepend && prepended) {\n        viewport.scrollTop += nextScrollHeight - previousScrollHeight\n      } else if (autoScroll && atEndRef.current) {\n        viewport.scrollTo({ top: nextScrollHeight })\n      }\n      previousScrollHeight = nextScrollHeight\n      update()\n    })\n    observer.observe(viewport, { childList: true, subtree: true })\n    update()\n    return () => observer.disconnect()\n  }, [\n    atEndRef,\n    autoScroll,\n    defaultScrollPosition,\n    preserveScrollOnPrepend,\n    scrollEdgeThreshold,\n    setAtEnd,\n    setAtStart,\n    viewportRef,\n  ])\n\n  return (\n    <div\n      ref={viewportRef}\n      data-slot=\"message-scroller-viewport\"\n      className={cn(\n        \"size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain\",\n        className\n      )}\n      style={{\n        scrollPaddingBlockStart: scrollPreviousItemPeek,\n        scrollPaddingBlockEnd: scrollMargin,\n        ...style,\n      }}\n      onScroll={(event) => {\n        const viewport = event.currentTarget\n        setAtEnd(\n          viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <=\n            scrollEdgeThreshold\n        )\n        setAtStart(viewport.scrollTop <= scrollEdgeThreshold)\n        onScroll?.(event)\n      }}\n      {...props}\n    />\n  )\n}\n\nfunction MessageScrollerContent({\n  className,\n  spacerClassName,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & { spacerClassName?: string }) {\n  return (\n    <div\n      data-slot=\"message-scroller-content\"\n      className={cn(\"flex min-h-full flex-col gap-8\", className)}\n      {...props}\n    >\n      {spacerClassName ? (\n        <div\n          aria-hidden=\"true\"\n          data-slot=\"message-scroller-spacer\"\n          className={cn(\"flex-1\", spacerClassName)}\n        />\n      ) : null}\n      {children}\n    </div>\n  )\n}\n\nfunction MessageScrollerItem({\n  className,\n  messageId,\n  scrollAnchor,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  messageId?: string\n  scrollAnchor?: boolean\n}) {\n  return (\n    <div\n      data-slot=\"message-scroller-item\"\n      data-message-id={messageId}\n      data-scroll-anchor={scrollAnchor || undefined}\n      className={cn(\"min-w-0 shrink-0\", className)}\n      {...props}\n    />\n  )\n}\n\nexport interface MessageScrollerButtonProps\n  extends Omit<React.ComponentProps<typeof Button>, \"children\"> {\n  behavior?: ScrollBehavior\n  direction?: \"start\" | \"end\"\n  render?: React.ReactElement\n  children?: React.ReactNode\n}\n\nfunction MessageScrollerButton({\n  behavior = \"smooth\",\n  direction = \"end\",\n  className,\n  children,\n  render,\n  onClick,\n  ...props\n}: MessageScrollerButtonProps) {\n  const { atEnd, atStart, viewportRef } = useScroller()\n  const inactive = direction === \"end\" ? atEnd : atStart\n  return (\n    <Button\n      asChild={Boolean(render)}\n      type=\"button\"\n      aria-hidden={inactive}\n      tabIndex={inactive ? -1 : 0}\n      className={cn(\n        \"bg-background absolute left-1/2 -translate-x-1/2 border transition-[opacity,transform] duration-200\",\n        direction === \"end\" ? \"bottom-4\" : \"top-4\",\n        inactive && \"pointer-events-none translate-y-2 opacity-0\",\n        className\n      )}\n      onClick={(event) => {\n        const viewport = viewportRef.current\n        viewport?.scrollTo({\n          top: direction === \"end\" ? viewport.scrollHeight : 0,\n          behavior,\n        })\n        onClick?.(event)\n      }}\n      {...props}\n    >\n      {render ?? (\n        <>\n          {children ?? (\n            <ArrowDownIcon\n              className={cn(direction === \"start\" && \"rotate-180\")}\n            />\n          )}\n          <span className=\"sr-only\">\n            {direction === \"end\" ? \"Scroll to end\" : \"Scroll to start\"}\n          </span>\n        </>\n      )}\n    </Button>\n  )\n}\n\nexport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/button.tsx",
          "target": "@components/voice-agents/livekit/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-chat-indicator.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-indicator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { motion, useReducedMotion, type MotionProps } from \"motion/react\"\nimport { type ComponentProps, type Ref } from \"react\"\n\nconst motionAnimationProps = {\n  variants: {\n    hidden: {\n      opacity: 0,\n      scale: 0.1,\n      transition: {\n        duration: 0.1,\n        ease: \"linear\" as const,\n      },\n    },\n    visible: {\n      opacity: [0.5, 1],\n      scale: [0.9, 1],\n      transition: {\n        type: \"spring\" as const,\n        bounce: 0,\n        duration: 0.5,\n        repeat: Infinity,\n        repeatType: \"mirror\" as const,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\nconst agentChatIndicatorVariants = cva(\n  \"bg-muted-foreground inline-block size-2.5 rounded-full\",\n  {\n    variants: {\n      size: {\n        sm: \"size-3\",\n        md: \"size-4\",\n        lg: \"size-6\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentChatIndicator component.\n */\nexport interface AgentChatIndicatorProps extends MotionProps {\n  /**\n   * The size of the indicator dot.\n   * @defaultValue 'md'\n   */\n  size?: \"sm\" | \"md\" | \"lg\"\n  /**\n   * Additional CSS class names to apply to the indicator.\n   */\n  className?: string\n  /**\n   * Allows getting a ref to the component instance.\\nOnce the component unmounts, React will set `ref.current` to `null`\\n(or call the ref with `null` if you passed a callback ref).\\n@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}\n   */\n  ref?: Ref<HTMLSpanElement>\n}\n\n/**\n * An animated indicator that shows the agent is processing or thinking.\n * Displays as a pulsing dot, typically used in chat interfaces.\n *\n * @extends ComponentProps<'span'>\n *\n * @example\n * ```tsx\n * {agentState === 'thinking' && <AgentChatIndicator size=\"md\" />}\n * ```\n */\nexport function AgentChatIndicator({\n  size = \"md\",\n  className,\n  ...props\n}: AgentChatIndicatorProps &\n  ComponentProps<\"span\"> &\n  VariantProps<typeof agentChatIndicatorVariants>) {\n  const prefersReducedMotion = useReducedMotion()\n\n  return (\n    <motion.span\n      {...(prefersReducedMotion\n        ? { initial: false, animate: { opacity: 1, scale: 1 } }\n        : motionAnimationProps)}\n      transition={{ duration: 0.1, ease: \"linear\" as const }}\n      className={cn(agentChatIndicatorVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-react-shader-toy",
      "type": "registry:block",
      "title": "Livekit React Shader Toy",
      "description": "React Shader Toy",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/react-shader-toy.tsx",
          "target": "@components/voice-agents/livekit/react-shader-toy.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n/**\n * @license\n *\n * MIT License\n *\n * Copyright (c) 2018 Morgan Villedieu\n * Copyright (c) 2023 Rysana, Inc. (forked from the above)\n * Copyright (c) 2026 LiveKit, Inc. (forked from the above)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport React, { useEffect, useRef, type ComponentPropsWithoutRef } from \"react\"\n\nconst PRECISIONS = [\"lowp\", \"mediump\", \"highp\"]\nconst FS_MAIN_SHADER = `\\nvoid main(void){\n    vec4 color = vec4(0.0,0.0,0.0,1.0);\n    mainImage( color, gl_FragCoord.xy );\n    gl_FragColor = color;\n}`\nconst BASIC_FS = `void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n    vec2 uv = fragCoord/iResolution.xy;\n    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));\n    fragColor = vec4(col,1.0);\n}`\nconst BASIC_VS = `attribute vec3 aVertexPosition;\nvoid main(void) {\n    gl_Position = vec4(aVertexPosition, 1.0);\n}`\nconst UNIFORM_TIME = \"iTime\"\nconst UNIFORM_TIMEDELTA = \"iTimeDelta\"\nconst UNIFORM_DATE = \"iDate\"\nconst UNIFORM_FRAME = \"iFrame\"\nconst UNIFORM_MOUSE = \"iMouse\"\nconst UNIFORM_RESOLUTION = \"iResolution\"\nconst UNIFORM_CHANNEL = \"iChannel\"\nconst UNIFORM_CHANNELRESOLUTION = \"iChannelResolution\"\nconst UNIFORM_DEVICEORIENTATION = \"iDeviceOrientation\"\n\ntype Vector4<T = number> = [T, T, T, T]\ntype UniformType = keyof Uniforms\n\nfunction isMatrixType(t: string, v: number[] | number): v is number[] {\n  return t.includes(\"Matrix\") && Array.isArray(v)\n}\nfunction isVectorListType(t: string, v: number[] | number): v is number[] {\n  return (\n    t.includes(\"v\") &&\n    Array.isArray(v) &&\n    v.length > Number.parseInt(t.charAt(0))\n  )\n}\nfunction isVectorType(t: string, v: number[] | number): v is Vector4 {\n  return (\n    !t.includes(\"v\") &&\n    Array.isArray(v) &&\n    v.length > Number.parseInt(t.charAt(0))\n  )\n}\nconst processUniform = <T extends UniformType>(\n  gl: WebGLRenderingContext,\n  location: WebGLUniformLocation,\n  t: T,\n  value: number | number[]\n) => {\n  if (isVectorType(t, value)) {\n    switch (t) {\n      case \"2f\":\n        return gl.uniform2f(location, value[0], value[1])\n      case \"3f\":\n        return gl.uniform3f(location, value[0], value[1], value[2])\n      case \"4f\":\n        return gl.uniform4f(location, value[0], value[1], value[2], value[3])\n      case \"2i\":\n        return gl.uniform2i(location, value[0], value[1])\n      case \"3i\":\n        return gl.uniform3i(location, value[0], value[1], value[2])\n      case \"4i\":\n        return gl.uniform4i(location, value[0], value[1], value[2], value[3])\n    }\n  }\n  if (typeof value === \"number\") {\n    switch (t) {\n      case \"1i\":\n        return gl.uniform1i(location, value)\n      default:\n        return gl.uniform1f(location, value)\n    }\n  }\n  switch (t) {\n    case \"1iv\":\n      return gl.uniform1iv(location, value)\n    case \"2iv\":\n      return gl.uniform2iv(location, value)\n    case \"3iv\":\n      return gl.uniform3iv(location, value)\n    case \"4iv\":\n      return gl.uniform4iv(location, value)\n    case \"1fv\":\n      return gl.uniform1fv(location, value)\n    case \"2fv\":\n      return gl.uniform2fv(location, value)\n    case \"3fv\":\n      return gl.uniform3fv(location, value)\n    case \"4fv\":\n      return gl.uniform4fv(location, value)\n    case \"Matrix2fv\":\n      return gl.uniformMatrix2fv(location, false, value)\n    case \"Matrix3fv\":\n      return gl.uniformMatrix3fv(location, false, value)\n    case \"Matrix4fv\":\n      return gl.uniformMatrix4fv(location, false, value)\n  }\n}\n\nconst uniformTypeToGLSLType = (t: string) => {\n  switch (t) {\n    case \"1f\":\n      return \"float\"\n    case \"2f\":\n      return \"vec2\"\n    case \"3f\":\n      return \"vec3\"\n    case \"4f\":\n      return \"vec4\"\n    case \"1i\":\n      return \"int\"\n    case \"2i\":\n      return \"ivec2\"\n    case \"3i\":\n      return \"ivec3\"\n    case \"4i\":\n      return \"ivec4\"\n    case \"1iv\":\n      return \"int\"\n    case \"2iv\":\n      return \"ivec2\"\n    case \"3iv\":\n      return \"ivec3\"\n    case \"4iv\":\n      return \"ivec4\"\n    case \"1fv\":\n      return \"float\"\n    case \"2fv\":\n      return \"vec2\"\n    case \"3fv\":\n      return \"vec3\"\n    case \"4fv\":\n      return \"vec4\"\n    case \"Matrix2fv\":\n      return \"mat2\"\n    case \"Matrix3fv\":\n      return \"mat3\"\n    case \"Matrix4fv\":\n      return \"mat4\"\n    default:\n      console.error(\n        log(\n          `The uniform type \"${t}\" is not valid, please make sure your uniform type is valid`\n        )\n      )\n  }\n}\n\nconst LinearFilter = 9729\nconst NearestFilter = 9728\nconst LinearMipMapLinearFilter = 9987\nconst ClampToEdgeWrapping = 33071\nconst RepeatWrapping = 10497\n\nclass Texture {\n  gl: WebGLRenderingContext\n  url?: string\n  wrapS?: number\n  wrapT?: number\n  minFilter?: number\n  magFilter?: number\n  source?: HTMLImageElement | HTMLVideoElement\n  pow2canvas?: HTMLCanvasElement\n  isLoaded = false\n  isVideo = false\n  flipY = -1\n  width = 0\n  height = 0\n  _webglTexture: WebGLTexture | null = null\n  constructor(gl: WebGLRenderingContext) {\n    this.gl = gl\n  }\n  updateTexture = (\n    texture: WebGLTexture,\n    video: HTMLVideoElement,\n    flipY: number\n  ) => {\n    const { gl } = this\n    const level = 0\n    const internalFormat = gl.RGBA\n    const srcFormat = gl.RGBA\n    const srcType = gl.UNSIGNED_BYTE\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      srcFormat,\n      srcType,\n      video\n    )\n  }\n  setupVideo = (url: string) => {\n    const video = document.createElement(\"video\")\n    let playing = false\n    let timeupdate = false\n    video.autoplay = true\n    video.muted = true\n    video.loop = true\n    video.crossOrigin = \"anonymous\"\n    const checkReady = () => {\n      if (playing && timeupdate) {\n        this.isLoaded = true\n      }\n    }\n    video.addEventListener(\n      \"playing\",\n      () => {\n        playing = true\n        this.width = video.videoWidth || 0\n        this.height = video.videoHeight || 0\n        checkReady()\n      },\n      true\n    )\n    video.addEventListener(\n      \"timeupdate\",\n      () => {\n        timeupdate = true\n        checkReady()\n      },\n      true\n    )\n    video.src = url\n    return video\n  }\n  makePowerOf2 = <T extends HTMLCanvasElement | HTMLImageElement | ImageBitmap>(\n    image: T\n  ): T => {\n    if (\n      image instanceof HTMLImageElement ||\n      image instanceof HTMLCanvasElement ||\n      image instanceof ImageBitmap\n    ) {\n      if (this.pow2canvas === undefined)\n        this.pow2canvas = document.createElement(\"canvas\")\n      this.pow2canvas.width = 2 ** Math.floor(Math.log(image.width) / Math.LN2)\n      this.pow2canvas.height =\n        2 ** Math.floor(Math.log(image.height) / Math.LN2)\n      const context = this.pow2canvas.getContext(\"2d\")\n      context?.drawImage(\n        image,\n        0,\n        0,\n        this.pow2canvas.width,\n        this.pow2canvas.height\n      )\n      console.warn(\n        log(\n          `Image is not power of two ${image.width} x ${image.height}. Resized to ${this.pow2canvas.width} x ${this.pow2canvas.height};`\n        )\n      )\n      return this.pow2canvas as T\n    }\n    return image\n  }\n  load = async (textureArgs: TextureParams) => {\n    const { gl } = this\n    const {\n      url,\n      wrapS,\n      wrapT,\n      minFilter,\n      magFilter,\n      flipY = -1,\n    }: TextureParams = textureArgs\n    if (!url) {\n      return Promise.reject(\n        new Error(\n          log(\n            \"Missing url, please make sure to pass the url of your texture { url: ... }\"\n          )\n        )\n      )\n    }\n    const isImage = /(\\.jpg|\\.jpeg|\\.png|\\.gif|\\.bmp)$/i.exec(url)\n    const isVideo = /(\\.mp4|\\.3gp|\\.webm|\\.ogv)$/i.exec(url)\n    if (isImage === null && isVideo === null) {\n      return Promise.reject(\n        new Error(\n          log(\n            `Please upload a video or an image with a valid format (url: ${url})`\n          )\n        )\n      )\n    }\n    Object.assign(this, { url, wrapS, wrapT, minFilter, magFilter, flipY })\n    const level = 0\n    const internalFormat = gl.RGBA\n    const width = 1\n    const height = 1\n    const border = 0\n    const srcFormat = gl.RGBA\n    const srcType = gl.UNSIGNED_BYTE\n    const pixel = new Uint8Array([255, 255, 255, 0])\n    const texture = gl.createTexture()\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      width,\n      height,\n      border,\n      srcFormat,\n      srcType,\n      pixel\n    )\n    if (isVideo) {\n      const video = this.setupVideo(url)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)\n      this._webglTexture = texture\n      this.source = video\n      this.isVideo = true\n      return video.play().then(() => this)\n    }\n    async function loadImage() {\n      return new Promise((resolve, reject) => {\n        const image = new Image()\n        image.crossOrigin = \"anonymous\"\n        image.onload = () => {\n          resolve(image)\n        }\n        image.onerror = () => {\n          reject(new Error(log(`failed loading url: ${url}`)))\n        }\n        image.src = url ?? \"\"\n      })\n    }\n    let image = (await loadImage()) as HTMLImageElement\n    let isPowerOf2 =\n      (image.width & (image.width - 1)) === 0 &&\n      (image.height & (image.height - 1)) === 0\n    if (\n      (textureArgs.wrapS !== ClampToEdgeWrapping ||\n        textureArgs.wrapT !== ClampToEdgeWrapping ||\n        (textureArgs.minFilter !== NearestFilter &&\n          textureArgs.minFilter !== LinearFilter)) &&\n      !isPowerOf2\n    ) {\n      image = this.makePowerOf2(image)\n      isPowerOf2 = true\n    }\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      srcFormat,\n      srcType,\n      image\n    )\n    if (\n      isPowerOf2 &&\n      textureArgs.minFilter !== NearestFilter &&\n      textureArgs.minFilter !== LinearFilter\n    ) {\n      gl.generateMipmap(gl.TEXTURE_2D)\n    }\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_WRAP_S,\n      this.wrapS || RepeatWrapping\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_WRAP_T,\n      this.wrapT || RepeatWrapping\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_MIN_FILTER,\n      this.minFilter || LinearMipMapLinearFilter\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_MAG_FILTER,\n      this.magFilter || LinearFilter\n    )\n    this._webglTexture = texture\n    this.source = image\n    this.isVideo = false\n    this.isLoaded = true\n    this.width = image.width || 0\n    this.height = image.height || 0\n    return this\n  }\n}\n\nconst log = (text: string) => `react-shaders: ${text}`\n\nconst latestPointerClientCoords = (e: MouseEvent | TouchEvent) => {\n  if (\"changedTouches\" in e) {\n    const t = e.changedTouches[0]\n    return [t?.clientX ?? 0, t?.clientY ?? 0]\n  }\n  return [e.clientX, e.clientY]\n}\n\nconst lerpVal = (v0: number, v1: number, t: number) => v0 * (1 - t) + v1 * t\nconst insertStringAtIndex = (\n  currentString: string,\n  string: string,\n  index: number\n) =>\n  index > 0\n    ? currentString.substring(0, index) +\n      string +\n      currentString.substring(index, currentString.length)\n    : string + currentString\n\ntype Uniform = { type: string; value: number[] | number }\ntype Uniforms = Record<string, Uniform>\ntype TextureParams = {\n  url: string\n  wrapS?: number\n  wrapT?: number\n  minFilter?: number\n  magFilter?: number\n  flipY?: number\n}\n\nexport interface ReactShaderToyProps {\n  /** Fragment shader GLSL code. */\n  fs: string\n\n  /** Vertex shader GLSL code. */\n  vs?: string\n\n  /**\n   * Textures to be passed to the shader. Textures need to be squared or will be\n   * automatically resized.\n   *\n   * Options default to:\n   *\n   * ```js\n   * {\n   *   minFilter: LinearMipMapLinearFilter,\n   *   magFilter: LinearFilter,\n   *   wrapS: RepeatWrapping,\n   *   wrapT: RepeatWrapping,\n   * }\n   * ```\n   *\n   * See [textures in the docs](https://rysana.com/docs/react-shaders#textures)\n   * for details.\n   */\n  textures?: TextureParams[]\n\n  /**\n   * Custom uniforms to be passed to the shader.\n   *\n   * See [custom uniforms in the\n   * docs](https://rysana.com/docs/react-shaders#custom-uniforms) for details.\n   */\n  uniforms?: Uniforms\n\n  /**\n   * Color used when clearing the canvas.\n   *\n   * See [the WebGL\n   * docs](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/clearColor)\n   * for details.\n   */\n  clearColor?: Vector4\n\n  /**\n   * GLSL precision qualifier. Defaults to `'highp'`. Balance between\n   * performance and quality.\n   */\n  precision?: \"highp\" | \"lowp\" | \"mediump\"\n\n  /** Custom inline style for canvas. */\n  style?: React.CSSProperties\n\n  /** Customize WebGL context attributes. See [the WebGL docs](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getContextAttributes) for details. */\n  contextAttributes?: Record<string, unknown>\n\n  /** Lerp value for `iMouse` built-in uniform. Must be between 0 and 1. */\n  lerp?: number\n\n  /** Device pixel ratio. */\n  devicePixelRatio?: number\n\n  /**\n   * Callback for when the textures are done loading. Useful if you want to do\n   * something like e.g. hide the canvas until textures are done loading.\n   */\n  onDoneLoadingTextures?: () => void\n\n  /** Custom callback to handle errors. Defaults to `console.error`. */\n  onError?: (error: string) => void\n\n  /** Custom callback to handle warnings. Defaults to `console.warn`. */\n  onWarning?: (warning: string) => void\n\n  /**\n   * When true, the animation loop runs even when the canvas is not visible in the viewport.\n   * When false (default), animation runs only while visible (uses Intersection Observer),\n   * reducing CPU/GPU usage when the shader is off-screen.\n   */\n  animateWhenNotVisible?: boolean\n}\n\nexport function ReactShaderToy({\n  fs,\n  vs = BASIC_VS,\n  textures = [],\n  uniforms: propUniforms,\n  clearColor = [0, 0, 0, 1],\n  precision = \"highp\",\n  style,\n  contextAttributes = {},\n  lerp = 1,\n  devicePixelRatio = 1,\n  onDoneLoadingTextures,\n  onError = console.error,\n  onWarning = console.warn,\n  animateWhenNotVisible = false,\n  ...canvasProps\n}: ReactShaderToyProps & ComponentPropsWithoutRef<\"canvas\">) {\n  // Refs for WebGL state\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const glRef = useRef<WebGLRenderingContext | null>(null)\n  const squareVerticesBufferRef = useRef<WebGLBuffer | null>(null)\n  const shaderProgramRef = useRef<WebGLProgram | null>(null)\n  const vertexPositionAttributeRef = useRef<number | undefined>(undefined)\n  const animFrameIdRef = useRef<number | undefined>(undefined)\n  const initFrameIdRef = useRef<number | undefined>(undefined)\n  const isVisibleRef = useRef(true)\n  const prefersReducedMotionRef = useRef(false)\n  const animateWhenNotVisibleRef = useRef(animateWhenNotVisible)\n  const mousedownRef = useRef(false)\n  const canvasPositionRef = useRef<DOMRect | undefined>(undefined)\n  const timerRef = useRef(0)\n  const lastMouseArrRef = useRef<number[]>([0, 0])\n  const texturesArrRef = useRef<Texture[]>([])\n  const lastTimeRef = useRef(0)\n  const resizeObserverRef = useRef<ResizeObserver | undefined>(undefined)\n  const uniformsRef = useRef<\n    Record<\n      string,\n      {\n        type: string\n        isNeeded: boolean\n        value?: number[] | number\n        arraySize?: string\n      }\n    >\n  >({\n    [UNIFORM_TIME]: { type: \"float\", isNeeded: false, value: 0 },\n    [UNIFORM_TIMEDELTA]: { type: \"float\", isNeeded: false, value: 0 },\n    [UNIFORM_DATE]: { type: \"vec4\", isNeeded: false, value: [0, 0, 0, 0] },\n    [UNIFORM_MOUSE]: { type: \"vec4\", isNeeded: false, value: [0, 0, 0, 0] },\n    [UNIFORM_RESOLUTION]: { type: \"vec2\", isNeeded: false, value: [0, 0] },\n    [UNIFORM_FRAME]: { type: \"int\", isNeeded: false, value: 0 },\n    [UNIFORM_DEVICEORIENTATION]: {\n      type: \"vec4\",\n      isNeeded: false,\n      value: [0, 0, 0, 0],\n    },\n  })\n  const propsUniformsRef = useRef<Uniforms | undefined>(propUniforms)\n  const resolvedDevicePixelRatio = Math.min(Math.max(devicePixelRatio, 1), 2)\n\n  const setupChannelRes = (texture: TextureParams | Texture, id: number) => {\n    const width = \"width\" in texture ? (texture.width ?? 0) : 0\n    const height = \"height\" in texture ? (texture.height ?? 0) : 0\n    const channelResUniform = uniformsRef.current.iChannelResolution\n    if (!channelResUniform) return\n    const channelResValue = Array.isArray(channelResUniform.value)\n      ? channelResUniform.value\n      : (channelResUniform.value = [])\n    channelResValue[id * 3] = width * resolvedDevicePixelRatio\n    channelResValue[id * 3 + 1] = height * resolvedDevicePixelRatio\n    channelResValue[id * 3 + 2] = 0\n  }\n\n  const initWebGL = () => {\n    if (!canvasRef.current) return\n    glRef.current = (canvasRef.current.getContext(\"webgl\", contextAttributes) ||\n      canvasRef.current.getContext(\n        \"experimental-webgl\",\n        contextAttributes\n      )) as WebGLRenderingContext | null\n    glRef.current?.getExtension(\"OES_standard_derivatives\")\n    glRef.current?.getExtension(\"EXT_shader_texture_lod\")\n  }\n\n  const initBuffers = () => {\n    const gl = glRef.current\n    squareVerticesBufferRef.current = gl?.createBuffer() ?? null\n    gl?.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBufferRef.current)\n    const vertices = [\n      1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0,\n    ]\n    gl?.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)\n  }\n\n  const onDeviceOrientationChange = ({\n    alpha,\n    beta,\n    gamma,\n  }: DeviceOrientationEvent) => {\n    uniformsRef.current.iDeviceOrientation!.value = [\n      alpha ?? 0,\n      beta ?? 0,\n      gamma ?? 0,\n      window.orientation ?? 0,\n    ]\n  }\n\n  const mouseDown = (e: MouseEvent | TouchEvent) => {\n    const [clientX = 0, clientY = 0] = latestPointerClientCoords(e)\n    const mouseX =\n      clientX - (canvasPositionRef.current?.left ?? 0) - window.pageXOffset\n    const mouseY =\n      (canvasPositionRef.current?.height ?? 0) -\n      clientY -\n      (canvasPositionRef.current?.top ?? 0) -\n      window.pageYOffset\n    mousedownRef.current = true\n    const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n      ? uniformsRef.current.iMouse.value\n      : undefined\n    if (mouseValue) {\n      mouseValue[2] = mouseX\n      mouseValue[3] = mouseY\n    }\n    lastMouseArrRef.current[0] = mouseX\n    lastMouseArrRef.current[1] = mouseY\n  }\n\n  const mouseMove = (e: MouseEvent | TouchEvent) => {\n    canvasPositionRef.current = canvasRef.current?.getBoundingClientRect()\n    const [clientX = 0, clientY = 0] = latestPointerClientCoords(e)\n    const mouseX = clientX - (canvasPositionRef.current?.left ?? 0)\n    const mouseY =\n      (canvasPositionRef.current?.height ?? 0) -\n      clientY -\n      (canvasPositionRef.current?.top ?? 0)\n    if (lerp !== 1) {\n      lastMouseArrRef.current[0] = mouseX\n      lastMouseArrRef.current[1] = mouseY\n    } else {\n      const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n        ? uniformsRef.current.iMouse.value\n        : undefined\n      if (mouseValue) {\n        mouseValue[0] = mouseX\n        mouseValue[1] = mouseY\n      }\n    }\n  }\n\n  const mouseUp = () => {\n    const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n      ? uniformsRef.current.iMouse.value\n      : undefined\n    if (mouseValue) {\n      mouseValue[2] = 0\n      mouseValue[3] = 0\n    }\n  }\n\n  const onResize = () => {\n    const gl = glRef.current\n    if (!gl) return\n    canvasPositionRef.current = canvasRef.current?.getBoundingClientRect()\n    // Force pixel ratio to be one to avoid expensive calculus on retina display.\n    const realToCSSPixels = resolvedDevicePixelRatio\n    const displayWidth = Math.floor(\n      (canvasPositionRef.current?.width ?? 1) * realToCSSPixels\n    )\n    const displayHeight = Math.floor(\n      (canvasPositionRef.current?.height ?? 1) * realToCSSPixels\n    )\n    gl.canvas.width = displayWidth\n    gl.canvas.height = displayHeight\n    if (uniformsRef.current.iResolution?.isNeeded && shaderProgramRef.current) {\n      const rUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_RESOLUTION\n      )\n      gl.uniform2fv(rUniform, [gl.canvas.width, gl.canvas.height])\n    }\n  }\n\n  const createShader = (type: number, shaderCodeAsText: string) => {\n    const gl = glRef.current\n    if (!gl) return null\n    const shader = gl.createShader(type)\n    if (!shader) return null\n    gl.shaderSource(shader, shaderCodeAsText)\n    gl.compileShader(shader)\n    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n      onWarning?.(log(`Error compiling the shader:\\n${shaderCodeAsText}`))\n      const compilationLog = gl.getShaderInfoLog(shader)\n      gl.deleteShader(shader)\n      onError?.(log(`Shader compiler log: ${compilationLog}`))\n    }\n    return shader\n  }\n\n  const initShaders = (fragmentShader: string, vertexShader: string) => {\n    const gl = glRef.current\n    if (!gl) return\n    const fragmentShaderObj = createShader(gl.FRAGMENT_SHADER, fragmentShader)\n    const vertexShaderObj = createShader(gl.VERTEX_SHADER, vertexShader)\n    shaderProgramRef.current = gl.createProgram()\n    if (!shaderProgramRef.current || !vertexShaderObj || !fragmentShaderObj)\n      return\n    gl.attachShader(shaderProgramRef.current, vertexShaderObj)\n    gl.attachShader(shaderProgramRef.current, fragmentShaderObj)\n    gl.linkProgram(shaderProgramRef.current)\n    if (!gl.getProgramParameter(shaderProgramRef.current, gl.LINK_STATUS)) {\n      onError?.(\n        log(\n          `Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgramRef.current)}`\n        )\n      )\n      return\n    }\n    gl.useProgram(shaderProgramRef.current)\n    vertexPositionAttributeRef.current = gl.getAttribLocation(\n      shaderProgramRef.current,\n      \"aVertexPosition\"\n    )\n    gl.enableVertexAttribArray(vertexPositionAttributeRef.current)\n  }\n\n  const processCustomUniforms = () => {\n    if (propUniforms) {\n      for (const name of Object.keys(propUniforms)) {\n        const uniform = propUniforms[name]\n        if (!uniform) continue\n        const { value, type } = uniform\n        const glslType = uniformTypeToGLSLType(type)\n        if (!glslType) continue\n        const tempObject: { arraySize?: string } = {}\n        if (isMatrixType(type, value)) {\n          const arrayLength = type.length\n          const val = Number.parseInt(type.charAt(arrayLength - 3))\n          const numberOfMatrices = Math.floor(value.length / (val * val))\n          if (value.length > val * val)\n            tempObject.arraySize = `[${numberOfMatrices}]`\n        } else if (isVectorListType(type, value)) {\n          tempObject.arraySize = `[${Math.floor(value.length / Number.parseInt(type.charAt(0)))}]`\n        }\n        uniformsRef.current[name] = {\n          type: glslType,\n          isNeeded: false,\n          value,\n          ...tempObject,\n        }\n      }\n    }\n  }\n\n  const processTextures = () => {\n    const gl = glRef.current\n    if (!gl) return\n    if (textures && textures.length > 0) {\n      uniformsRef.current[`${UNIFORM_CHANNELRESOLUTION}`] = {\n        type: \"vec3\",\n        isNeeded: false,\n        arraySize: `[${textures.length}]`,\n        value: [],\n      }\n      const texturePromisesArr = textures.map(\n        (texture: TextureParams, id: number) => {\n          // Dynamically add textures uniforms.\n          uniformsRef.current[`${UNIFORM_CHANNEL}${id}`] = {\n            type: \"sampler2D\",\n            isNeeded: false,\n          }\n          setupChannelRes(texture, id)\n          texturesArrRef.current[id] = new Texture(gl)\n          return texturesArrRef.current[id]\n            ?.load(texture)\n            .then((t: Texture) => {\n              setupChannelRes(t, id)\n            })\n        }\n      )\n      Promise.all(texturePromisesArr)\n        .then(() => {\n          if (onDoneLoadingTextures) onDoneLoadingTextures()\n        })\n        .catch((e) => {\n          onError?.(e)\n          if (onDoneLoadingTextures) onDoneLoadingTextures()\n        })\n    } else if (onDoneLoadingTextures) onDoneLoadingTextures()\n  }\n\n  const preProcessFragment = (fragment: string) => {\n    const isValidPrecision = PRECISIONS.includes(precision ?? \"highp\")\n    const precisionString = `precision ${isValidPrecision ? precision : PRECISIONS[1]} float;\\n`\n    if (!isValidPrecision) {\n      onWarning?.(\n        log(\n          `wrong precision type ${precision}, please make sure to pass one of a valid precision lowp, mediump, highp, by default you shader precision will be set to highp.`\n        )\n      )\n    }\n    let fragmentShader = precisionString\n      .concat(`#define DPR ${resolvedDevicePixelRatio.toFixed(1)}\\n`)\n      .concat(fragment.replace(/texture\\(/g, \"texture2D(\"))\n    for (const uniform of Object.keys(uniformsRef.current)) {\n      if (fragment.includes(uniform)) {\n        const u = uniformsRef.current[uniform]\n        if (!u) continue\n        fragmentShader = insertStringAtIndex(\n          fragmentShader,\n          `uniform ${u.type} ${uniform}${u.arraySize || \"\"}; \\n`,\n          fragmentShader.lastIndexOf(precisionString) + precisionString.length\n        )\n        u.isNeeded = true\n      }\n    }\n    const isShadertoy = fragment.includes(\"mainImage\")\n    if (isShadertoy) fragmentShader = fragmentShader.concat(FS_MAIN_SHADER)\n    return fragmentShader\n  }\n\n  const setUniforms = (timestamp: number) => {\n    const gl = glRef.current\n    if (!gl || !shaderProgramRef.current) return\n    const delta = lastTimeRef.current\n      ? (timestamp - lastTimeRef.current) / 1000\n      : 0\n    lastTimeRef.current = timestamp\n    const propUniforms = propsUniformsRef.current\n    if (propUniforms) {\n      for (const name of Object.keys(propUniforms)) {\n        const currentUniform = propUniforms[name]\n        if (!currentUniform) continue\n        if (uniformsRef.current[name]?.isNeeded) {\n          if (!shaderProgramRef.current) return\n          const customUniformLocation = gl.getUniformLocation(\n            shaderProgramRef.current,\n            name\n          )\n          if (!customUniformLocation) return\n          processUniform(\n            gl,\n            customUniformLocation,\n            currentUniform.type as UniformType,\n            currentUniform.value\n          )\n        }\n      }\n    }\n    if (uniformsRef.current.iMouse?.isNeeded) {\n      const mouseUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_MOUSE\n      )\n      gl.uniform4fv(mouseUniform, uniformsRef.current.iMouse.value as number[])\n    }\n    if (uniformsRef.current.iChannelResolution?.isNeeded) {\n      const channelResUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_CHANNELRESOLUTION\n      )\n      gl.uniform3fv(\n        channelResUniform,\n        uniformsRef.current.iChannelResolution.value as number[]\n      )\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      const deviceOrientationUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_DEVICEORIENTATION\n      )\n      gl.uniform4fv(\n        deviceOrientationUniform,\n        uniformsRef.current.iDeviceOrientation.value as number[]\n      )\n    }\n    if (uniformsRef.current.iTime?.isNeeded) {\n      const timeUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_TIME\n      )\n      gl.uniform1f(timeUniform, (timerRef.current += delta))\n    }\n    if (uniformsRef.current.iTimeDelta?.isNeeded) {\n      const timeDeltaUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_TIMEDELTA\n      )\n      gl.uniform1f(timeDeltaUniform, delta)\n    }\n    if (uniformsRef.current.iDate?.isNeeded) {\n      const d = new Date()\n      const month = d.getMonth() + 1\n      const day = d.getDate()\n      const year = d.getFullYear()\n      const time =\n        d.getHours() * 60 * 60 +\n        d.getMinutes() * 60 +\n        d.getSeconds() +\n        d.getMilliseconds() * 0.001\n      const dateUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_DATE\n      )\n      gl.uniform4fv(dateUniform, [year, month, day, time])\n    }\n    if (uniformsRef.current.iFrame?.isNeeded) {\n      const timeDeltaUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_FRAME\n      )\n      const frame = uniformsRef.current.iFrame.value as number\n      gl.uniform1i(timeDeltaUniform, frame)\n      uniformsRef.current.iFrame.value = frame + 1\n    }\n    if (texturesArrRef.current.length > 0) {\n      for (let index = 0; index < texturesArrRef.current.length; index++) {\n        const texture = texturesArrRef.current[index]\n        if (!texture) return\n        const { isVideo, _webglTexture, source, flipY, isLoaded } = texture\n        if (!isLoaded || !_webglTexture || !source) return\n        if (uniformsRef.current[`iChannel${index}`]?.isNeeded) {\n          if (!shaderProgramRef.current) return\n          const iChannel = gl.getUniformLocation(\n            shaderProgramRef.current,\n            `iChannel${index}`\n          )\n          gl.activeTexture(gl.TEXTURE0 + index)\n          gl.bindTexture(gl.TEXTURE_2D, _webglTexture)\n          gl.uniform1i(iChannel, index)\n          if (isVideo) {\n            texture.updateTexture(\n              _webglTexture,\n              source as HTMLVideoElement,\n              flipY\n            )\n          }\n        }\n      }\n    }\n  }\n\n  const drawScene = (timestamp: number) => {\n    const gl = glRef.current\n    if (!gl) return\n    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight)\n    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)\n    gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBufferRef.current)\n    gl.vertexAttribPointer(\n      vertexPositionAttributeRef.current ?? 0,\n      3,\n      gl.FLOAT,\n      false,\n      0,\n      0\n    )\n    setUniforms(timestamp)\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\n    const mouseValue = uniformsRef.current.iMouse?.value\n    if (\n      uniformsRef.current.iMouse?.isNeeded &&\n      lerp !== 1 &&\n      Array.isArray(mouseValue)\n    ) {\n      const currentX = mouseValue[0] ?? 0\n      const currentY = mouseValue[1] ?? 0\n      mouseValue[0] = lerpVal(currentX, lastMouseArrRef.current[0] ?? 0, lerp)\n      mouseValue[1] = lerpVal(currentY, lastMouseArrRef.current[1] ?? 0, lerp)\n    }\n    if (\n      !prefersReducedMotionRef.current &&\n      (animateWhenNotVisibleRef.current || isVisibleRef.current)\n    ) {\n      animFrameIdRef.current = requestAnimationFrame(drawScene)\n    }\n  }\n\n  const addEventListeners = () => {\n    const options = { passive: true }\n    if (uniformsRef.current.iMouse?.isNeeded && canvasRef.current) {\n      canvasRef.current.addEventListener(\"mousemove\", mouseMove, options)\n      canvasRef.current.addEventListener(\"mouseout\", mouseUp, options)\n      canvasRef.current.addEventListener(\"mouseup\", mouseUp, options)\n      canvasRef.current.addEventListener(\"mousedown\", mouseDown, options)\n      canvasRef.current.addEventListener(\"touchmove\", mouseMove, options)\n      canvasRef.current.addEventListener(\"touchend\", mouseUp, options)\n      canvasRef.current.addEventListener(\"touchstart\", mouseDown, options)\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      window.addEventListener(\n        \"deviceorientation\",\n        onDeviceOrientationChange,\n        options\n      )\n    }\n    if (canvasRef.current) {\n      resizeObserverRef.current = new ResizeObserver(onResize)\n      resizeObserverRef.current.observe(canvasRef.current)\n      window.addEventListener(\"resize\", onResize, options)\n    }\n  }\n\n  const removeEventListeners = () => {\n    const options = { passive: true } as EventListenerOptions\n    if (uniformsRef.current.iMouse?.isNeeded && canvasRef.current) {\n      canvasRef.current.removeEventListener(\"mousemove\", mouseMove, options)\n      canvasRef.current.removeEventListener(\"mouseout\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"mouseup\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"mousedown\", mouseDown, options)\n      canvasRef.current.removeEventListener(\"touchmove\", mouseMove, options)\n      canvasRef.current.removeEventListener(\"touchend\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"touchstart\", mouseDown, options)\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      window.removeEventListener(\n        \"deviceorientation\",\n        onDeviceOrientationChange,\n        options\n      )\n    }\n    if (resizeObserverRef.current) {\n      resizeObserverRef.current.disconnect()\n      window.removeEventListener(\"resize\", onResize, options)\n    }\n  }\n\n  useEffect(() => {\n    propsUniformsRef.current = propUniforms\n  }, [propUniforms])\n\n  useEffect(() => {\n    animateWhenNotVisibleRef.current = animateWhenNotVisible\n    if (animateWhenNotVisible) {\n      isVisibleRef.current = true\n    }\n  }, [animateWhenNotVisible])\n\n  useEffect(() => {\n    const media = window.matchMedia(\"(prefers-reduced-motion: reduce)\")\n    const update = () => {\n      prefersReducedMotionRef.current = media.matches\n      if (media.matches) {\n        cancelAnimationFrame(animFrameIdRef.current ?? 0)\n        requestAnimationFrame(drawScene)\n      } else if (animateWhenNotVisibleRef.current || isVisibleRef.current) {\n        requestAnimationFrame(drawScene)\n      }\n    }\n    update()\n    media.addEventListener(\"change\", update)\n    return () => media.removeEventListener(\"change\", update)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [])\n\n  // Intersection Observer: pause animation when off-screen when animateWhenNotVisible is false\n  useEffect(() => {\n    if (animateWhenNotVisible || !canvasRef.current) return\n    const canvas = canvasRef.current\n    const observer = new IntersectionObserver(\n      (entries) => {\n        for (const entry of entries) {\n          isVisibleRef.current = entry.isIntersecting\n          if (entry.isIntersecting) {\n            requestAnimationFrame(drawScene)\n          }\n        }\n      },\n      { threshold: 0 }\n    )\n    observer.observe(canvas)\n    return () => observer.disconnect()\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [animateWhenNotVisible])\n\n  // Main effect for initialization and cleanup\n  useEffect(() => {\n    const textures = texturesArrRef.current\n\n    function init() {\n      initWebGL()\n      const gl = glRef.current\n      if (gl && canvasRef.current) {\n        gl.clearColor(...clearColor)\n        gl.clearDepth(1.0)\n        gl.enable(gl.DEPTH_TEST)\n        gl.depthFunc(gl.LEQUAL)\n        gl.viewport(0, 0, canvasRef.current.width, canvasRef.current.height)\n        canvasRef.current.height = canvasRef.current.clientHeight\n        canvasRef.current.width = canvasRef.current.clientWidth\n        processCustomUniforms()\n        processTextures()\n        initShaders(preProcessFragment(fs || BASIC_FS), vs || BASIC_VS)\n        initBuffers()\n        requestAnimationFrame(drawScene)\n        addEventListeners()\n        onResize()\n      }\n    }\n\n    initFrameIdRef.current = requestAnimationFrame(init)\n\n    // Cleanup function\n    return () => {\n      const gl = glRef.current\n      if (gl) {\n        gl.getExtension(\"WEBGL_lose_context\")?.loseContext()\n        gl.useProgram(null)\n        gl.deleteProgram(shaderProgramRef.current ?? null)\n        if (textures.length > 0) {\n          for (const texture of textures as Texture[]) {\n            gl.deleteTexture(texture._webglTexture)\n          }\n        }\n        shaderProgramRef.current = null\n      }\n      removeEventListeners()\n      cancelAnimationFrame(initFrameIdRef.current ?? 0)\n      cancelAnimationFrame(animFrameIdRef.current ?? 0)\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []) // Empty dependency array to run only once on mount\n\n  return (\n    <canvas\n      ref={canvasRef}\n      style={{ height: \"100%\", width: \"100%\", ...style }}\n      {...canvasProps}\n    />\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-audio-visualizer-wave",
      "type": "registry:block",
      "title": "Livekit Agent Audio Visualizer Wave",
      "description": "Agent Audio Visualizer Wave",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-wave.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-wave.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerWave } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave\"\nimport { ReactShaderToy } from \"@/components/voice-agents/livekit/react-shader-toy\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport type { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport { useMemo, type ComponentProps } from \"react\"\n\nconst DEFAULT_COLOR = \"#1FD5F9\"\n\nfunction hexToRgb(hexColor: string) {\n  try {\n    const rgbColor = hexColor.match(\n      /^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n    )\n\n    if (rgbColor) {\n      const [, r, g, b] = rgbColor\n      const color = [r, g, b].map((c = \"00\") => parseInt(c, 16) / 255)\n\n      return color\n    }\n  } catch {\n    console.error(\n      `Invalid hex color '${hexColor}'.\\nFalling back to default color '${DEFAULT_COLOR}'.`\n    )\n  }\n\n  return hexToRgb(DEFAULT_COLOR)\n}\n\nconst shaderSource = `\nconst float TAU = 6.28318530718;\n\n// Noise for dithering\nvec2 randFibo(vec2 p) {\n  p = fract(p * vec2(443.897, 441.423));\n  p += dot(p, p.yx + 19.19);\n  return fract((p.xx + p.yx) * p.xy);\n}\n\n// Luma for alpha\nfloat luma(vec3 color) {\n  return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\n// RGB to HSV\nvec3 rgb2hsv(vec3 c) {\n  vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n  vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n  vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n  float d = q.x - min(q.w, q.y);\n  float e = 1.0e-10;\n  return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\n// HSV to RGB\nvec3 hsv2rgb(vec3 c) {\n  vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n  vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n  return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\n// Bell curve function for attenuation from center with rounded top\nfloat bellCurve(float distanceFromCenter, float maxDistance) {\n  float normalizedDistance = distanceFromCenter / maxDistance;\n  // Use cosine with high power for smooth rounded top\n  return pow(cos(normalizedDistance * (3.14159265359 / 4.0)), 16.0);\n}\n\n// Calculate the sine wave\nfloat oscilloscopeWave(float x, float centerX, float time) {\n  float relativeX = x - centerX;\n  float maxDistance = centerX;\n  float distanceFromCenter = abs(relativeX);\n\n  // Apply bell curve for amplitude attenuation\n  float bell = bellCurve(distanceFromCenter, maxDistance);\n\n  // Calculate wave with uniforms and bell curve attenuation\n  float wave = sin(relativeX * uFrequency + time * uSpeed) * uAmplitude * bell;\n\n  return wave;\n}\n\nvoid mainImage(out vec4 fragColor, in vec2 fragCoord) {\n  vec2 uv = fragCoord / iResolution.xy;\n  vec2 pos = uv - 0.5;\n\n  // Calculate center and positions\n  float centerX = 0.5;\n  float centerY = 0.5;\n  float x = uv.x;\n  float y = uv.y;\n\n  // Convert line width from pixels to UV space\n  // Use the average of width and height to handle aspect ratio\n  float pixelSize = 2.0 / (iResolution.x + iResolution.y);\n  float lineWidthUV = uLineWidth * pixelSize;\n  float smoothingUV = uSmoothing * pixelSize;\n\n  // Find minimum distance to the wave by sampling nearby points\n  // This gives us consistent line width without high-frequency artifacts\n  const int NUM_SAMPLES = 50; // Must be const for GLSL loop\n  float minDist = 1000.0;\n  float sampleRange = 0.02; // Range to search for closest point\n\n  for(int i = 0; i < NUM_SAMPLES; i++) {\n    float offset = (float(i) / float(NUM_SAMPLES - 1) - 0.5) * sampleRange;\n    float sampleX = x + offset;\n    float waveY = centerY + oscilloscopeWave(sampleX, centerX, iTime);\n\n    // Calculate distance from current pixel to this point on the wave\n    vec2 wavePoint = vec2(sampleX, waveY);\n    vec2 currentPoint = vec2(x, y);\n    float dist = distance(currentPoint, wavePoint);\n\n    minDist = min(minDist, dist);\n  }\n\n  // Solid line with smooth edges using minimum distance\n  float line = smoothstep(lineWidthUV + smoothingUV, lineWidthUV - smoothingUV, minDist);\n\n  vec3 color = uColor;\n  if(abs(uColorShift) > 0.01) {\n    // Keep the center 50% at base color, then ramp shift across outer 25% on each side.\n    float centerBandHalfWidth = 0.2;\n    float edgeBandWidth = 0.5;\n    float distanceFromCenter = abs(x - centerX);\n    float edgeFactor = clamp((distanceFromCenter - centerBandHalfWidth) / edgeBandWidth, 0.0, 1.0);\n    vec3 hsv = rgb2hsv(color);\n    // Hue shift is zero in the center band and strongest at far edges.\n    hsv.x = fract(hsv.x + edgeFactor * uColorShift * 0.3);\n    color = hsv2rgb(hsv);\n  }\n\n  // Apply line intensity\n  color *= line;\n\n  // Add dithering for smoother gradients\n  // color += (randFibo(fragCoord).x - 0.5) / 255.0;\n\n  // Calculate alpha based on line intensity\n  float alpha = line * uMix;\n\n  fragColor = vec4(color * uMix, alpha);\n}`\n\ninterface WaveShaderProps {\n  /**\n   * Class name\n   * @default ''\n   */\n  className?: string\n  /**\n   * Speed of the oscilloscope\n   * @default 10\n   */\n  speed?: number\n  /**\n   * Amplitude of the oscilloscope\n   * @default 0.02\n   */\n  amplitude?: number\n  /**\n   * Frequency of the oscilloscope\n   * @default 20.0\n   */\n  frequency?: number\n  /**\n   * Color of the oscilloscope in hexidecimal format.\n   * @default '#1FD5F9'\n   */\n  color?: `#${string}`\n  /**\n   * Hue shift amount applied toward the outside of the wave. Center remains at the base color.\n   * @default 0.05\n   */\n  colorShift?: number\n  /**\n   * Mix of the oscilloscope\n   * @default 1.0\n   */\n  mix?: number\n  /**\n   * Line width of the oscilloscope in pixels\n   * @default 2.0\n   */\n  lineWidth?: number\n  /**\n   * Blur of the oscilloscope in pixels\n   * @default 0.5\n   */\n  blur?: number\n}\n\nfunction WaveShader({\n  speed = 10,\n  color = \"#1FD5F9\",\n  colorShift = 0.05,\n  mix = 1.0,\n  amplitude = 0.02,\n  frequency = 20.0,\n  lineWidth = 2.0,\n  blur = 0.5,\n  ref,\n  className,\n  ...props\n}: WaveShaderProps & ComponentProps<\"div\">) {\n  const rgbColor = useMemo(() => hexToRgb(color), [color])\n\n  return (\n    <div ref={ref} className={className} {...props}>\n      <ReactShaderToy\n        fs={shaderSource}\n        devicePixelRatio={globalThis.devicePixelRatio ?? 1}\n        uniforms={{\n          uSpeed: { type: \"1f\", value: speed },\n          uAmplitude: { type: \"1f\", value: amplitude },\n          uFrequency: { type: \"1f\", value: frequency },\n          uMix: { type: \"1f\", value: mix },\n          uLineWidth: { type: \"1f\", value: lineWidth },\n          uSmoothing: { type: \"1f\", value: blur },\n          uColor: { type: \"3fv\", value: rgbColor },\n          uColorShift: { type: \"1f\", value: colorShift },\n        }}\n        onError={(error) => {\n          console.error(\"Shader error:\", error)\n        }}\n        onWarning={(warning) => {\n          console.warn(\"Shader warning:\", warning)\n        }}\n        style={{ width: \"100%\", height: \"100%\" }}\n      />\n    </div>\n  )\n}\n\nWaveShader.displayName = \"WaveShader\"\n\nexport const AgentAudioVisualizerWaveVariants = cva([\"aspect-square\"], {\n  variants: {\n    size: {\n      icon: \"h-[24px]\",\n      sm: \"h-[56px]\",\n      md: \"h-[112px]\",\n      lg: \"h-[224px]\",\n      xl: \"h-[448px]\",\n    },\n  },\n  defaultVariants: {\n    size: \"lg\",\n  },\n})\n\nexport interface AgentAudioVisualizerWaveProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'lg'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The agent state.\n   * @defaultValue 'speaking'\n   */\n  state?: AgentState\n  /**\n   * The color of the wave in hexidecimal format.\n   * @defaultValue '#1FD5F9'\n   */\n  color?: `#${string}`\n  /**\n   * The color shift of the wave. Higher values increase hue variation toward the edges.\n   * @defaultValue 0.05\n   */\n  colorShift?: number\n  /**\n   * The line width of the wave in pixels.\n   * @defaultValue 2.0\n   */\n  lineWidth?: number\n  /**\n   * The blur of the wave in pixels.\n   * @defaultValue 0.5\n   */\n  blur?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume value (0-1) to use instead of the value computed from the audioTrack.\n   */\n  volume?: number\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\n/**\n * A wave-style audio visualizer that responds to agent state and audio levels.\n * Displays an animated wave that reacts to the current agent state (connecting, thinking, speaking, etc.)\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example ```tsx\n * <AgentAudioVisualizerWave\n *   size=\"lg\"\n *   state=\"speaking\"\n *   color=\"#1FD5F9\"\n *   colorShift={0.3}\n *   lineWidth={2}\n *   blur={0.5}\n *   audioTrack={audioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerWave({\n  size = \"lg\",\n  state = \"speaking\",\n  color,\n  colorShift = 0.05,\n  lineWidth,\n  blur,\n  audioTrack,\n  volume,\n  className,\n  ref,\n  ...props\n}: AgentAudioVisualizerWaveProps &\n  ComponentProps<\"div\"> &\n  VariantProps<typeof AgentAudioVisualizerWaveVariants>) {\n  const _lineWidth = useMemo(() => {\n    if (lineWidth !== undefined) {\n      return lineWidth\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 2\n      default:\n        return 1\n    }\n  }, [lineWidth, size])\n\n  const { speed, amplitude, frequency, opacity } = useAgentAudioVisualizerWave({\n    state,\n    audioTrack,\n    volume,\n  })\n\n  return (\n    <WaveShader\n      ref={ref}\n      data-lk-state={state}\n      speed={speed}\n      color={color}\n      colorShift={colorShift}\n      mix={opacity}\n      amplitude={amplitude}\n      frequency={frequency}\n      lineWidth={_lineWidth}\n      blur={blur}\n      className={cn(\n        AgentAudioVisualizerWaveVariants({ size }),\n        \"mask-[linear-gradient(90deg,transparent_0%,black_20%,black_80%,transparent_100%)]\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave.ts",
          "type": "registry:component",
          "content": "import {\n  useTrackVolume,\n  type AgentState,\n  type TrackReference,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport {\n  animate,\n  useMotionValue,\n  useMotionValueEvent,\n  useReducedMotion,\n  type AnimationPlaybackControlsWithThen,\n  type ValueAnimationTransition,\n} from \"motion/react\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nconst DEFAULT_SPEED = 5\nconst DEFAULT_AMPLITUDE = 0.025\nconst DEFAULT_FREQUENCY = 10\nconst DEFAULT_TRANSITION: ValueAnimationTransition = {\n  duration: 0.2,\n  ease: \"easeOut\",\n}\n\nfunction useAnimatedValue<T>(initialValue: T) {\n  const [value, setValue] = useState(initialValue)\n  const motionValue = useMotionValue(initialValue)\n  const controlsRef = useRef<AnimationPlaybackControlsWithThen | null>(null)\n  useMotionValueEvent(motionValue, \"change\", (value) => setValue(value as T))\n\n  const animateFn = useCallback(\n    (targetValue: T | T[], transition: ValueAnimationTransition) => {\n      controlsRef.current = animate(motionValue, targetValue, transition)\n    },\n    [motionValue]\n  )\n\n  return { value, controls: controlsRef, animate: animateFn }\n}\n\ninterface UseAgentAudioVisualizerWaveAnimatorArgs {\n  state?: AgentState\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  volume?: number\n}\n\nexport function useAgentAudioVisualizerWave({\n  state,\n  audioTrack,\n  volume: volumeProp,\n}: UseAgentAudioVisualizerWaveAnimatorArgs) {\n  const prefersReducedMotion = useReducedMotion()\n  const [speed, setSpeed] = useState(DEFAULT_SPEED)\n  const { value: amplitude, animate: animateAmplitude } =\n    useAnimatedValue(DEFAULT_AMPLITUDE)\n  const { value: frequency, animate: animateFrequency } =\n    useAnimatedValue(DEFAULT_FREQUENCY)\n  const { value: opacity, animate: animateOpacity } = useAnimatedValue(1.0)\n\n  const trackVolume = useTrackVolume(audioTrack as TrackReference, {\n    fftSize: 512,\n    smoothingTimeConstant: 0.55,\n  })\n  const volume = volumeProp ?? trackVolume\n\n  useEffect(() => {\n    switch (state) {\n      case \"disconnected\":\n        setSpeed(DEFAULT_SPEED)\n        animateAmplitude(0, DEFAULT_TRANSITION)\n        animateFrequency(0, DEFAULT_TRANSITION)\n        animateOpacity(1.0, DEFAULT_TRANSITION)\n        return\n      case \"listening\":\n        setSpeed(DEFAULT_SPEED)\n        animateAmplitude(DEFAULT_AMPLITUDE, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY, DEFAULT_TRANSITION)\n        animateOpacity(\n          prefersReducedMotion ? 0.65 : [1.0, 0.3],\n          prefersReducedMotion\n            ? { duration: 0 }\n            : { duration: 0.75, repeat: Infinity, repeatType: \"mirror\" }\n        )\n        return\n      case \"thinking\":\n      case \"connecting\":\n      case \"initializing\":\n        setSpeed(DEFAULT_SPEED * 4)\n        animateAmplitude(DEFAULT_AMPLITUDE / 4, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY * 4, DEFAULT_TRANSITION)\n        animateOpacity(\n          prefersReducedMotion ? 0.65 : [1.0, 0.3],\n          prefersReducedMotion\n            ? { duration: 0 }\n            : { duration: 0.4, repeat: Infinity, repeatType: \"mirror\" }\n        )\n        return\n      case \"speaking\":\n      default:\n        setSpeed(DEFAULT_SPEED * 2)\n        animateAmplitude(DEFAULT_AMPLITUDE, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY, DEFAULT_TRANSITION)\n        animateOpacity(1.0, DEFAULT_TRANSITION)\n        return\n    }\n  }, [\n    state,\n    setSpeed,\n    animateAmplitude,\n    animateFrequency,\n    animateOpacity,\n    prefersReducedMotion,\n  ])\n\n  useEffect(() => {\n    if (state === \"speaking\") {\n      animateAmplitude(0.015 + 0.4 * volume, { duration: 0 })\n      animateFrequency(20 + 60 * volume, { duration: 0 })\n    }\n  }, [state, volume, animateAmplitude, animateFrequency])\n\n  return {\n    speed,\n    amplitude,\n    frequency,\n    opacity,\n  }\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/react-shader-toy.tsx",
          "target": "@components/voice-agents/livekit/react-shader-toy.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n/**\n * @license\n *\n * MIT License\n *\n * Copyright (c) 2018 Morgan Villedieu\n * Copyright (c) 2023 Rysana, Inc. (forked from the above)\n * Copyright (c) 2026 LiveKit, Inc. (forked from the above)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport React, { useEffect, useRef, type ComponentPropsWithoutRef } from \"react\"\n\nconst PRECISIONS = [\"lowp\", \"mediump\", \"highp\"]\nconst FS_MAIN_SHADER = `\\nvoid main(void){\n    vec4 color = vec4(0.0,0.0,0.0,1.0);\n    mainImage( color, gl_FragCoord.xy );\n    gl_FragColor = color;\n}`\nconst BASIC_FS = `void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n    vec2 uv = fragCoord/iResolution.xy;\n    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));\n    fragColor = vec4(col,1.0);\n}`\nconst BASIC_VS = `attribute vec3 aVertexPosition;\nvoid main(void) {\n    gl_Position = vec4(aVertexPosition, 1.0);\n}`\nconst UNIFORM_TIME = \"iTime\"\nconst UNIFORM_TIMEDELTA = \"iTimeDelta\"\nconst UNIFORM_DATE = \"iDate\"\nconst UNIFORM_FRAME = \"iFrame\"\nconst UNIFORM_MOUSE = \"iMouse\"\nconst UNIFORM_RESOLUTION = \"iResolution\"\nconst UNIFORM_CHANNEL = \"iChannel\"\nconst UNIFORM_CHANNELRESOLUTION = \"iChannelResolution\"\nconst UNIFORM_DEVICEORIENTATION = \"iDeviceOrientation\"\n\ntype Vector4<T = number> = [T, T, T, T]\ntype UniformType = keyof Uniforms\n\nfunction isMatrixType(t: string, v: number[] | number): v is number[] {\n  return t.includes(\"Matrix\") && Array.isArray(v)\n}\nfunction isVectorListType(t: string, v: number[] | number): v is number[] {\n  return (\n    t.includes(\"v\") &&\n    Array.isArray(v) &&\n    v.length > Number.parseInt(t.charAt(0))\n  )\n}\nfunction isVectorType(t: string, v: number[] | number): v is Vector4 {\n  return (\n    !t.includes(\"v\") &&\n    Array.isArray(v) &&\n    v.length > Number.parseInt(t.charAt(0))\n  )\n}\nconst processUniform = <T extends UniformType>(\n  gl: WebGLRenderingContext,\n  location: WebGLUniformLocation,\n  t: T,\n  value: number | number[]\n) => {\n  if (isVectorType(t, value)) {\n    switch (t) {\n      case \"2f\":\n        return gl.uniform2f(location, value[0], value[1])\n      case \"3f\":\n        return gl.uniform3f(location, value[0], value[1], value[2])\n      case \"4f\":\n        return gl.uniform4f(location, value[0], value[1], value[2], value[3])\n      case \"2i\":\n        return gl.uniform2i(location, value[0], value[1])\n      case \"3i\":\n        return gl.uniform3i(location, value[0], value[1], value[2])\n      case \"4i\":\n        return gl.uniform4i(location, value[0], value[1], value[2], value[3])\n    }\n  }\n  if (typeof value === \"number\") {\n    switch (t) {\n      case \"1i\":\n        return gl.uniform1i(location, value)\n      default:\n        return gl.uniform1f(location, value)\n    }\n  }\n  switch (t) {\n    case \"1iv\":\n      return gl.uniform1iv(location, value)\n    case \"2iv\":\n      return gl.uniform2iv(location, value)\n    case \"3iv\":\n      return gl.uniform3iv(location, value)\n    case \"4iv\":\n      return gl.uniform4iv(location, value)\n    case \"1fv\":\n      return gl.uniform1fv(location, value)\n    case \"2fv\":\n      return gl.uniform2fv(location, value)\n    case \"3fv\":\n      return gl.uniform3fv(location, value)\n    case \"4fv\":\n      return gl.uniform4fv(location, value)\n    case \"Matrix2fv\":\n      return gl.uniformMatrix2fv(location, false, value)\n    case \"Matrix3fv\":\n      return gl.uniformMatrix3fv(location, false, value)\n    case \"Matrix4fv\":\n      return gl.uniformMatrix4fv(location, false, value)\n  }\n}\n\nconst uniformTypeToGLSLType = (t: string) => {\n  switch (t) {\n    case \"1f\":\n      return \"float\"\n    case \"2f\":\n      return \"vec2\"\n    case \"3f\":\n      return \"vec3\"\n    case \"4f\":\n      return \"vec4\"\n    case \"1i\":\n      return \"int\"\n    case \"2i\":\n      return \"ivec2\"\n    case \"3i\":\n      return \"ivec3\"\n    case \"4i\":\n      return \"ivec4\"\n    case \"1iv\":\n      return \"int\"\n    case \"2iv\":\n      return \"ivec2\"\n    case \"3iv\":\n      return \"ivec3\"\n    case \"4iv\":\n      return \"ivec4\"\n    case \"1fv\":\n      return \"float\"\n    case \"2fv\":\n      return \"vec2\"\n    case \"3fv\":\n      return \"vec3\"\n    case \"4fv\":\n      return \"vec4\"\n    case \"Matrix2fv\":\n      return \"mat2\"\n    case \"Matrix3fv\":\n      return \"mat3\"\n    case \"Matrix4fv\":\n      return \"mat4\"\n    default:\n      console.error(\n        log(\n          `The uniform type \"${t}\" is not valid, please make sure your uniform type is valid`\n        )\n      )\n  }\n}\n\nconst LinearFilter = 9729\nconst NearestFilter = 9728\nconst LinearMipMapLinearFilter = 9987\nconst ClampToEdgeWrapping = 33071\nconst RepeatWrapping = 10497\n\nclass Texture {\n  gl: WebGLRenderingContext\n  url?: string\n  wrapS?: number\n  wrapT?: number\n  minFilter?: number\n  magFilter?: number\n  source?: HTMLImageElement | HTMLVideoElement\n  pow2canvas?: HTMLCanvasElement\n  isLoaded = false\n  isVideo = false\n  flipY = -1\n  width = 0\n  height = 0\n  _webglTexture: WebGLTexture | null = null\n  constructor(gl: WebGLRenderingContext) {\n    this.gl = gl\n  }\n  updateTexture = (\n    texture: WebGLTexture,\n    video: HTMLVideoElement,\n    flipY: number\n  ) => {\n    const { gl } = this\n    const level = 0\n    const internalFormat = gl.RGBA\n    const srcFormat = gl.RGBA\n    const srcType = gl.UNSIGNED_BYTE\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      srcFormat,\n      srcType,\n      video\n    )\n  }\n  setupVideo = (url: string) => {\n    const video = document.createElement(\"video\")\n    let playing = false\n    let timeupdate = false\n    video.autoplay = true\n    video.muted = true\n    video.loop = true\n    video.crossOrigin = \"anonymous\"\n    const checkReady = () => {\n      if (playing && timeupdate) {\n        this.isLoaded = true\n      }\n    }\n    video.addEventListener(\n      \"playing\",\n      () => {\n        playing = true\n        this.width = video.videoWidth || 0\n        this.height = video.videoHeight || 0\n        checkReady()\n      },\n      true\n    )\n    video.addEventListener(\n      \"timeupdate\",\n      () => {\n        timeupdate = true\n        checkReady()\n      },\n      true\n    )\n    video.src = url\n    return video\n  }\n  makePowerOf2 = <T extends HTMLCanvasElement | HTMLImageElement | ImageBitmap>(\n    image: T\n  ): T => {\n    if (\n      image instanceof HTMLImageElement ||\n      image instanceof HTMLCanvasElement ||\n      image instanceof ImageBitmap\n    ) {\n      if (this.pow2canvas === undefined)\n        this.pow2canvas = document.createElement(\"canvas\")\n      this.pow2canvas.width = 2 ** Math.floor(Math.log(image.width) / Math.LN2)\n      this.pow2canvas.height =\n        2 ** Math.floor(Math.log(image.height) / Math.LN2)\n      const context = this.pow2canvas.getContext(\"2d\")\n      context?.drawImage(\n        image,\n        0,\n        0,\n        this.pow2canvas.width,\n        this.pow2canvas.height\n      )\n      console.warn(\n        log(\n          `Image is not power of two ${image.width} x ${image.height}. Resized to ${this.pow2canvas.width} x ${this.pow2canvas.height};`\n        )\n      )\n      return this.pow2canvas as T\n    }\n    return image\n  }\n  load = async (textureArgs: TextureParams) => {\n    const { gl } = this\n    const {\n      url,\n      wrapS,\n      wrapT,\n      minFilter,\n      magFilter,\n      flipY = -1,\n    }: TextureParams = textureArgs\n    if (!url) {\n      return Promise.reject(\n        new Error(\n          log(\n            \"Missing url, please make sure to pass the url of your texture { url: ... }\"\n          )\n        )\n      )\n    }\n    const isImage = /(\\.jpg|\\.jpeg|\\.png|\\.gif|\\.bmp)$/i.exec(url)\n    const isVideo = /(\\.mp4|\\.3gp|\\.webm|\\.ogv)$/i.exec(url)\n    if (isImage === null && isVideo === null) {\n      return Promise.reject(\n        new Error(\n          log(\n            `Please upload a video or an image with a valid format (url: ${url})`\n          )\n        )\n      )\n    }\n    Object.assign(this, { url, wrapS, wrapT, minFilter, magFilter, flipY })\n    const level = 0\n    const internalFormat = gl.RGBA\n    const width = 1\n    const height = 1\n    const border = 0\n    const srcFormat = gl.RGBA\n    const srcType = gl.UNSIGNED_BYTE\n    const pixel = new Uint8Array([255, 255, 255, 0])\n    const texture = gl.createTexture()\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      width,\n      height,\n      border,\n      srcFormat,\n      srcType,\n      pixel\n    )\n    if (isVideo) {\n      const video = this.setupVideo(url)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)\n      this._webglTexture = texture\n      this.source = video\n      this.isVideo = true\n      return video.play().then(() => this)\n    }\n    async function loadImage() {\n      return new Promise((resolve, reject) => {\n        const image = new Image()\n        image.crossOrigin = \"anonymous\"\n        image.onload = () => {\n          resolve(image)\n        }\n        image.onerror = () => {\n          reject(new Error(log(`failed loading url: ${url}`)))\n        }\n        image.src = url ?? \"\"\n      })\n    }\n    let image = (await loadImage()) as HTMLImageElement\n    let isPowerOf2 =\n      (image.width & (image.width - 1)) === 0 &&\n      (image.height & (image.height - 1)) === 0\n    if (\n      (textureArgs.wrapS !== ClampToEdgeWrapping ||\n        textureArgs.wrapT !== ClampToEdgeWrapping ||\n        (textureArgs.minFilter !== NearestFilter &&\n          textureArgs.minFilter !== LinearFilter)) &&\n      !isPowerOf2\n    ) {\n      image = this.makePowerOf2(image)\n      isPowerOf2 = true\n    }\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      srcFormat,\n      srcType,\n      image\n    )\n    if (\n      isPowerOf2 &&\n      textureArgs.minFilter !== NearestFilter &&\n      textureArgs.minFilter !== LinearFilter\n    ) {\n      gl.generateMipmap(gl.TEXTURE_2D)\n    }\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_WRAP_S,\n      this.wrapS || RepeatWrapping\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_WRAP_T,\n      this.wrapT || RepeatWrapping\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_MIN_FILTER,\n      this.minFilter || LinearMipMapLinearFilter\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_MAG_FILTER,\n      this.magFilter || LinearFilter\n    )\n    this._webglTexture = texture\n    this.source = image\n    this.isVideo = false\n    this.isLoaded = true\n    this.width = image.width || 0\n    this.height = image.height || 0\n    return this\n  }\n}\n\nconst log = (text: string) => `react-shaders: ${text}`\n\nconst latestPointerClientCoords = (e: MouseEvent | TouchEvent) => {\n  if (\"changedTouches\" in e) {\n    const t = e.changedTouches[0]\n    return [t?.clientX ?? 0, t?.clientY ?? 0]\n  }\n  return [e.clientX, e.clientY]\n}\n\nconst lerpVal = (v0: number, v1: number, t: number) => v0 * (1 - t) + v1 * t\nconst insertStringAtIndex = (\n  currentString: string,\n  string: string,\n  index: number\n) =>\n  index > 0\n    ? currentString.substring(0, index) +\n      string +\n      currentString.substring(index, currentString.length)\n    : string + currentString\n\ntype Uniform = { type: string; value: number[] | number }\ntype Uniforms = Record<string, Uniform>\ntype TextureParams = {\n  url: string\n  wrapS?: number\n  wrapT?: number\n  minFilter?: number\n  magFilter?: number\n  flipY?: number\n}\n\nexport interface ReactShaderToyProps {\n  /** Fragment shader GLSL code. */\n  fs: string\n\n  /** Vertex shader GLSL code. */\n  vs?: string\n\n  /**\n   * Textures to be passed to the shader. Textures need to be squared or will be\n   * automatically resized.\n   *\n   * Options default to:\n   *\n   * ```js\n   * {\n   *   minFilter: LinearMipMapLinearFilter,\n   *   magFilter: LinearFilter,\n   *   wrapS: RepeatWrapping,\n   *   wrapT: RepeatWrapping,\n   * }\n   * ```\n   *\n   * See [textures in the docs](https://rysana.com/docs/react-shaders#textures)\n   * for details.\n   */\n  textures?: TextureParams[]\n\n  /**\n   * Custom uniforms to be passed to the shader.\n   *\n   * See [custom uniforms in the\n   * docs](https://rysana.com/docs/react-shaders#custom-uniforms) for details.\n   */\n  uniforms?: Uniforms\n\n  /**\n   * Color used when clearing the canvas.\n   *\n   * See [the WebGL\n   * docs](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/clearColor)\n   * for details.\n   */\n  clearColor?: Vector4\n\n  /**\n   * GLSL precision qualifier. Defaults to `'highp'`. Balance between\n   * performance and quality.\n   */\n  precision?: \"highp\" | \"lowp\" | \"mediump\"\n\n  /** Custom inline style for canvas. */\n  style?: React.CSSProperties\n\n  /** Customize WebGL context attributes. See [the WebGL docs](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getContextAttributes) for details. */\n  contextAttributes?: Record<string, unknown>\n\n  /** Lerp value for `iMouse` built-in uniform. Must be between 0 and 1. */\n  lerp?: number\n\n  /** Device pixel ratio. */\n  devicePixelRatio?: number\n\n  /**\n   * Callback for when the textures are done loading. Useful if you want to do\n   * something like e.g. hide the canvas until textures are done loading.\n   */\n  onDoneLoadingTextures?: () => void\n\n  /** Custom callback to handle errors. Defaults to `console.error`. */\n  onError?: (error: string) => void\n\n  /** Custom callback to handle warnings. Defaults to `console.warn`. */\n  onWarning?: (warning: string) => void\n\n  /**\n   * When true, the animation loop runs even when the canvas is not visible in the viewport.\n   * When false (default), animation runs only while visible (uses Intersection Observer),\n   * reducing CPU/GPU usage when the shader is off-screen.\n   */\n  animateWhenNotVisible?: boolean\n}\n\nexport function ReactShaderToy({\n  fs,\n  vs = BASIC_VS,\n  textures = [],\n  uniforms: propUniforms,\n  clearColor = [0, 0, 0, 1],\n  precision = \"highp\",\n  style,\n  contextAttributes = {},\n  lerp = 1,\n  devicePixelRatio = 1,\n  onDoneLoadingTextures,\n  onError = console.error,\n  onWarning = console.warn,\n  animateWhenNotVisible = false,\n  ...canvasProps\n}: ReactShaderToyProps & ComponentPropsWithoutRef<\"canvas\">) {\n  // Refs for WebGL state\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const glRef = useRef<WebGLRenderingContext | null>(null)\n  const squareVerticesBufferRef = useRef<WebGLBuffer | null>(null)\n  const shaderProgramRef = useRef<WebGLProgram | null>(null)\n  const vertexPositionAttributeRef = useRef<number | undefined>(undefined)\n  const animFrameIdRef = useRef<number | undefined>(undefined)\n  const initFrameIdRef = useRef<number | undefined>(undefined)\n  const isVisibleRef = useRef(true)\n  const prefersReducedMotionRef = useRef(false)\n  const animateWhenNotVisibleRef = useRef(animateWhenNotVisible)\n  const mousedownRef = useRef(false)\n  const canvasPositionRef = useRef<DOMRect | undefined>(undefined)\n  const timerRef = useRef(0)\n  const lastMouseArrRef = useRef<number[]>([0, 0])\n  const texturesArrRef = useRef<Texture[]>([])\n  const lastTimeRef = useRef(0)\n  const resizeObserverRef = useRef<ResizeObserver | undefined>(undefined)\n  const uniformsRef = useRef<\n    Record<\n      string,\n      {\n        type: string\n        isNeeded: boolean\n        value?: number[] | number\n        arraySize?: string\n      }\n    >\n  >({\n    [UNIFORM_TIME]: { type: \"float\", isNeeded: false, value: 0 },\n    [UNIFORM_TIMEDELTA]: { type: \"float\", isNeeded: false, value: 0 },\n    [UNIFORM_DATE]: { type: \"vec4\", isNeeded: false, value: [0, 0, 0, 0] },\n    [UNIFORM_MOUSE]: { type: \"vec4\", isNeeded: false, value: [0, 0, 0, 0] },\n    [UNIFORM_RESOLUTION]: { type: \"vec2\", isNeeded: false, value: [0, 0] },\n    [UNIFORM_FRAME]: { type: \"int\", isNeeded: false, value: 0 },\n    [UNIFORM_DEVICEORIENTATION]: {\n      type: \"vec4\",\n      isNeeded: false,\n      value: [0, 0, 0, 0],\n    },\n  })\n  const propsUniformsRef = useRef<Uniforms | undefined>(propUniforms)\n  const resolvedDevicePixelRatio = Math.min(Math.max(devicePixelRatio, 1), 2)\n\n  const setupChannelRes = (texture: TextureParams | Texture, id: number) => {\n    const width = \"width\" in texture ? (texture.width ?? 0) : 0\n    const height = \"height\" in texture ? (texture.height ?? 0) : 0\n    const channelResUniform = uniformsRef.current.iChannelResolution\n    if (!channelResUniform) return\n    const channelResValue = Array.isArray(channelResUniform.value)\n      ? channelResUniform.value\n      : (channelResUniform.value = [])\n    channelResValue[id * 3] = width * resolvedDevicePixelRatio\n    channelResValue[id * 3 + 1] = height * resolvedDevicePixelRatio\n    channelResValue[id * 3 + 2] = 0\n  }\n\n  const initWebGL = () => {\n    if (!canvasRef.current) return\n    glRef.current = (canvasRef.current.getContext(\"webgl\", contextAttributes) ||\n      canvasRef.current.getContext(\n        \"experimental-webgl\",\n        contextAttributes\n      )) as WebGLRenderingContext | null\n    glRef.current?.getExtension(\"OES_standard_derivatives\")\n    glRef.current?.getExtension(\"EXT_shader_texture_lod\")\n  }\n\n  const initBuffers = () => {\n    const gl = glRef.current\n    squareVerticesBufferRef.current = gl?.createBuffer() ?? null\n    gl?.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBufferRef.current)\n    const vertices = [\n      1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0,\n    ]\n    gl?.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)\n  }\n\n  const onDeviceOrientationChange = ({\n    alpha,\n    beta,\n    gamma,\n  }: DeviceOrientationEvent) => {\n    uniformsRef.current.iDeviceOrientation!.value = [\n      alpha ?? 0,\n      beta ?? 0,\n      gamma ?? 0,\n      window.orientation ?? 0,\n    ]\n  }\n\n  const mouseDown = (e: MouseEvent | TouchEvent) => {\n    const [clientX = 0, clientY = 0] = latestPointerClientCoords(e)\n    const mouseX =\n      clientX - (canvasPositionRef.current?.left ?? 0) - window.pageXOffset\n    const mouseY =\n      (canvasPositionRef.current?.height ?? 0) -\n      clientY -\n      (canvasPositionRef.current?.top ?? 0) -\n      window.pageYOffset\n    mousedownRef.current = true\n    const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n      ? uniformsRef.current.iMouse.value\n      : undefined\n    if (mouseValue) {\n      mouseValue[2] = mouseX\n      mouseValue[3] = mouseY\n    }\n    lastMouseArrRef.current[0] = mouseX\n    lastMouseArrRef.current[1] = mouseY\n  }\n\n  const mouseMove = (e: MouseEvent | TouchEvent) => {\n    canvasPositionRef.current = canvasRef.current?.getBoundingClientRect()\n    const [clientX = 0, clientY = 0] = latestPointerClientCoords(e)\n    const mouseX = clientX - (canvasPositionRef.current?.left ?? 0)\n    const mouseY =\n      (canvasPositionRef.current?.height ?? 0) -\n      clientY -\n      (canvasPositionRef.current?.top ?? 0)\n    if (lerp !== 1) {\n      lastMouseArrRef.current[0] = mouseX\n      lastMouseArrRef.current[1] = mouseY\n    } else {\n      const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n        ? uniformsRef.current.iMouse.value\n        : undefined\n      if (mouseValue) {\n        mouseValue[0] = mouseX\n        mouseValue[1] = mouseY\n      }\n    }\n  }\n\n  const mouseUp = () => {\n    const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n      ? uniformsRef.current.iMouse.value\n      : undefined\n    if (mouseValue) {\n      mouseValue[2] = 0\n      mouseValue[3] = 0\n    }\n  }\n\n  const onResize = () => {\n    const gl = glRef.current\n    if (!gl) return\n    canvasPositionRef.current = canvasRef.current?.getBoundingClientRect()\n    // Force pixel ratio to be one to avoid expensive calculus on retina display.\n    const realToCSSPixels = resolvedDevicePixelRatio\n    const displayWidth = Math.floor(\n      (canvasPositionRef.current?.width ?? 1) * realToCSSPixels\n    )\n    const displayHeight = Math.floor(\n      (canvasPositionRef.current?.height ?? 1) * realToCSSPixels\n    )\n    gl.canvas.width = displayWidth\n    gl.canvas.height = displayHeight\n    if (uniformsRef.current.iResolution?.isNeeded && shaderProgramRef.current) {\n      const rUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_RESOLUTION\n      )\n      gl.uniform2fv(rUniform, [gl.canvas.width, gl.canvas.height])\n    }\n  }\n\n  const createShader = (type: number, shaderCodeAsText: string) => {\n    const gl = glRef.current\n    if (!gl) return null\n    const shader = gl.createShader(type)\n    if (!shader) return null\n    gl.shaderSource(shader, shaderCodeAsText)\n    gl.compileShader(shader)\n    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n      onWarning?.(log(`Error compiling the shader:\\n${shaderCodeAsText}`))\n      const compilationLog = gl.getShaderInfoLog(shader)\n      gl.deleteShader(shader)\n      onError?.(log(`Shader compiler log: ${compilationLog}`))\n    }\n    return shader\n  }\n\n  const initShaders = (fragmentShader: string, vertexShader: string) => {\n    const gl = glRef.current\n    if (!gl) return\n    const fragmentShaderObj = createShader(gl.FRAGMENT_SHADER, fragmentShader)\n    const vertexShaderObj = createShader(gl.VERTEX_SHADER, vertexShader)\n    shaderProgramRef.current = gl.createProgram()\n    if (!shaderProgramRef.current || !vertexShaderObj || !fragmentShaderObj)\n      return\n    gl.attachShader(shaderProgramRef.current, vertexShaderObj)\n    gl.attachShader(shaderProgramRef.current, fragmentShaderObj)\n    gl.linkProgram(shaderProgramRef.current)\n    if (!gl.getProgramParameter(shaderProgramRef.current, gl.LINK_STATUS)) {\n      onError?.(\n        log(\n          `Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgramRef.current)}`\n        )\n      )\n      return\n    }\n    gl.useProgram(shaderProgramRef.current)\n    vertexPositionAttributeRef.current = gl.getAttribLocation(\n      shaderProgramRef.current,\n      \"aVertexPosition\"\n    )\n    gl.enableVertexAttribArray(vertexPositionAttributeRef.current)\n  }\n\n  const processCustomUniforms = () => {\n    if (propUniforms) {\n      for (const name of Object.keys(propUniforms)) {\n        const uniform = propUniforms[name]\n        if (!uniform) continue\n        const { value, type } = uniform\n        const glslType = uniformTypeToGLSLType(type)\n        if (!glslType) continue\n        const tempObject: { arraySize?: string } = {}\n        if (isMatrixType(type, value)) {\n          const arrayLength = type.length\n          const val = Number.parseInt(type.charAt(arrayLength - 3))\n          const numberOfMatrices = Math.floor(value.length / (val * val))\n          if (value.length > val * val)\n            tempObject.arraySize = `[${numberOfMatrices}]`\n        } else if (isVectorListType(type, value)) {\n          tempObject.arraySize = `[${Math.floor(value.length / Number.parseInt(type.charAt(0)))}]`\n        }\n        uniformsRef.current[name] = {\n          type: glslType,\n          isNeeded: false,\n          value,\n          ...tempObject,\n        }\n      }\n    }\n  }\n\n  const processTextures = () => {\n    const gl = glRef.current\n    if (!gl) return\n    if (textures && textures.length > 0) {\n      uniformsRef.current[`${UNIFORM_CHANNELRESOLUTION}`] = {\n        type: \"vec3\",\n        isNeeded: false,\n        arraySize: `[${textures.length}]`,\n        value: [],\n      }\n      const texturePromisesArr = textures.map(\n        (texture: TextureParams, id: number) => {\n          // Dynamically add textures uniforms.\n          uniformsRef.current[`${UNIFORM_CHANNEL}${id}`] = {\n            type: \"sampler2D\",\n            isNeeded: false,\n          }\n          setupChannelRes(texture, id)\n          texturesArrRef.current[id] = new Texture(gl)\n          return texturesArrRef.current[id]\n            ?.load(texture)\n            .then((t: Texture) => {\n              setupChannelRes(t, id)\n            })\n        }\n      )\n      Promise.all(texturePromisesArr)\n        .then(() => {\n          if (onDoneLoadingTextures) onDoneLoadingTextures()\n        })\n        .catch((e) => {\n          onError?.(e)\n          if (onDoneLoadingTextures) onDoneLoadingTextures()\n        })\n    } else if (onDoneLoadingTextures) onDoneLoadingTextures()\n  }\n\n  const preProcessFragment = (fragment: string) => {\n    const isValidPrecision = PRECISIONS.includes(precision ?? \"highp\")\n    const precisionString = `precision ${isValidPrecision ? precision : PRECISIONS[1]} float;\\n`\n    if (!isValidPrecision) {\n      onWarning?.(\n        log(\n          `wrong precision type ${precision}, please make sure to pass one of a valid precision lowp, mediump, highp, by default you shader precision will be set to highp.`\n        )\n      )\n    }\n    let fragmentShader = precisionString\n      .concat(`#define DPR ${resolvedDevicePixelRatio.toFixed(1)}\\n`)\n      .concat(fragment.replace(/texture\\(/g, \"texture2D(\"))\n    for (const uniform of Object.keys(uniformsRef.current)) {\n      if (fragment.includes(uniform)) {\n        const u = uniformsRef.current[uniform]\n        if (!u) continue\n        fragmentShader = insertStringAtIndex(\n          fragmentShader,\n          `uniform ${u.type} ${uniform}${u.arraySize || \"\"}; \\n`,\n          fragmentShader.lastIndexOf(precisionString) + precisionString.length\n        )\n        u.isNeeded = true\n      }\n    }\n    const isShadertoy = fragment.includes(\"mainImage\")\n    if (isShadertoy) fragmentShader = fragmentShader.concat(FS_MAIN_SHADER)\n    return fragmentShader\n  }\n\n  const setUniforms = (timestamp: number) => {\n    const gl = glRef.current\n    if (!gl || !shaderProgramRef.current) return\n    const delta = lastTimeRef.current\n      ? (timestamp - lastTimeRef.current) / 1000\n      : 0\n    lastTimeRef.current = timestamp\n    const propUniforms = propsUniformsRef.current\n    if (propUniforms) {\n      for (const name of Object.keys(propUniforms)) {\n        const currentUniform = propUniforms[name]\n        if (!currentUniform) continue\n        if (uniformsRef.current[name]?.isNeeded) {\n          if (!shaderProgramRef.current) return\n          const customUniformLocation = gl.getUniformLocation(\n            shaderProgramRef.current,\n            name\n          )\n          if (!customUniformLocation) return\n          processUniform(\n            gl,\n            customUniformLocation,\n            currentUniform.type as UniformType,\n            currentUniform.value\n          )\n        }\n      }\n    }\n    if (uniformsRef.current.iMouse?.isNeeded) {\n      const mouseUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_MOUSE\n      )\n      gl.uniform4fv(mouseUniform, uniformsRef.current.iMouse.value as number[])\n    }\n    if (uniformsRef.current.iChannelResolution?.isNeeded) {\n      const channelResUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_CHANNELRESOLUTION\n      )\n      gl.uniform3fv(\n        channelResUniform,\n        uniformsRef.current.iChannelResolution.value as number[]\n      )\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      const deviceOrientationUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_DEVICEORIENTATION\n      )\n      gl.uniform4fv(\n        deviceOrientationUniform,\n        uniformsRef.current.iDeviceOrientation.value as number[]\n      )\n    }\n    if (uniformsRef.current.iTime?.isNeeded) {\n      const timeUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_TIME\n      )\n      gl.uniform1f(timeUniform, (timerRef.current += delta))\n    }\n    if (uniformsRef.current.iTimeDelta?.isNeeded) {\n      const timeDeltaUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_TIMEDELTA\n      )\n      gl.uniform1f(timeDeltaUniform, delta)\n    }\n    if (uniformsRef.current.iDate?.isNeeded) {\n      const d = new Date()\n      const month = d.getMonth() + 1\n      const day = d.getDate()\n      const year = d.getFullYear()\n      const time =\n        d.getHours() * 60 * 60 +\n        d.getMinutes() * 60 +\n        d.getSeconds() +\n        d.getMilliseconds() * 0.001\n      const dateUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_DATE\n      )\n      gl.uniform4fv(dateUniform, [year, month, day, time])\n    }\n    if (uniformsRef.current.iFrame?.isNeeded) {\n      const timeDeltaUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_FRAME\n      )\n      const frame = uniformsRef.current.iFrame.value as number\n      gl.uniform1i(timeDeltaUniform, frame)\n      uniformsRef.current.iFrame.value = frame + 1\n    }\n    if (texturesArrRef.current.length > 0) {\n      for (let index = 0; index < texturesArrRef.current.length; index++) {\n        const texture = texturesArrRef.current[index]\n        if (!texture) return\n        const { isVideo, _webglTexture, source, flipY, isLoaded } = texture\n        if (!isLoaded || !_webglTexture || !source) return\n        if (uniformsRef.current[`iChannel${index}`]?.isNeeded) {\n          if (!shaderProgramRef.current) return\n          const iChannel = gl.getUniformLocation(\n            shaderProgramRef.current,\n            `iChannel${index}`\n          )\n          gl.activeTexture(gl.TEXTURE0 + index)\n          gl.bindTexture(gl.TEXTURE_2D, _webglTexture)\n          gl.uniform1i(iChannel, index)\n          if (isVideo) {\n            texture.updateTexture(\n              _webglTexture,\n              source as HTMLVideoElement,\n              flipY\n            )\n          }\n        }\n      }\n    }\n  }\n\n  const drawScene = (timestamp: number) => {\n    const gl = glRef.current\n    if (!gl) return\n    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight)\n    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)\n    gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBufferRef.current)\n    gl.vertexAttribPointer(\n      vertexPositionAttributeRef.current ?? 0,\n      3,\n      gl.FLOAT,\n      false,\n      0,\n      0\n    )\n    setUniforms(timestamp)\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\n    const mouseValue = uniformsRef.current.iMouse?.value\n    if (\n      uniformsRef.current.iMouse?.isNeeded &&\n      lerp !== 1 &&\n      Array.isArray(mouseValue)\n    ) {\n      const currentX = mouseValue[0] ?? 0\n      const currentY = mouseValue[1] ?? 0\n      mouseValue[0] = lerpVal(currentX, lastMouseArrRef.current[0] ?? 0, lerp)\n      mouseValue[1] = lerpVal(currentY, lastMouseArrRef.current[1] ?? 0, lerp)\n    }\n    if (\n      !prefersReducedMotionRef.current &&\n      (animateWhenNotVisibleRef.current || isVisibleRef.current)\n    ) {\n      animFrameIdRef.current = requestAnimationFrame(drawScene)\n    }\n  }\n\n  const addEventListeners = () => {\n    const options = { passive: true }\n    if (uniformsRef.current.iMouse?.isNeeded && canvasRef.current) {\n      canvasRef.current.addEventListener(\"mousemove\", mouseMove, options)\n      canvasRef.current.addEventListener(\"mouseout\", mouseUp, options)\n      canvasRef.current.addEventListener(\"mouseup\", mouseUp, options)\n      canvasRef.current.addEventListener(\"mousedown\", mouseDown, options)\n      canvasRef.current.addEventListener(\"touchmove\", mouseMove, options)\n      canvasRef.current.addEventListener(\"touchend\", mouseUp, options)\n      canvasRef.current.addEventListener(\"touchstart\", mouseDown, options)\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      window.addEventListener(\n        \"deviceorientation\",\n        onDeviceOrientationChange,\n        options\n      )\n    }\n    if (canvasRef.current) {\n      resizeObserverRef.current = new ResizeObserver(onResize)\n      resizeObserverRef.current.observe(canvasRef.current)\n      window.addEventListener(\"resize\", onResize, options)\n    }\n  }\n\n  const removeEventListeners = () => {\n    const options = { passive: true } as EventListenerOptions\n    if (uniformsRef.current.iMouse?.isNeeded && canvasRef.current) {\n      canvasRef.current.removeEventListener(\"mousemove\", mouseMove, options)\n      canvasRef.current.removeEventListener(\"mouseout\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"mouseup\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"mousedown\", mouseDown, options)\n      canvasRef.current.removeEventListener(\"touchmove\", mouseMove, options)\n      canvasRef.current.removeEventListener(\"touchend\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"touchstart\", mouseDown, options)\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      window.removeEventListener(\n        \"deviceorientation\",\n        onDeviceOrientationChange,\n        options\n      )\n    }\n    if (resizeObserverRef.current) {\n      resizeObserverRef.current.disconnect()\n      window.removeEventListener(\"resize\", onResize, options)\n    }\n  }\n\n  useEffect(() => {\n    propsUniformsRef.current = propUniforms\n  }, [propUniforms])\n\n  useEffect(() => {\n    animateWhenNotVisibleRef.current = animateWhenNotVisible\n    if (animateWhenNotVisible) {\n      isVisibleRef.current = true\n    }\n  }, [animateWhenNotVisible])\n\n  useEffect(() => {\n    const media = window.matchMedia(\"(prefers-reduced-motion: reduce)\")\n    const update = () => {\n      prefersReducedMotionRef.current = media.matches\n      if (media.matches) {\n        cancelAnimationFrame(animFrameIdRef.current ?? 0)\n        requestAnimationFrame(drawScene)\n      } else if (animateWhenNotVisibleRef.current || isVisibleRef.current) {\n        requestAnimationFrame(drawScene)\n      }\n    }\n    update()\n    media.addEventListener(\"change\", update)\n    return () => media.removeEventListener(\"change\", update)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [])\n\n  // Intersection Observer: pause animation when off-screen when animateWhenNotVisible is false\n  useEffect(() => {\n    if (animateWhenNotVisible || !canvasRef.current) return\n    const canvas = canvasRef.current\n    const observer = new IntersectionObserver(\n      (entries) => {\n        for (const entry of entries) {\n          isVisibleRef.current = entry.isIntersecting\n          if (entry.isIntersecting) {\n            requestAnimationFrame(drawScene)\n          }\n        }\n      },\n      { threshold: 0 }\n    )\n    observer.observe(canvas)\n    return () => observer.disconnect()\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [animateWhenNotVisible])\n\n  // Main effect for initialization and cleanup\n  useEffect(() => {\n    const textures = texturesArrRef.current\n\n    function init() {\n      initWebGL()\n      const gl = glRef.current\n      if (gl && canvasRef.current) {\n        gl.clearColor(...clearColor)\n        gl.clearDepth(1.0)\n        gl.enable(gl.DEPTH_TEST)\n        gl.depthFunc(gl.LEQUAL)\n        gl.viewport(0, 0, canvasRef.current.width, canvasRef.current.height)\n        canvasRef.current.height = canvasRef.current.clientHeight\n        canvasRef.current.width = canvasRef.current.clientWidth\n        processCustomUniforms()\n        processTextures()\n        initShaders(preProcessFragment(fs || BASIC_FS), vs || BASIC_VS)\n        initBuffers()\n        requestAnimationFrame(drawScene)\n        addEventListeners()\n        onResize()\n      }\n    }\n\n    initFrameIdRef.current = requestAnimationFrame(init)\n\n    // Cleanup function\n    return () => {\n      const gl = glRef.current\n      if (gl) {\n        gl.getExtension(\"WEBGL_lose_context\")?.loseContext()\n        gl.useProgram(null)\n        gl.deleteProgram(shaderProgramRef.current ?? null)\n        if (textures.length > 0) {\n          for (const texture of textures as Texture[]) {\n            gl.deleteTexture(texture._webglTexture)\n          }\n        }\n        shaderProgramRef.current = null\n      }\n      removeEventListeners()\n      cancelAnimationFrame(initFrameIdRef.current ?? 0)\n      cancelAnimationFrame(animFrameIdRef.current ?? 0)\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []) // Empty dependency array to run only once on mount\n\n  return (\n    <canvas\n      ref={canvasRef}\n      style={{ height: \"100%\", width: \"100%\", ...style }}\n      {...canvasProps}\n    />\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-session-view-01",
      "type": "registry:block",
      "title": "Livekit Agent Session View 01",
      "description": "Agent Session View",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "radix-ui@1.6.7",
        "streamdown@2.4.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/blocks/agent-session-view-01/components/agent-session-block.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-session-view-01/components/agent-session-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { type AgentAudioVisualizerBarProps } from \"@/components/voice-agents/livekit/agent-audio-visualizer-bar\"\nimport { type AgentAudioVisualizerGridProps } from \"@/components/voice-agents/livekit/agent-audio-visualizer-grid\"\nimport { type AgentAudioVisualizerRadialProps } from \"@/components/voice-agents/livekit/agent-audio-visualizer-radial\"\nimport { type AgentAudioVisualizerWaveProps } from \"@/components/voice-agents/livekit/agent-audio-visualizer-wave\"\nimport { AgentChatTranscript } from \"@/components/voice-agents/livekit/agent-chat-transcript\"\nimport {\n  AgentControlBar,\n  type AgentControlBarControls,\n} from \"@/components/voice-agents/livekit/agent-control-bar\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useAgent,\n  useSessionContext,\n  useSessionMessages,\n} from \"@livekit/components-react\"\nimport { AnimatePresence, motion, type MotionProps } from \"motion/react\"\nimport React, { useEffect, useRef, useState } from \"react\"\nimport { TileLayout } from \"./tile-view\"\n\n/**\n * Configures the visualizer style rendered in the main tile area. `type` selects the\n * visualizer, and the remaining fields are exactly the props of the matching\n * `AgentAudioVisualizer*` component (e.g. `type: 'grid'` accepts `rowCount`/`columnCount`,\n * `type: 'wave'` accepts `lineWidth`, etc).\n */\nexport type AudioVisualizerConfig =\n  | ({ type?: \"bar\" } & AgentAudioVisualizerBarProps)\n  | ({ type: \"wave\" } & AgentAudioVisualizerWaveProps)\n  | ({ type: \"grid\" } & AgentAudioVisualizerGridProps)\n  | ({ type: \"radial\" } & AgentAudioVisualizerRadialProps)\n\nconst DEFAULT_CONTROLS: AgentControlBarControls = {\n  leave: true,\n  microphone: true,\n  chat: false,\n  camera: false,\n  screenShare: false,\n}\n\nconst BOTTOM_VIEW_MOTION_PROPS: MotionProps = {\n  variants: {\n    visible: {\n      opacity: 1,\n      translateY: \"0%\",\n    },\n    hidden: {\n      opacity: 0,\n      translateY: \"100%\",\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n  transition: {\n    duration: 0.3,\n    delay: 0.5,\n    ease: \"easeOut\",\n  },\n}\n\nconst CHAT_MOTION_PROPS: MotionProps = {\n  variants: {\n    hidden: {\n      opacity: 0,\n      transition: {\n        ease: \"easeOut\",\n        duration: 0.3,\n      },\n    },\n    visible: {\n      opacity: 1,\n      transition: {\n        delay: 0.2,\n        ease: \"easeOut\",\n        duration: 0.3,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\nconst SHIMMER_MOTION_PROPS: MotionProps = {\n  variants: {\n    visible: {\n      opacity: 1,\n      transition: {\n        ease: \"easeIn\",\n        duration: 0.5,\n        delay: 0.8,\n      },\n    },\n    hidden: {\n      opacity: 0,\n      transition: {\n        ease: \"easeIn\",\n        duration: 0.5,\n        delay: 0,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\ninterface FadeProps {\n  top?: boolean\n  bottom?: boolean\n  className?: string\n}\n\nexport function Fade({ top = false, bottom = false, className }: FadeProps) {\n  return (\n    <div\n      className={cn(\n        \"from-background pointer-events-none h-4 bg-linear-to-b to-transparent\",\n        top && \"bg-linear-to-b\",\n        bottom && \"bg-linear-to-t\",\n        className\n      )}\n    />\n  )\n}\n\nexport interface AgentSessionView_01Props {\n  /**\n   * Retained for API compatibility with LiveKit's complete block.\n   * This distribution omits the separately licensed aura visualizer.\n   */\n  themeMode?: \"dark\" | \"light\"\n  /**\n   * Message shown above the controls before the first chat message is sent.\n   *\n   * @default 'Agent is listening, ask it a question'\n   */\n  preConnectMessage?: string\n  /**\n   * An object with the following keys: leave, microphone, screenShare, camera, chat.\n   * Each key maps to a boolean value that determines whether the control is displayed.\n   *\n   * @default {\n   *   leave: true,\n   *   microphone: true,\n   *   chat: false,\n   *   camera: false,\n   *   screenShare: false,\n   * }\n   */\n  controls?: AgentControlBarControls\n  /** Whether device choices are read from and saved to local storage. */\n  saveUserChoices?: boolean\n  /**\n   * Shows a pre-connect buffer state with a shimmer message before messages appear.\n   *\n   * @default true\n   */\n  isPreConnectBufferEnabled?: boolean\n  /**\n   * Configures the visualizer style rendered in the main tile area.\n   *\n   * @default { type: 'bar' }\n   */\n  audioVisualizer?: AudioVisualizerConfig\n  /** Optional class name merged onto the outer `<section>` container. */\n  className?: string\n  /** Called when the user clicks the leave control, in addition to ending the session. */\n  onDisconnect?: () => void\n}\n\nexport function AgentSessionView_01({\n  preConnectMessage = \"Agent is listening, ask it a question\",\n  controls = DEFAULT_CONTROLS,\n  saveUserChoices = true,\n  isPreConnectBufferEnabled = true,\n  audioVisualizer = { type: \"bar\" },\n  themeMode,\n  onDisconnect,\n  ref,\n  className,\n  ...props\n}: React.ComponentProps<\"section\"> & AgentSessionView_01Props) {\n  const session = useSessionContext()\n  const { messages } = useSessionMessages(session)\n  const [isChatOpen, setIsChatOpen] = useState(false)\n  const scrollAreaRef = useRef<HTMLDivElement>(null)\n  const { state: agentState } = useAgent()\n\n  useEffect(() => {\n    const lastMessage = messages.at(-1)\n    const lastMessageIsLocal = lastMessage?.from?.isLocal === true\n\n    if (scrollAreaRef.current && lastMessageIsLocal) {\n      scrollAreaRef.current.scrollTop = scrollAreaRef.current.scrollHeight\n    }\n  }, [messages])\n\n  const finalControls = {\n    ...DEFAULT_CONTROLS,\n    ...controls,\n  }\n\n  return (\n    <section\n      ref={ref}\n      data-theme-mode={themeMode}\n      className={cn(\n        \"bg-background @container/agent-session-block relative z-10 h-full w-full overflow-hidden\",\n        className\n      )}\n      {...props}\n    >\n      <Fade top className=\"absolute inset-x-4 top-0 z-10 h-40\" />\n      {/* transcript */}\n      <AnimatePresence>\n        {isChatOpen && (\n          <motion.div\n            {...CHAT_MOTION_PROPS}\n            className=\"absolute inset-x-0 top-0 bottom-[135px] overflow-hidden @md/agent-session-block:bottom-[170px]\"\n          >\n            <AgentChatTranscript\n              agentState={agentState}\n              messages={messages}\n              className=\"mx-auto max-w-2xl **:data-[slot=message-scroller-content]:p-4 **:data-[slot=message-scroller-content]:pt-40! @md/agent-session-block:**:data-[slot=message-scroller-content]:p-6\"\n            />\n          </motion.div>\n        )}\n      </AnimatePresence>\n\n      {/* Tile layout */}\n      <TileLayout isChatOpen={isChatOpen} audioVisualizer={audioVisualizer} />\n\n      {/* Bottom */}\n      <motion.div\n        {...BOTTOM_VIEW_MOTION_PROPS}\n        className=\"absolute inset-x-3 bottom-0 z-50 @md/agent-session-block:inset-x-12\"\n      >\n        {/* Pre-connect message */}\n        {isPreConnectBufferEnabled && (\n          <AnimatePresence>\n            {messages.length === 0 && (\n              <motion.p\n                key=\"pre-connect-message\"\n                aria-hidden={messages.length > 0}\n                {...SHIMMER_MOTION_PROPS}\n                className=\"shimmer shimmer-duration-2000 text-muted-foreground pointer-events-none mx-auto block w-full max-w-2xl pb-4 text-center text-sm\"\n              >\n                {preConnectMessage}\n              </motion.p>\n            )}\n          </AnimatePresence>\n        )}\n        <div className=\"bg-background relative mx-auto max-w-2xl pb-3 @md/agent-session-block:pb-12\">\n          <AgentControlBar\n            variant=\"livekit\"\n            controls={finalControls}\n            isChatOpen={isChatOpen}\n            isConnected={session.isConnected}\n            saveUserChoices={saveUserChoices}\n            onDisconnect={onDisconnect ?? session.end}\n            onIsChatOpenChange={setIsChatOpen}\n          />\n        </div>\n      </motion.div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerBarAnimator } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { type LocalAudioTrack, type RemoteAudioTrack } from \"livekit-client\"\nimport React, {\n  Children,\n  cloneElement,\n  isValidElement,\n  useMemo,\n  type ComponentProps,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nfunction cloneSingleChild(\n  children: ReactNode | ReactNode[],\n  props?: Record<string, unknown>,\n  key?: unknown\n) {\n  return Children.map(children, (child) => {\n    // Checking isValidElement is the safe way and avoids a typescript error too.\n    if (isValidElement(child) && Children.only(children)) {\n      const childProps = child.props as Record<string, unknown>\n      if (childProps.className) {\n        // make sure we retain classnames of both passed props and child\n        props ??= {}\n        props.className = cn(\n          childProps.className as string,\n          props.className as string\n        )\n        props.style = {\n          ...(childProps.style as CSSProperties),\n          ...(props.style as CSSProperties),\n        }\n      }\n      return cloneElement(child, {\n        ...props,\n        key: key ? String(key) : undefined,\n      })\n    }\n    return child\n  })\n}\n\nexport const AgentAudioVisualizerBarElementVariants = cva(\n  [\n    \"rounded-full transition-colors duration-250 ease-linear\",\n    \"bg-current/10 data-[lk-highlighted=true]:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: \"w-[4px] min-h-[4px]\",\n        sm: \"w-[8px] min-h-[8px]\",\n        md: \"w-[16px] min-h-[16px]\",\n        lg: \"w-[32px] min-h-[32px]\",\n        xl: \"w-[64px] min-h-[64px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\nexport const AgentAudioVisualizerBarVariants = cva(\n  \"relative flex items-center justify-center\",\n  {\n    variants: {\n      size: {\n        icon: \"h-[24px] gap-[2px]\",\n        sm: \"h-[56px] gap-[4px]\",\n        md: \"h-[112px] gap-[8px]\",\n        lg: \"h-[224px] gap-[16px]\",\n        xl: \"h-[448px] gap-[32px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentAudioVisualizerBar component.\n */\nexport interface AgentAudioVisualizerBarProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the bars in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The number of bars to display in the visualizer.\n   * If not provided, defaults based on size: 3 for 'icon'/'sm', 5 for others.\n   */\n  barCount?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match barCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Custom div element to render as grid cells. Each child receives data-lk-index,\n   * data-lk-highlighted props and style props for height. Must be a single div element.\n   */\n  children?: ReactNode\n}\n\n/**\n * A bar-style audio visualizer that responds to agent state and audio levels.\n * Displays animated bars that react to the current agent state (connecting, thinking, speaking, etc.)\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerBar\n *   size=\"md\"\n *   state=\"speaking\"\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerBar({\n  size = \"md\",\n  state = \"connecting\",\n  color,\n  barCount,\n  audioTrack,\n  volumeBands,\n  className,\n  children,\n  style,\n  ...props\n}: AgentAudioVisualizerBarProps &\n  VariantProps<typeof AgentAudioVisualizerBarVariants> &\n  ComponentProps<\"div\">) {\n  const _barCount = useMemo(() => {\n    if (barCount) {\n      return barCount\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 3\n      default:\n        return 5\n    }\n  }, [barCount, size])\n\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: _barCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, _barCount)\n    : multibandVolume\n\n  const sequencerInterval = useMemo(() => {\n    switch (state) {\n      case \"connecting\":\n        return 2000 / _barCount\n      case \"initializing\":\n        return 2000\n      case \"listening\":\n        return 500\n      case \"thinking\":\n        return 150\n      default:\n        return 1000\n    }\n  }, [state, _barCount])\n\n  const highlightedIndices = useAgentAudioVisualizerBarAnimator(\n    state,\n    _barCount,\n    sequencerInterval\n  )\n\n  const bands = useMemo(\n    () =>\n      state === \"speaking\" ? resolvedVolumeBands : new Array(_barCount).fill(0),\n    [state, resolvedVolumeBands, _barCount]\n  )\n\n  if (children && Array.isArray(children)) {\n    throw new Error(\n      \"AgentAudioVisualizerBar children must be a single element.\"\n    )\n  }\n\n  return (\n    <div\n      data-lk-state={state}\n      style={{ ...style, color } as CSSProperties}\n      className={cn(AgentAudioVisualizerBarVariants({ size }), className)}\n      {...props}\n    >\n      {bands.map((band: number, idx: number) =>\n        children ? (\n          <React.Fragment key={idx}>\n            {cloneSingleChild(children, {\n              \"data-lk-index\": idx,\n              \"data-lk-highlighted\": highlightedIndices.includes(idx),\n              style: { height: `${band * 100}%` },\n            })}\n          </React.Fragment>\n        ) : (\n          <div\n            key={idx}\n            data-lk-index={idx}\n            data-lk-highlighted={highlightedIndices.includes(idx)}\n            style={{ height: `${band * 100}%` }}\n            className={cn(AgentAudioVisualizerBarElementVariants({ size }))}\n          />\n        )\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nfunction generateConnectingSequenceBar(columns: number): number[][] {\n  const seq = []\n\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, columns - 1 - x])\n  }\n\n  return seq\n}\n\nfunction generateListeningSequenceBar(columns: number): number[][] {\n  const center = Math.floor(columns / 2)\n  const noIndex = -1\n\n  return [[center], [noIndex]]\n}\n\nexport function useAgentAudioVisualizerBarAnimator(\n  state: AgentState | undefined,\n  columns: number,\n  interval: number\n): number[] {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<number[][]>([[]])\n\n  useEffect(() => {\n    if (state === \"thinking\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      const sequence = [...generateConnectingSequenceBar(columns)]\n      setSequence(sequence)\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === undefined || state === \"speaking\") {\n      setSequence([new Array(columns).fill(0).map((_, idx) => idx)])\n    } else {\n      setSequence([[]])\n    }\n    setIndex(0)\n  }, [state, columns])\n\n  const animationFrameId = useRef<number | null>(null)\n  useEffect(() => {\n    if (prefersReducedMotion || sequence.length <= 1) return\n\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        setIndex((prev) => prev + 1)\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, columns, state, sequence.length, prefersReducedMotion])\n\n  return sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? []\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-grid.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-grid.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  useAgentAudioVisualizerGridAnimator,\n  type Coordinate,\n} from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport type { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport React, {\n  Children,\n  cloneElement,\n  isValidElement,\n  memo,\n  useMemo,\n  type ComponentProps,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nfunction cloneSingleChild(\n  children: ReactNode | ReactNode[],\n  props?: Record<string, unknown>,\n  key?: unknown\n) {\n  return Children.map(children, (child) => {\n    // Checking isValidElement is the safe way and avoids a typescript error too.\n    if (isValidElement(child) && Children.only(children)) {\n      const childProps = child.props as Record<string, unknown>\n      if (childProps.className) {\n        // make sure we retain classnames of both passed props and child\n        props ??= {}\n        props.className = cn(\n          childProps.className as string,\n          props.className as string\n        )\n        props.style = {\n          ...(childProps.style as CSSProperties),\n          ...(props.style as CSSProperties),\n        }\n      }\n      return cloneElement(child, {\n        ...props,\n        key: key ? String(key) : undefined,\n      })\n    }\n    return child\n  })\n}\n\nexport const AgentAudioVisualizerGridCellVariants = cva(\n  [\n    \"w-1 h-1 rounded-full bg-current/10 place-self-center transition-all ease-out\",\n    \"data-[lk-highlighted=true]:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: [\"w-[2px] h-[2px]\"],\n        sm: [\"w-[4px] h-[4px]\"],\n        md: [\"w-[8px] h-[8px]\"],\n        lg: [\"w-[12px] h-[12px]\"],\n        xl: [\"w-[16px] h-[16px]\"],\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\nexport const AgentAudioVisualizerGridVariants = cva(\"grid\", {\n  variants: {\n    size: {\n      icon: [\"gap-[2px]\"],\n      sm: [\"gap-[4px]\"],\n      md: [\"gap-[8px]\"],\n      lg: [\"gap-[12px]\"],\n      xl: [\"gap-[16px]\"],\n    },\n  },\n  defaultVariants: {\n    size: \"md\",\n  },\n})\n\n/**\n * Configuration options for the grid visualizer.\n */\nexport interface GridOptions {\n  /**\n   * The radius for the animation spread effect.\n   */\n  radius?: number\n  /**\n   * The interval in milliseconds between animation frames.\n   * @defaultValue 100\n   */\n  interval?: number\n  /**\n   * The number of rows in the grid.\n   * @defaultValue 5\n   */\n  rowCount?: number\n  /**\n   * The number of columns in the grid.\n   * @defaultValue 5\n   */\n  columnCount?: number\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\nconst sizeDefaults = {\n  icon: 3,\n  sm: 5,\n  md: 5,\n  lg: 5,\n  xl: 5,\n}\n\nfunction useGrid(\n  size: VariantProps<typeof AgentAudioVisualizerGridVariants>[\"size\"] = \"md\",\n  columnCount = sizeDefaults[size as keyof typeof sizeDefaults],\n  rowCount = sizeDefaults[size as keyof typeof sizeDefaults]\n) {\n  return useMemo(() => {\n    const _columnCount = columnCount\n    const _rowCount = rowCount ?? columnCount\n    const items = new Array(_columnCount * _rowCount)\n      .fill(0)\n      .map((_, idx) => idx)\n\n    return { columnCount: _columnCount, rowCount: _rowCount, items }\n  }, [columnCount, rowCount])\n}\n\ninterface GridCellProps {\n  index: number\n  state: AgentState\n  interval: number\n  rowCount: number\n  columnCount: number\n  volumeBands: number[]\n  highlightedCoordinate: Coordinate\n  children?: ReactNode\n}\n\nconst GridCell = memo(function GridCell({\n  index,\n  state,\n  interval,\n  rowCount,\n  columnCount,\n  volumeBands,\n  highlightedCoordinate,\n  children,\n}: GridCellProps) {\n  if (state === \"speaking\") {\n    const y = Math.floor(index / columnCount)\n    const rowMidPoint = Math.floor(rowCount / 2)\n    const volumeChunks = 1 / (rowMidPoint + 1)\n    const distanceToMid = Math.abs(rowMidPoint - y)\n    const threshold = distanceToMid * volumeChunks\n    const isHighlighted = (volumeBands[index % columnCount] ?? 0) >= threshold\n\n    return cloneSingleChild(children, {\n      \"data-lk-index\": index,\n      \"data-lk-highlighted\": isHighlighted,\n    })\n  }\n\n  const isHighlighted =\n    highlightedCoordinate.x === index % columnCount &&\n    highlightedCoordinate.y === Math.floor(index / columnCount)\n\n  const transitionDurationInSeconds = interval / (isHighlighted ? 1000 : 100)\n\n  return cloneSingleChild(children, {\n    \"data-lk-index\": index,\n    \"data-lk-highlighted\": isHighlighted,\n    style: {\n      transitionDuration: `${transitionDurationInSeconds}s`,\n    },\n  })\n})\n\n/**\n * Props for the AgentAudioVisualizerGrid component.\n */\nexport type AgentAudioVisualizerGridProps = GridOptions & {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the grid cells in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match columnCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Custom element to render as grid cells. Each child receives data-lk-index\n   * and data-lk-highlighted props.\n   */\n  children?: ReactNode\n} & VariantProps<typeof AgentAudioVisualizerGridVariants>\n\n/**\n * A grid-style audio visualizer that responds to agent state and audio levels.\n * Displays an animated grid of cells that react to the current agent state\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerGrid\n *   size=\"md\"\n *   state=\"speaking\"\n *   rowCount={5}\n *   columnCount={5}\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerGrid({\n  size = \"md\",\n  state = \"connecting\",\n  radius,\n  color,\n  rowCount: _rowCount = 5,\n  columnCount: _columnCount = 5,\n  interval = 100,\n  className,\n  children,\n  audioTrack,\n  volumeBands,\n  style,\n  ...props\n}: AgentAudioVisualizerGridProps & ComponentProps<\"div\">) {\n  const { columnCount, rowCount, items } = useGrid(\n    size,\n    _columnCount,\n    _rowCount\n  )\n  const highlightedCoordinate = useAgentAudioVisualizerGridAnimator(\n    state,\n    rowCount,\n    columnCount,\n    interval,\n    radius\n  )\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: columnCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, columnCount)\n    : multibandVolume\n\n  if (children && Array.isArray(children)) {\n    throw new Error(\n      \"AgentAudioVisualizerGrid children must be a single element.\"\n    )\n  }\n\n  return (\n    <div\n      data-lk-state={state}\n      className={cn(AgentAudioVisualizerGridVariants({ size }), className)}\n      style={\n        {\n          ...style,\n          gridTemplateColumns: `repeat(${columnCount}, 1fr)`,\n          color,\n        } as CSSProperties\n      }\n      {...props}\n    >\n      {items.map((idx) => (\n        <GridCell\n          key={idx}\n          index={idx}\n          state={state}\n          interval={interval}\n          rowCount={rowCount}\n          columnCount={columnCount}\n          volumeBands={resolvedVolumeBands}\n          highlightedCoordinate={highlightedCoordinate}\n        >\n          {children ?? (\n            <div className={AgentAudioVisualizerGridCellVariants({ size })} />\n          )}\n        </GridCell>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useState } from \"react\"\n\nexport interface Coordinate {\n  x: number\n  y: number\n}\n\nexport function generateConnectingSequence(\n  rows: number,\n  columns: number,\n  radius: number\n) {\n  const seq = []\n  const centerY = Math.floor(rows / 2)\n\n  // Calculate the boundaries of the ring based on the ring distance\n  const topLeft = {\n    x: Math.max(0, centerY - radius),\n    y: Math.max(0, centerY - radius),\n  }\n  const bottomRight = {\n    x: columns - 1 - topLeft.x,\n    y: Math.min(rows - 1, centerY + radius),\n  }\n\n  // Top edge\n  for (let x = topLeft.x; x <= bottomRight.x; x++) {\n    seq.push({ x, y: topLeft.y })\n  }\n\n  // Right edge\n  for (let y = topLeft.y + 1; y <= bottomRight.y; y++) {\n    seq.push({ x: bottomRight.x, y })\n  }\n\n  // Bottom edge\n  for (let x = bottomRight.x - 1; x >= topLeft.x; x--) {\n    seq.push({ x, y: bottomRight.y })\n  }\n\n  // Left edge\n  for (let y = bottomRight.y - 1; y > topLeft.y; y--) {\n    seq.push({ x: topLeft.x, y })\n  }\n\n  return seq\n}\n\nexport function generateListeningSequence(rows: number, columns: number) {\n  const center = { x: Math.floor(columns / 2), y: Math.floor(rows / 2) }\n  const noIndex = { x: -1, y: -1 }\n\n  return [\n    center,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n  ]\n}\n\nexport function generateThinkingSequence(rows: number, columns: number) {\n  const seq = []\n  const y = Math.floor(rows / 2)\n  for (let x = 0; x < columns; x++) {\n    seq.push({ x, y })\n  }\n  for (let x = columns - 1; x >= 0; x--) {\n    seq.push({ x, y })\n  }\n\n  return seq\n}\n\nexport function useAgentAudioVisualizerGridAnimator(\n  state: AgentState,\n  rows: number,\n  columns: number,\n  interval: number,\n  radius?: number\n): Coordinate {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<Coordinate[]>(() => [\n    {\n      x: Math.floor(columns / 2),\n      y: Math.floor(rows / 2),\n    },\n  ])\n\n  useEffect(() => {\n    const clampedRadius = radius\n      ? Math.min(radius, Math.floor(Math.max(rows, columns) / 2))\n      : Math.floor(Math.max(rows, columns) / 2)\n\n    if (state === \"thinking\") {\n      setSequence(generateThinkingSequence(rows, columns))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      const sequence = [\n        ...generateConnectingSequence(rows, columns, clampedRadius),\n      ]\n      setSequence(sequence)\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequence(rows, columns))\n    } else {\n      setSequence([{ x: Math.floor(columns / 2), y: Math.floor(rows / 2) }])\n    }\n    setIndex(0)\n  }, [state, rows, columns, radius])\n\n  useEffect(() => {\n    if (state === \"speaking\" || prefersReducedMotion) {\n      return\n    }\n\n    const indexInterval = setInterval(() => {\n      setIndex((prev) => {\n        return prev + 1\n      })\n    }, interval)\n\n    return () => clearInterval(indexInterval)\n  }, [interval, columns, rows, state, sequence.length, prefersReducedMotion])\n\n  return (\n    sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? {\n      x: Math.floor(columns / 2),\n      y: Math.floor(rows / 2),\n    }\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-radial.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-radial.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerRadialAnimator } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { type LocalAudioTrack, type RemoteAudioTrack } from \"livekit-client\"\nimport { useMemo, type ComponentProps, type CSSProperties } from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nexport const AgentAudioVisualizerRadialVariants = cva(\n  [\n    \"relative flex items-center justify-center\",\n    \"**:data-lk-index:bg-current/10\",\n    \"**:data-lk-index:absolute **:data-lk-index:top-1/2 **:data-lk-index:left-1/2 **:data-lk-index:origin-bottom **:data-lk-index:-translate-x-1/2\",\n    \"**:data-lk-index:rounded-full **:data-lk-index:transition-colors **:data-lk-index:duration-150 **:data-lk-index:ease-linear **:data-lk-index:data-[lk-highlighted=true]:bg-current\",\n    \"has-data-[lk-state=connecting]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=initializing]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=listening]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=thinking]:animate-spin has-data-[lk-state=thinking]:[animation-duration:5s] motion-reduce:animate-none has-data-[lk-state=thinking]:**:data-lk-index:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: [\"h-[24px] gap-[2px]\"],\n        sm: [\"h-[56px] gap-[4px]\"],\n        md: [\"h-[112px] gap-[8px]\"],\n        lg: [\"h-[224px] gap-[16px]\"],\n        xl: [\"h-[448px] gap-[32px]\"],\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentAudioVisualizerRadial component.\n */\nexport interface AgentAudioVisualizerRadialProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the radial bars in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The radius (distance from center) for the radial bars.\n   * If not provided, defaults based on size.\n   */\n  radius?: number\n  /**\n   * The number of bars to display around the circle.\n   * Should be divisible by 4 for optimal visual results.\n   * If not provided, defaults to 12 for 'icon'/'sm', 24 for others.\n   */\n  barCount?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match barCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\n/**\n * A radial (circular) audio visualizer that responds to agent state and audio levels.\n * Displays animated bars arranged in a circle that react to the current agent state\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerRadial\n *   size=\"lg\"\n *   state=\"speaking\"\n *   barCount={24}\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerRadial({\n  size = \"md\",\n  state = \"connecting\",\n  color,\n  radius,\n  barCount,\n  audioTrack,\n  volumeBands,\n  className,\n  style,\n  ...props\n}: AgentAudioVisualizerRadialProps &\n  ComponentProps<\"div\"> &\n  VariantProps<typeof AgentAudioVisualizerRadialVariants>) {\n  const _barCount = useMemo(() => {\n    if (barCount) {\n      return barCount\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 12\n      default:\n        return 24\n    }\n  }, [barCount, size])\n\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: _barCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, _barCount)\n    : multibandVolume\n\n  const sequencerInterval = useMemo(() => {\n    switch (state) {\n      case \"connecting\":\n      case \"listening\":\n        return 500\n      case \"initializing\":\n        return 250\n      case \"thinking\":\n        return Infinity\n      default:\n        return 1000\n    }\n  }, [state])\n\n  const distanceFromCenter = useMemo(() => {\n    if (radius) {\n      return radius\n    }\n    switch (size) {\n      case \"icon\":\n        return 6\n      case \"xl\":\n        return 128\n      case \"lg\":\n        return 64\n      case \"sm\":\n        return 16\n      case \"md\":\n      default:\n        return 32\n    }\n  }, [size, radius])\n\n  if (_barCount % 4 !== 0) {\n    console.warn(\"barCount should be divisible by 4 for optimal visual results\")\n  }\n\n  const highlightedIndices = useAgentAudioVisualizerRadialAnimator(\n    state,\n    _barCount,\n    sequencerInterval\n  )\n\n  const dotSize = useMemo(() => {\n    return (distanceFromCenter * Math.PI) / _barCount\n  }, [distanceFromCenter, _barCount])\n\n  return (\n    <div\n      data-lk-state={state}\n      className={cn(\n        AgentAudioVisualizerRadialVariants({ size }),\n        \"relative\",\n        className\n      )}\n      style={{ ...style, color } as CSSProperties}\n      {...props}\n    >\n      {resolvedVolumeBands.map((band, idx) => {\n        const angle = (idx / _barCount) * Math.PI * 2\n\n        return (\n          <div\n            key={`${_barCount}-${idx}`}\n            data-lk-state={state}\n            className=\"absolute top-1/2 left-1/2 h-1 w-1 -translate-x-1/2 -translate-y-1/2\"\n            style={{\n              transformOrigin: \"center\",\n              transform: `rotate(${angle}rad) translateY(${distanceFromCenter}px)`,\n            }}\n          >\n            <div\n              data-lk-index={idx}\n              data-lk-highlighted={highlightedIndices.includes(idx)}\n              style={{\n                width: dotSize,\n                minHeight: dotSize,\n                height: state === \"speaking\" ? `${dotSize * 10 * band}px` : 0,\n              }}\n            />\n          </div>\n        )\n      })}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nfunction findGcdLessThan(columns: number, max: number = columns): number {\n  function gcd(a: number, b: number): number {\n    while (b !== 0) {\n      const t = b\n      b = a % b\n      a = t\n    }\n    return a\n  }\n  for (let i = max; i >= 1; i--) {\n    if (gcd(columns, i) === i) {\n      return i\n    }\n  }\n  return 1\n}\n\nfunction generateConnectingSequenceBar(columns: number): number[][] {\n  const seq = []\n  const center = Math.floor(columns / 2)\n\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, (x + center) % columns])\n  }\n\n  return seq\n}\n\nfunction generateListeningSequenceBar(columns: number): number[][] {\n  const divisor =\n    columns > 8\n      ? columns / findGcdLessThan(columns, 4)\n      : findGcdLessThan(columns, 2)\n\n  return Array.from({ length: divisor }, (_, idx) => [\n    ...Array(Math.floor(columns / divisor))\n      .fill(1)\n      .map((_, idx2) => idx2 * divisor + idx),\n  ])\n}\n\nexport const useAgentAudioVisualizerRadialAnimator = (\n  state: AgentState | undefined,\n  barCount: number,\n  interval: number\n): number[] => {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<number[][]>([[]])\n\n  useEffect(() => {\n    if (state === \"thinking\") {\n      setSequence(generateListeningSequenceBar(barCount))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      setSequence(generateConnectingSequenceBar(barCount))\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequenceBar(barCount))\n    } else if (state === undefined || state === \"speaking\") {\n      setSequence([new Array(barCount).fill(0).map((_, idx) => idx)])\n    } else {\n      setSequence([[]])\n    }\n    setIndex(0)\n  }, [state, barCount])\n\n  const animationFrameId = useRef<number | null>(null)\n  useEffect(() => {\n    if (\n      prefersReducedMotion ||\n      sequence.length <= 1 ||\n      !Number.isFinite(interval)\n    )\n      return\n\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        setIndex((prev) => prev + 1)\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, barCount, state, sequence.length, prefersReducedMotion])\n\n  return sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? []\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-wave.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-wave.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerWave } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave\"\nimport { ReactShaderToy } from \"@/components/voice-agents/livekit/react-shader-toy\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport type { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport { useMemo, type ComponentProps } from \"react\"\n\nconst DEFAULT_COLOR = \"#1FD5F9\"\n\nfunction hexToRgb(hexColor: string) {\n  try {\n    const rgbColor = hexColor.match(\n      /^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n    )\n\n    if (rgbColor) {\n      const [, r, g, b] = rgbColor\n      const color = [r, g, b].map((c = \"00\") => parseInt(c, 16) / 255)\n\n      return color\n    }\n  } catch {\n    console.error(\n      `Invalid hex color '${hexColor}'.\\nFalling back to default color '${DEFAULT_COLOR}'.`\n    )\n  }\n\n  return hexToRgb(DEFAULT_COLOR)\n}\n\nconst shaderSource = `\nconst float TAU = 6.28318530718;\n\n// Noise for dithering\nvec2 randFibo(vec2 p) {\n  p = fract(p * vec2(443.897, 441.423));\n  p += dot(p, p.yx + 19.19);\n  return fract((p.xx + p.yx) * p.xy);\n}\n\n// Luma for alpha\nfloat luma(vec3 color) {\n  return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\n// RGB to HSV\nvec3 rgb2hsv(vec3 c) {\n  vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n  vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n  vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n  float d = q.x - min(q.w, q.y);\n  float e = 1.0e-10;\n  return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\n// HSV to RGB\nvec3 hsv2rgb(vec3 c) {\n  vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n  vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n  return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\n// Bell curve function for attenuation from center with rounded top\nfloat bellCurve(float distanceFromCenter, float maxDistance) {\n  float normalizedDistance = distanceFromCenter / maxDistance;\n  // Use cosine with high power for smooth rounded top\n  return pow(cos(normalizedDistance * (3.14159265359 / 4.0)), 16.0);\n}\n\n// Calculate the sine wave\nfloat oscilloscopeWave(float x, float centerX, float time) {\n  float relativeX = x - centerX;\n  float maxDistance = centerX;\n  float distanceFromCenter = abs(relativeX);\n\n  // Apply bell curve for amplitude attenuation\n  float bell = bellCurve(distanceFromCenter, maxDistance);\n\n  // Calculate wave with uniforms and bell curve attenuation\n  float wave = sin(relativeX * uFrequency + time * uSpeed) * uAmplitude * bell;\n\n  return wave;\n}\n\nvoid mainImage(out vec4 fragColor, in vec2 fragCoord) {\n  vec2 uv = fragCoord / iResolution.xy;\n  vec2 pos = uv - 0.5;\n\n  // Calculate center and positions\n  float centerX = 0.5;\n  float centerY = 0.5;\n  float x = uv.x;\n  float y = uv.y;\n\n  // Convert line width from pixels to UV space\n  // Use the average of width and height to handle aspect ratio\n  float pixelSize = 2.0 / (iResolution.x + iResolution.y);\n  float lineWidthUV = uLineWidth * pixelSize;\n  float smoothingUV = uSmoothing * pixelSize;\n\n  // Find minimum distance to the wave by sampling nearby points\n  // This gives us consistent line width without high-frequency artifacts\n  const int NUM_SAMPLES = 50; // Must be const for GLSL loop\n  float minDist = 1000.0;\n  float sampleRange = 0.02; // Range to search for closest point\n\n  for(int i = 0; i < NUM_SAMPLES; i++) {\n    float offset = (float(i) / float(NUM_SAMPLES - 1) - 0.5) * sampleRange;\n    float sampleX = x + offset;\n    float waveY = centerY + oscilloscopeWave(sampleX, centerX, iTime);\n\n    // Calculate distance from current pixel to this point on the wave\n    vec2 wavePoint = vec2(sampleX, waveY);\n    vec2 currentPoint = vec2(x, y);\n    float dist = distance(currentPoint, wavePoint);\n\n    minDist = min(minDist, dist);\n  }\n\n  // Solid line with smooth edges using minimum distance\n  float line = smoothstep(lineWidthUV + smoothingUV, lineWidthUV - smoothingUV, minDist);\n\n  vec3 color = uColor;\n  if(abs(uColorShift) > 0.01) {\n    // Keep the center 50% at base color, then ramp shift across outer 25% on each side.\n    float centerBandHalfWidth = 0.2;\n    float edgeBandWidth = 0.5;\n    float distanceFromCenter = abs(x - centerX);\n    float edgeFactor = clamp((distanceFromCenter - centerBandHalfWidth) / edgeBandWidth, 0.0, 1.0);\n    vec3 hsv = rgb2hsv(color);\n    // Hue shift is zero in the center band and strongest at far edges.\n    hsv.x = fract(hsv.x + edgeFactor * uColorShift * 0.3);\n    color = hsv2rgb(hsv);\n  }\n\n  // Apply line intensity\n  color *= line;\n\n  // Add dithering for smoother gradients\n  // color += (randFibo(fragCoord).x - 0.5) / 255.0;\n\n  // Calculate alpha based on line intensity\n  float alpha = line * uMix;\n\n  fragColor = vec4(color * uMix, alpha);\n}`\n\ninterface WaveShaderProps {\n  /**\n   * Class name\n   * @default ''\n   */\n  className?: string\n  /**\n   * Speed of the oscilloscope\n   * @default 10\n   */\n  speed?: number\n  /**\n   * Amplitude of the oscilloscope\n   * @default 0.02\n   */\n  amplitude?: number\n  /**\n   * Frequency of the oscilloscope\n   * @default 20.0\n   */\n  frequency?: number\n  /**\n   * Color of the oscilloscope in hexidecimal format.\n   * @default '#1FD5F9'\n   */\n  color?: `#${string}`\n  /**\n   * Hue shift amount applied toward the outside of the wave. Center remains at the base color.\n   * @default 0.05\n   */\n  colorShift?: number\n  /**\n   * Mix of the oscilloscope\n   * @default 1.0\n   */\n  mix?: number\n  /**\n   * Line width of the oscilloscope in pixels\n   * @default 2.0\n   */\n  lineWidth?: number\n  /**\n   * Blur of the oscilloscope in pixels\n   * @default 0.5\n   */\n  blur?: number\n}\n\nfunction WaveShader({\n  speed = 10,\n  color = \"#1FD5F9\",\n  colorShift = 0.05,\n  mix = 1.0,\n  amplitude = 0.02,\n  frequency = 20.0,\n  lineWidth = 2.0,\n  blur = 0.5,\n  ref,\n  className,\n  ...props\n}: WaveShaderProps & ComponentProps<\"div\">) {\n  const rgbColor = useMemo(() => hexToRgb(color), [color])\n\n  return (\n    <div ref={ref} className={className} {...props}>\n      <ReactShaderToy\n        fs={shaderSource}\n        devicePixelRatio={globalThis.devicePixelRatio ?? 1}\n        uniforms={{\n          uSpeed: { type: \"1f\", value: speed },\n          uAmplitude: { type: \"1f\", value: amplitude },\n          uFrequency: { type: \"1f\", value: frequency },\n          uMix: { type: \"1f\", value: mix },\n          uLineWidth: { type: \"1f\", value: lineWidth },\n          uSmoothing: { type: \"1f\", value: blur },\n          uColor: { type: \"3fv\", value: rgbColor },\n          uColorShift: { type: \"1f\", value: colorShift },\n        }}\n        onError={(error) => {\n          console.error(\"Shader error:\", error)\n        }}\n        onWarning={(warning) => {\n          console.warn(\"Shader warning:\", warning)\n        }}\n        style={{ width: \"100%\", height: \"100%\" }}\n      />\n    </div>\n  )\n}\n\nWaveShader.displayName = \"WaveShader\"\n\nexport const AgentAudioVisualizerWaveVariants = cva([\"aspect-square\"], {\n  variants: {\n    size: {\n      icon: \"h-[24px]\",\n      sm: \"h-[56px]\",\n      md: \"h-[112px]\",\n      lg: \"h-[224px]\",\n      xl: \"h-[448px]\",\n    },\n  },\n  defaultVariants: {\n    size: \"lg\",\n  },\n})\n\nexport interface AgentAudioVisualizerWaveProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'lg'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The agent state.\n   * @defaultValue 'speaking'\n   */\n  state?: AgentState\n  /**\n   * The color of the wave in hexidecimal format.\n   * @defaultValue '#1FD5F9'\n   */\n  color?: `#${string}`\n  /**\n   * The color shift of the wave. Higher values increase hue variation toward the edges.\n   * @defaultValue 0.05\n   */\n  colorShift?: number\n  /**\n   * The line width of the wave in pixels.\n   * @defaultValue 2.0\n   */\n  lineWidth?: number\n  /**\n   * The blur of the wave in pixels.\n   * @defaultValue 0.5\n   */\n  blur?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume value (0-1) to use instead of the value computed from the audioTrack.\n   */\n  volume?: number\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\n/**\n * A wave-style audio visualizer that responds to agent state and audio levels.\n * Displays an animated wave that reacts to the current agent state (connecting, thinking, speaking, etc.)\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example ```tsx\n * <AgentAudioVisualizerWave\n *   size=\"lg\"\n *   state=\"speaking\"\n *   color=\"#1FD5F9\"\n *   colorShift={0.3}\n *   lineWidth={2}\n *   blur={0.5}\n *   audioTrack={audioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerWave({\n  size = \"lg\",\n  state = \"speaking\",\n  color,\n  colorShift = 0.05,\n  lineWidth,\n  blur,\n  audioTrack,\n  volume,\n  className,\n  ref,\n  ...props\n}: AgentAudioVisualizerWaveProps &\n  ComponentProps<\"div\"> &\n  VariantProps<typeof AgentAudioVisualizerWaveVariants>) {\n  const _lineWidth = useMemo(() => {\n    if (lineWidth !== undefined) {\n      return lineWidth\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 2\n      default:\n        return 1\n    }\n  }, [lineWidth, size])\n\n  const { speed, amplitude, frequency, opacity } = useAgentAudioVisualizerWave({\n    state,\n    audioTrack,\n    volume,\n  })\n\n  return (\n    <WaveShader\n      ref={ref}\n      data-lk-state={state}\n      speed={speed}\n      color={color}\n      colorShift={colorShift}\n      mix={opacity}\n      amplitude={amplitude}\n      frequency={frequency}\n      lineWidth={_lineWidth}\n      blur={blur}\n      className={cn(\n        AgentAudioVisualizerWaveVariants({ size }),\n        \"mask-[linear-gradient(90deg,transparent_0%,black_20%,black_80%,transparent_100%)]\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave.ts",
          "type": "registry:component",
          "content": "import {\n  useTrackVolume,\n  type AgentState,\n  type TrackReference,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport {\n  animate,\n  useMotionValue,\n  useMotionValueEvent,\n  useReducedMotion,\n  type AnimationPlaybackControlsWithThen,\n  type ValueAnimationTransition,\n} from \"motion/react\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nconst DEFAULT_SPEED = 5\nconst DEFAULT_AMPLITUDE = 0.025\nconst DEFAULT_FREQUENCY = 10\nconst DEFAULT_TRANSITION: ValueAnimationTransition = {\n  duration: 0.2,\n  ease: \"easeOut\",\n}\n\nfunction useAnimatedValue<T>(initialValue: T) {\n  const [value, setValue] = useState(initialValue)\n  const motionValue = useMotionValue(initialValue)\n  const controlsRef = useRef<AnimationPlaybackControlsWithThen | null>(null)\n  useMotionValueEvent(motionValue, \"change\", (value) => setValue(value as T))\n\n  const animateFn = useCallback(\n    (targetValue: T | T[], transition: ValueAnimationTransition) => {\n      controlsRef.current = animate(motionValue, targetValue, transition)\n    },\n    [motionValue]\n  )\n\n  return { value, controls: controlsRef, animate: animateFn }\n}\n\ninterface UseAgentAudioVisualizerWaveAnimatorArgs {\n  state?: AgentState\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  volume?: number\n}\n\nexport function useAgentAudioVisualizerWave({\n  state,\n  audioTrack,\n  volume: volumeProp,\n}: UseAgentAudioVisualizerWaveAnimatorArgs) {\n  const prefersReducedMotion = useReducedMotion()\n  const [speed, setSpeed] = useState(DEFAULT_SPEED)\n  const { value: amplitude, animate: animateAmplitude } =\n    useAnimatedValue(DEFAULT_AMPLITUDE)\n  const { value: frequency, animate: animateFrequency } =\n    useAnimatedValue(DEFAULT_FREQUENCY)\n  const { value: opacity, animate: animateOpacity } = useAnimatedValue(1.0)\n\n  const trackVolume = useTrackVolume(audioTrack as TrackReference, {\n    fftSize: 512,\n    smoothingTimeConstant: 0.55,\n  })\n  const volume = volumeProp ?? trackVolume\n\n  useEffect(() => {\n    switch (state) {\n      case \"disconnected\":\n        setSpeed(DEFAULT_SPEED)\n        animateAmplitude(0, DEFAULT_TRANSITION)\n        animateFrequency(0, DEFAULT_TRANSITION)\n        animateOpacity(1.0, DEFAULT_TRANSITION)\n        return\n      case \"listening\":\n        setSpeed(DEFAULT_SPEED)\n        animateAmplitude(DEFAULT_AMPLITUDE, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY, DEFAULT_TRANSITION)\n        animateOpacity(\n          prefersReducedMotion ? 0.65 : [1.0, 0.3],\n          prefersReducedMotion\n            ? { duration: 0 }\n            : { duration: 0.75, repeat: Infinity, repeatType: \"mirror\" }\n        )\n        return\n      case \"thinking\":\n      case \"connecting\":\n      case \"initializing\":\n        setSpeed(DEFAULT_SPEED * 4)\n        animateAmplitude(DEFAULT_AMPLITUDE / 4, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY * 4, DEFAULT_TRANSITION)\n        animateOpacity(\n          prefersReducedMotion ? 0.65 : [1.0, 0.3],\n          prefersReducedMotion\n            ? { duration: 0 }\n            : { duration: 0.4, repeat: Infinity, repeatType: \"mirror\" }\n        )\n        return\n      case \"speaking\":\n      default:\n        setSpeed(DEFAULT_SPEED * 2)\n        animateAmplitude(DEFAULT_AMPLITUDE, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY, DEFAULT_TRANSITION)\n        animateOpacity(1.0, DEFAULT_TRANSITION)\n        return\n    }\n  }, [\n    state,\n    setSpeed,\n    animateAmplitude,\n    animateFrequency,\n    animateOpacity,\n    prefersReducedMotion,\n  ])\n\n  useEffect(() => {\n    if (state === \"speaking\") {\n      animateAmplitude(0.015 + 0.4 * volume, { duration: 0 })\n      animateFrequency(20 + 60 * volume, { duration: 0 })\n    }\n  }, [state, volume, animateAmplitude, animateFrequency])\n\n  return {\n    speed,\n    amplitude,\n    frequency,\n    opacity,\n  }\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/react-shader-toy.tsx",
          "target": "@components/voice-agents/livekit/react-shader-toy.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n/**\n * @license\n *\n * MIT License\n *\n * Copyright (c) 2018 Morgan Villedieu\n * Copyright (c) 2023 Rysana, Inc. (forked from the above)\n * Copyright (c) 2026 LiveKit, Inc. (forked from the above)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport React, { useEffect, useRef, type ComponentPropsWithoutRef } from \"react\"\n\nconst PRECISIONS = [\"lowp\", \"mediump\", \"highp\"]\nconst FS_MAIN_SHADER = `\\nvoid main(void){\n    vec4 color = vec4(0.0,0.0,0.0,1.0);\n    mainImage( color, gl_FragCoord.xy );\n    gl_FragColor = color;\n}`\nconst BASIC_FS = `void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n    vec2 uv = fragCoord/iResolution.xy;\n    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));\n    fragColor = vec4(col,1.0);\n}`\nconst BASIC_VS = `attribute vec3 aVertexPosition;\nvoid main(void) {\n    gl_Position = vec4(aVertexPosition, 1.0);\n}`\nconst UNIFORM_TIME = \"iTime\"\nconst UNIFORM_TIMEDELTA = \"iTimeDelta\"\nconst UNIFORM_DATE = \"iDate\"\nconst UNIFORM_FRAME = \"iFrame\"\nconst UNIFORM_MOUSE = \"iMouse\"\nconst UNIFORM_RESOLUTION = \"iResolution\"\nconst UNIFORM_CHANNEL = \"iChannel\"\nconst UNIFORM_CHANNELRESOLUTION = \"iChannelResolution\"\nconst UNIFORM_DEVICEORIENTATION = \"iDeviceOrientation\"\n\ntype Vector4<T = number> = [T, T, T, T]\ntype UniformType = keyof Uniforms\n\nfunction isMatrixType(t: string, v: number[] | number): v is number[] {\n  return t.includes(\"Matrix\") && Array.isArray(v)\n}\nfunction isVectorListType(t: string, v: number[] | number): v is number[] {\n  return (\n    t.includes(\"v\") &&\n    Array.isArray(v) &&\n    v.length > Number.parseInt(t.charAt(0))\n  )\n}\nfunction isVectorType(t: string, v: number[] | number): v is Vector4 {\n  return (\n    !t.includes(\"v\") &&\n    Array.isArray(v) &&\n    v.length > Number.parseInt(t.charAt(0))\n  )\n}\nconst processUniform = <T extends UniformType>(\n  gl: WebGLRenderingContext,\n  location: WebGLUniformLocation,\n  t: T,\n  value: number | number[]\n) => {\n  if (isVectorType(t, value)) {\n    switch (t) {\n      case \"2f\":\n        return gl.uniform2f(location, value[0], value[1])\n      case \"3f\":\n        return gl.uniform3f(location, value[0], value[1], value[2])\n      case \"4f\":\n        return gl.uniform4f(location, value[0], value[1], value[2], value[3])\n      case \"2i\":\n        return gl.uniform2i(location, value[0], value[1])\n      case \"3i\":\n        return gl.uniform3i(location, value[0], value[1], value[2])\n      case \"4i\":\n        return gl.uniform4i(location, value[0], value[1], value[2], value[3])\n    }\n  }\n  if (typeof value === \"number\") {\n    switch (t) {\n      case \"1i\":\n        return gl.uniform1i(location, value)\n      default:\n        return gl.uniform1f(location, value)\n    }\n  }\n  switch (t) {\n    case \"1iv\":\n      return gl.uniform1iv(location, value)\n    case \"2iv\":\n      return gl.uniform2iv(location, value)\n    case \"3iv\":\n      return gl.uniform3iv(location, value)\n    case \"4iv\":\n      return gl.uniform4iv(location, value)\n    case \"1fv\":\n      return gl.uniform1fv(location, value)\n    case \"2fv\":\n      return gl.uniform2fv(location, value)\n    case \"3fv\":\n      return gl.uniform3fv(location, value)\n    case \"4fv\":\n      return gl.uniform4fv(location, value)\n    case \"Matrix2fv\":\n      return gl.uniformMatrix2fv(location, false, value)\n    case \"Matrix3fv\":\n      return gl.uniformMatrix3fv(location, false, value)\n    case \"Matrix4fv\":\n      return gl.uniformMatrix4fv(location, false, value)\n  }\n}\n\nconst uniformTypeToGLSLType = (t: string) => {\n  switch (t) {\n    case \"1f\":\n      return \"float\"\n    case \"2f\":\n      return \"vec2\"\n    case \"3f\":\n      return \"vec3\"\n    case \"4f\":\n      return \"vec4\"\n    case \"1i\":\n      return \"int\"\n    case \"2i\":\n      return \"ivec2\"\n    case \"3i\":\n      return \"ivec3\"\n    case \"4i\":\n      return \"ivec4\"\n    case \"1iv\":\n      return \"int\"\n    case \"2iv\":\n      return \"ivec2\"\n    case \"3iv\":\n      return \"ivec3\"\n    case \"4iv\":\n      return \"ivec4\"\n    case \"1fv\":\n      return \"float\"\n    case \"2fv\":\n      return \"vec2\"\n    case \"3fv\":\n      return \"vec3\"\n    case \"4fv\":\n      return \"vec4\"\n    case \"Matrix2fv\":\n      return \"mat2\"\n    case \"Matrix3fv\":\n      return \"mat3\"\n    case \"Matrix4fv\":\n      return \"mat4\"\n    default:\n      console.error(\n        log(\n          `The uniform type \"${t}\" is not valid, please make sure your uniform type is valid`\n        )\n      )\n  }\n}\n\nconst LinearFilter = 9729\nconst NearestFilter = 9728\nconst LinearMipMapLinearFilter = 9987\nconst ClampToEdgeWrapping = 33071\nconst RepeatWrapping = 10497\n\nclass Texture {\n  gl: WebGLRenderingContext\n  url?: string\n  wrapS?: number\n  wrapT?: number\n  minFilter?: number\n  magFilter?: number\n  source?: HTMLImageElement | HTMLVideoElement\n  pow2canvas?: HTMLCanvasElement\n  isLoaded = false\n  isVideo = false\n  flipY = -1\n  width = 0\n  height = 0\n  _webglTexture: WebGLTexture | null = null\n  constructor(gl: WebGLRenderingContext) {\n    this.gl = gl\n  }\n  updateTexture = (\n    texture: WebGLTexture,\n    video: HTMLVideoElement,\n    flipY: number\n  ) => {\n    const { gl } = this\n    const level = 0\n    const internalFormat = gl.RGBA\n    const srcFormat = gl.RGBA\n    const srcType = gl.UNSIGNED_BYTE\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      srcFormat,\n      srcType,\n      video\n    )\n  }\n  setupVideo = (url: string) => {\n    const video = document.createElement(\"video\")\n    let playing = false\n    let timeupdate = false\n    video.autoplay = true\n    video.muted = true\n    video.loop = true\n    video.crossOrigin = \"anonymous\"\n    const checkReady = () => {\n      if (playing && timeupdate) {\n        this.isLoaded = true\n      }\n    }\n    video.addEventListener(\n      \"playing\",\n      () => {\n        playing = true\n        this.width = video.videoWidth || 0\n        this.height = video.videoHeight || 0\n        checkReady()\n      },\n      true\n    )\n    video.addEventListener(\n      \"timeupdate\",\n      () => {\n        timeupdate = true\n        checkReady()\n      },\n      true\n    )\n    video.src = url\n    return video\n  }\n  makePowerOf2 = <T extends HTMLCanvasElement | HTMLImageElement | ImageBitmap>(\n    image: T\n  ): T => {\n    if (\n      image instanceof HTMLImageElement ||\n      image instanceof HTMLCanvasElement ||\n      image instanceof ImageBitmap\n    ) {\n      if (this.pow2canvas === undefined)\n        this.pow2canvas = document.createElement(\"canvas\")\n      this.pow2canvas.width = 2 ** Math.floor(Math.log(image.width) / Math.LN2)\n      this.pow2canvas.height =\n        2 ** Math.floor(Math.log(image.height) / Math.LN2)\n      const context = this.pow2canvas.getContext(\"2d\")\n      context?.drawImage(\n        image,\n        0,\n        0,\n        this.pow2canvas.width,\n        this.pow2canvas.height\n      )\n      console.warn(\n        log(\n          `Image is not power of two ${image.width} x ${image.height}. Resized to ${this.pow2canvas.width} x ${this.pow2canvas.height};`\n        )\n      )\n      return this.pow2canvas as T\n    }\n    return image\n  }\n  load = async (textureArgs: TextureParams) => {\n    const { gl } = this\n    const {\n      url,\n      wrapS,\n      wrapT,\n      minFilter,\n      magFilter,\n      flipY = -1,\n    }: TextureParams = textureArgs\n    if (!url) {\n      return Promise.reject(\n        new Error(\n          log(\n            \"Missing url, please make sure to pass the url of your texture { url: ... }\"\n          )\n        )\n      )\n    }\n    const isImage = /(\\.jpg|\\.jpeg|\\.png|\\.gif|\\.bmp)$/i.exec(url)\n    const isVideo = /(\\.mp4|\\.3gp|\\.webm|\\.ogv)$/i.exec(url)\n    if (isImage === null && isVideo === null) {\n      return Promise.reject(\n        new Error(\n          log(\n            `Please upload a video or an image with a valid format (url: ${url})`\n          )\n        )\n      )\n    }\n    Object.assign(this, { url, wrapS, wrapT, minFilter, magFilter, flipY })\n    const level = 0\n    const internalFormat = gl.RGBA\n    const width = 1\n    const height = 1\n    const border = 0\n    const srcFormat = gl.RGBA\n    const srcType = gl.UNSIGNED_BYTE\n    const pixel = new Uint8Array([255, 255, 255, 0])\n    const texture = gl.createTexture()\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      width,\n      height,\n      border,\n      srcFormat,\n      srcType,\n      pixel\n    )\n    if (isVideo) {\n      const video = this.setupVideo(url)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)\n      this._webglTexture = texture\n      this.source = video\n      this.isVideo = true\n      return video.play().then(() => this)\n    }\n    async function loadImage() {\n      return new Promise((resolve, reject) => {\n        const image = new Image()\n        image.crossOrigin = \"anonymous\"\n        image.onload = () => {\n          resolve(image)\n        }\n        image.onerror = () => {\n          reject(new Error(log(`failed loading url: ${url}`)))\n        }\n        image.src = url ?? \"\"\n      })\n    }\n    let image = (await loadImage()) as HTMLImageElement\n    let isPowerOf2 =\n      (image.width & (image.width - 1)) === 0 &&\n      (image.height & (image.height - 1)) === 0\n    if (\n      (textureArgs.wrapS !== ClampToEdgeWrapping ||\n        textureArgs.wrapT !== ClampToEdgeWrapping ||\n        (textureArgs.minFilter !== NearestFilter &&\n          textureArgs.minFilter !== LinearFilter)) &&\n      !isPowerOf2\n    ) {\n      image = this.makePowerOf2(image)\n      isPowerOf2 = true\n    }\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      srcFormat,\n      srcType,\n      image\n    )\n    if (\n      isPowerOf2 &&\n      textureArgs.minFilter !== NearestFilter &&\n      textureArgs.minFilter !== LinearFilter\n    ) {\n      gl.generateMipmap(gl.TEXTURE_2D)\n    }\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_WRAP_S,\n      this.wrapS || RepeatWrapping\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_WRAP_T,\n      this.wrapT || RepeatWrapping\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_MIN_FILTER,\n      this.minFilter || LinearMipMapLinearFilter\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_MAG_FILTER,\n      this.magFilter || LinearFilter\n    )\n    this._webglTexture = texture\n    this.source = image\n    this.isVideo = false\n    this.isLoaded = true\n    this.width = image.width || 0\n    this.height = image.height || 0\n    return this\n  }\n}\n\nconst log = (text: string) => `react-shaders: ${text}`\n\nconst latestPointerClientCoords = (e: MouseEvent | TouchEvent) => {\n  if (\"changedTouches\" in e) {\n    const t = e.changedTouches[0]\n    return [t?.clientX ?? 0, t?.clientY ?? 0]\n  }\n  return [e.clientX, e.clientY]\n}\n\nconst lerpVal = (v0: number, v1: number, t: number) => v0 * (1 - t) + v1 * t\nconst insertStringAtIndex = (\n  currentString: string,\n  string: string,\n  index: number\n) =>\n  index > 0\n    ? currentString.substring(0, index) +\n      string +\n      currentString.substring(index, currentString.length)\n    : string + currentString\n\ntype Uniform = { type: string; value: number[] | number }\ntype Uniforms = Record<string, Uniform>\ntype TextureParams = {\n  url: string\n  wrapS?: number\n  wrapT?: number\n  minFilter?: number\n  magFilter?: number\n  flipY?: number\n}\n\nexport interface ReactShaderToyProps {\n  /** Fragment shader GLSL code. */\n  fs: string\n\n  /** Vertex shader GLSL code. */\n  vs?: string\n\n  /**\n   * Textures to be passed to the shader. Textures need to be squared or will be\n   * automatically resized.\n   *\n   * Options default to:\n   *\n   * ```js\n   * {\n   *   minFilter: LinearMipMapLinearFilter,\n   *   magFilter: LinearFilter,\n   *   wrapS: RepeatWrapping,\n   *   wrapT: RepeatWrapping,\n   * }\n   * ```\n   *\n   * See [textures in the docs](https://rysana.com/docs/react-shaders#textures)\n   * for details.\n   */\n  textures?: TextureParams[]\n\n  /**\n   * Custom uniforms to be passed to the shader.\n   *\n   * See [custom uniforms in the\n   * docs](https://rysana.com/docs/react-shaders#custom-uniforms) for details.\n   */\n  uniforms?: Uniforms\n\n  /**\n   * Color used when clearing the canvas.\n   *\n   * See [the WebGL\n   * docs](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/clearColor)\n   * for details.\n   */\n  clearColor?: Vector4\n\n  /**\n   * GLSL precision qualifier. Defaults to `'highp'`. Balance between\n   * performance and quality.\n   */\n  precision?: \"highp\" | \"lowp\" | \"mediump\"\n\n  /** Custom inline style for canvas. */\n  style?: React.CSSProperties\n\n  /** Customize WebGL context attributes. See [the WebGL docs](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getContextAttributes) for details. */\n  contextAttributes?: Record<string, unknown>\n\n  /** Lerp value for `iMouse` built-in uniform. Must be between 0 and 1. */\n  lerp?: number\n\n  /** Device pixel ratio. */\n  devicePixelRatio?: number\n\n  /**\n   * Callback for when the textures are done loading. Useful if you want to do\n   * something like e.g. hide the canvas until textures are done loading.\n   */\n  onDoneLoadingTextures?: () => void\n\n  /** Custom callback to handle errors. Defaults to `console.error`. */\n  onError?: (error: string) => void\n\n  /** Custom callback to handle warnings. Defaults to `console.warn`. */\n  onWarning?: (warning: string) => void\n\n  /**\n   * When true, the animation loop runs even when the canvas is not visible in the viewport.\n   * When false (default), animation runs only while visible (uses Intersection Observer),\n   * reducing CPU/GPU usage when the shader is off-screen.\n   */\n  animateWhenNotVisible?: boolean\n}\n\nexport function ReactShaderToy({\n  fs,\n  vs = BASIC_VS,\n  textures = [],\n  uniforms: propUniforms,\n  clearColor = [0, 0, 0, 1],\n  precision = \"highp\",\n  style,\n  contextAttributes = {},\n  lerp = 1,\n  devicePixelRatio = 1,\n  onDoneLoadingTextures,\n  onError = console.error,\n  onWarning = console.warn,\n  animateWhenNotVisible = false,\n  ...canvasProps\n}: ReactShaderToyProps & ComponentPropsWithoutRef<\"canvas\">) {\n  // Refs for WebGL state\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const glRef = useRef<WebGLRenderingContext | null>(null)\n  const squareVerticesBufferRef = useRef<WebGLBuffer | null>(null)\n  const shaderProgramRef = useRef<WebGLProgram | null>(null)\n  const vertexPositionAttributeRef = useRef<number | undefined>(undefined)\n  const animFrameIdRef = useRef<number | undefined>(undefined)\n  const initFrameIdRef = useRef<number | undefined>(undefined)\n  const isVisibleRef = useRef(true)\n  const prefersReducedMotionRef = useRef(false)\n  const animateWhenNotVisibleRef = useRef(animateWhenNotVisible)\n  const mousedownRef = useRef(false)\n  const canvasPositionRef = useRef<DOMRect | undefined>(undefined)\n  const timerRef = useRef(0)\n  const lastMouseArrRef = useRef<number[]>([0, 0])\n  const texturesArrRef = useRef<Texture[]>([])\n  const lastTimeRef = useRef(0)\n  const resizeObserverRef = useRef<ResizeObserver | undefined>(undefined)\n  const uniformsRef = useRef<\n    Record<\n      string,\n      {\n        type: string\n        isNeeded: boolean\n        value?: number[] | number\n        arraySize?: string\n      }\n    >\n  >({\n    [UNIFORM_TIME]: { type: \"float\", isNeeded: false, value: 0 },\n    [UNIFORM_TIMEDELTA]: { type: \"float\", isNeeded: false, value: 0 },\n    [UNIFORM_DATE]: { type: \"vec4\", isNeeded: false, value: [0, 0, 0, 0] },\n    [UNIFORM_MOUSE]: { type: \"vec4\", isNeeded: false, value: [0, 0, 0, 0] },\n    [UNIFORM_RESOLUTION]: { type: \"vec2\", isNeeded: false, value: [0, 0] },\n    [UNIFORM_FRAME]: { type: \"int\", isNeeded: false, value: 0 },\n    [UNIFORM_DEVICEORIENTATION]: {\n      type: \"vec4\",\n      isNeeded: false,\n      value: [0, 0, 0, 0],\n    },\n  })\n  const propsUniformsRef = useRef<Uniforms | undefined>(propUniforms)\n  const resolvedDevicePixelRatio = Math.min(Math.max(devicePixelRatio, 1), 2)\n\n  const setupChannelRes = (texture: TextureParams | Texture, id: number) => {\n    const width = \"width\" in texture ? (texture.width ?? 0) : 0\n    const height = \"height\" in texture ? (texture.height ?? 0) : 0\n    const channelResUniform = uniformsRef.current.iChannelResolution\n    if (!channelResUniform) return\n    const channelResValue = Array.isArray(channelResUniform.value)\n      ? channelResUniform.value\n      : (channelResUniform.value = [])\n    channelResValue[id * 3] = width * resolvedDevicePixelRatio\n    channelResValue[id * 3 + 1] = height * resolvedDevicePixelRatio\n    channelResValue[id * 3 + 2] = 0\n  }\n\n  const initWebGL = () => {\n    if (!canvasRef.current) return\n    glRef.current = (canvasRef.current.getContext(\"webgl\", contextAttributes) ||\n      canvasRef.current.getContext(\n        \"experimental-webgl\",\n        contextAttributes\n      )) as WebGLRenderingContext | null\n    glRef.current?.getExtension(\"OES_standard_derivatives\")\n    glRef.current?.getExtension(\"EXT_shader_texture_lod\")\n  }\n\n  const initBuffers = () => {\n    const gl = glRef.current\n    squareVerticesBufferRef.current = gl?.createBuffer() ?? null\n    gl?.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBufferRef.current)\n    const vertices = [\n      1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0,\n    ]\n    gl?.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)\n  }\n\n  const onDeviceOrientationChange = ({\n    alpha,\n    beta,\n    gamma,\n  }: DeviceOrientationEvent) => {\n    uniformsRef.current.iDeviceOrientation!.value = [\n      alpha ?? 0,\n      beta ?? 0,\n      gamma ?? 0,\n      window.orientation ?? 0,\n    ]\n  }\n\n  const mouseDown = (e: MouseEvent | TouchEvent) => {\n    const [clientX = 0, clientY = 0] = latestPointerClientCoords(e)\n    const mouseX =\n      clientX - (canvasPositionRef.current?.left ?? 0) - window.pageXOffset\n    const mouseY =\n      (canvasPositionRef.current?.height ?? 0) -\n      clientY -\n      (canvasPositionRef.current?.top ?? 0) -\n      window.pageYOffset\n    mousedownRef.current = true\n    const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n      ? uniformsRef.current.iMouse.value\n      : undefined\n    if (mouseValue) {\n      mouseValue[2] = mouseX\n      mouseValue[3] = mouseY\n    }\n    lastMouseArrRef.current[0] = mouseX\n    lastMouseArrRef.current[1] = mouseY\n  }\n\n  const mouseMove = (e: MouseEvent | TouchEvent) => {\n    canvasPositionRef.current = canvasRef.current?.getBoundingClientRect()\n    const [clientX = 0, clientY = 0] = latestPointerClientCoords(e)\n    const mouseX = clientX - (canvasPositionRef.current?.left ?? 0)\n    const mouseY =\n      (canvasPositionRef.current?.height ?? 0) -\n      clientY -\n      (canvasPositionRef.current?.top ?? 0)\n    if (lerp !== 1) {\n      lastMouseArrRef.current[0] = mouseX\n      lastMouseArrRef.current[1] = mouseY\n    } else {\n      const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n        ? uniformsRef.current.iMouse.value\n        : undefined\n      if (mouseValue) {\n        mouseValue[0] = mouseX\n        mouseValue[1] = mouseY\n      }\n    }\n  }\n\n  const mouseUp = () => {\n    const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n      ? uniformsRef.current.iMouse.value\n      : undefined\n    if (mouseValue) {\n      mouseValue[2] = 0\n      mouseValue[3] = 0\n    }\n  }\n\n  const onResize = () => {\n    const gl = glRef.current\n    if (!gl) return\n    canvasPositionRef.current = canvasRef.current?.getBoundingClientRect()\n    // Force pixel ratio to be one to avoid expensive calculus on retina display.\n    const realToCSSPixels = resolvedDevicePixelRatio\n    const displayWidth = Math.floor(\n      (canvasPositionRef.current?.width ?? 1) * realToCSSPixels\n    )\n    const displayHeight = Math.floor(\n      (canvasPositionRef.current?.height ?? 1) * realToCSSPixels\n    )\n    gl.canvas.width = displayWidth\n    gl.canvas.height = displayHeight\n    if (uniformsRef.current.iResolution?.isNeeded && shaderProgramRef.current) {\n      const rUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_RESOLUTION\n      )\n      gl.uniform2fv(rUniform, [gl.canvas.width, gl.canvas.height])\n    }\n  }\n\n  const createShader = (type: number, shaderCodeAsText: string) => {\n    const gl = glRef.current\n    if (!gl) return null\n    const shader = gl.createShader(type)\n    if (!shader) return null\n    gl.shaderSource(shader, shaderCodeAsText)\n    gl.compileShader(shader)\n    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n      onWarning?.(log(`Error compiling the shader:\\n${shaderCodeAsText}`))\n      const compilationLog = gl.getShaderInfoLog(shader)\n      gl.deleteShader(shader)\n      onError?.(log(`Shader compiler log: ${compilationLog}`))\n    }\n    return shader\n  }\n\n  const initShaders = (fragmentShader: string, vertexShader: string) => {\n    const gl = glRef.current\n    if (!gl) return\n    const fragmentShaderObj = createShader(gl.FRAGMENT_SHADER, fragmentShader)\n    const vertexShaderObj = createShader(gl.VERTEX_SHADER, vertexShader)\n    shaderProgramRef.current = gl.createProgram()\n    if (!shaderProgramRef.current || !vertexShaderObj || !fragmentShaderObj)\n      return\n    gl.attachShader(shaderProgramRef.current, vertexShaderObj)\n    gl.attachShader(shaderProgramRef.current, fragmentShaderObj)\n    gl.linkProgram(shaderProgramRef.current)\n    if (!gl.getProgramParameter(shaderProgramRef.current, gl.LINK_STATUS)) {\n      onError?.(\n        log(\n          `Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgramRef.current)}`\n        )\n      )\n      return\n    }\n    gl.useProgram(shaderProgramRef.current)\n    vertexPositionAttributeRef.current = gl.getAttribLocation(\n      shaderProgramRef.current,\n      \"aVertexPosition\"\n    )\n    gl.enableVertexAttribArray(vertexPositionAttributeRef.current)\n  }\n\n  const processCustomUniforms = () => {\n    if (propUniforms) {\n      for (const name of Object.keys(propUniforms)) {\n        const uniform = propUniforms[name]\n        if (!uniform) continue\n        const { value, type } = uniform\n        const glslType = uniformTypeToGLSLType(type)\n        if (!glslType) continue\n        const tempObject: { arraySize?: string } = {}\n        if (isMatrixType(type, value)) {\n          const arrayLength = type.length\n          const val = Number.parseInt(type.charAt(arrayLength - 3))\n          const numberOfMatrices = Math.floor(value.length / (val * val))\n          if (value.length > val * val)\n            tempObject.arraySize = `[${numberOfMatrices}]`\n        } else if (isVectorListType(type, value)) {\n          tempObject.arraySize = `[${Math.floor(value.length / Number.parseInt(type.charAt(0)))}]`\n        }\n        uniformsRef.current[name] = {\n          type: glslType,\n          isNeeded: false,\n          value,\n          ...tempObject,\n        }\n      }\n    }\n  }\n\n  const processTextures = () => {\n    const gl = glRef.current\n    if (!gl) return\n    if (textures && textures.length > 0) {\n      uniformsRef.current[`${UNIFORM_CHANNELRESOLUTION}`] = {\n        type: \"vec3\",\n        isNeeded: false,\n        arraySize: `[${textures.length}]`,\n        value: [],\n      }\n      const texturePromisesArr = textures.map(\n        (texture: TextureParams, id: number) => {\n          // Dynamically add textures uniforms.\n          uniformsRef.current[`${UNIFORM_CHANNEL}${id}`] = {\n            type: \"sampler2D\",\n            isNeeded: false,\n          }\n          setupChannelRes(texture, id)\n          texturesArrRef.current[id] = new Texture(gl)\n          return texturesArrRef.current[id]\n            ?.load(texture)\n            .then((t: Texture) => {\n              setupChannelRes(t, id)\n            })\n        }\n      )\n      Promise.all(texturePromisesArr)\n        .then(() => {\n          if (onDoneLoadingTextures) onDoneLoadingTextures()\n        })\n        .catch((e) => {\n          onError?.(e)\n          if (onDoneLoadingTextures) onDoneLoadingTextures()\n        })\n    } else if (onDoneLoadingTextures) onDoneLoadingTextures()\n  }\n\n  const preProcessFragment = (fragment: string) => {\n    const isValidPrecision = PRECISIONS.includes(precision ?? \"highp\")\n    const precisionString = `precision ${isValidPrecision ? precision : PRECISIONS[1]} float;\\n`\n    if (!isValidPrecision) {\n      onWarning?.(\n        log(\n          `wrong precision type ${precision}, please make sure to pass one of a valid precision lowp, mediump, highp, by default you shader precision will be set to highp.`\n        )\n      )\n    }\n    let fragmentShader = precisionString\n      .concat(`#define DPR ${resolvedDevicePixelRatio.toFixed(1)}\\n`)\n      .concat(fragment.replace(/texture\\(/g, \"texture2D(\"))\n    for (const uniform of Object.keys(uniformsRef.current)) {\n      if (fragment.includes(uniform)) {\n        const u = uniformsRef.current[uniform]\n        if (!u) continue\n        fragmentShader = insertStringAtIndex(\n          fragmentShader,\n          `uniform ${u.type} ${uniform}${u.arraySize || \"\"}; \\n`,\n          fragmentShader.lastIndexOf(precisionString) + precisionString.length\n        )\n        u.isNeeded = true\n      }\n    }\n    const isShadertoy = fragment.includes(\"mainImage\")\n    if (isShadertoy) fragmentShader = fragmentShader.concat(FS_MAIN_SHADER)\n    return fragmentShader\n  }\n\n  const setUniforms = (timestamp: number) => {\n    const gl = glRef.current\n    if (!gl || !shaderProgramRef.current) return\n    const delta = lastTimeRef.current\n      ? (timestamp - lastTimeRef.current) / 1000\n      : 0\n    lastTimeRef.current = timestamp\n    const propUniforms = propsUniformsRef.current\n    if (propUniforms) {\n      for (const name of Object.keys(propUniforms)) {\n        const currentUniform = propUniforms[name]\n        if (!currentUniform) continue\n        if (uniformsRef.current[name]?.isNeeded) {\n          if (!shaderProgramRef.current) return\n          const customUniformLocation = gl.getUniformLocation(\n            shaderProgramRef.current,\n            name\n          )\n          if (!customUniformLocation) return\n          processUniform(\n            gl,\n            customUniformLocation,\n            currentUniform.type as UniformType,\n            currentUniform.value\n          )\n        }\n      }\n    }\n    if (uniformsRef.current.iMouse?.isNeeded) {\n      const mouseUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_MOUSE\n      )\n      gl.uniform4fv(mouseUniform, uniformsRef.current.iMouse.value as number[])\n    }\n    if (uniformsRef.current.iChannelResolution?.isNeeded) {\n      const channelResUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_CHANNELRESOLUTION\n      )\n      gl.uniform3fv(\n        channelResUniform,\n        uniformsRef.current.iChannelResolution.value as number[]\n      )\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      const deviceOrientationUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_DEVICEORIENTATION\n      )\n      gl.uniform4fv(\n        deviceOrientationUniform,\n        uniformsRef.current.iDeviceOrientation.value as number[]\n      )\n    }\n    if (uniformsRef.current.iTime?.isNeeded) {\n      const timeUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_TIME\n      )\n      gl.uniform1f(timeUniform, (timerRef.current += delta))\n    }\n    if (uniformsRef.current.iTimeDelta?.isNeeded) {\n      const timeDeltaUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_TIMEDELTA\n      )\n      gl.uniform1f(timeDeltaUniform, delta)\n    }\n    if (uniformsRef.current.iDate?.isNeeded) {\n      const d = new Date()\n      const month = d.getMonth() + 1\n      const day = d.getDate()\n      const year = d.getFullYear()\n      const time =\n        d.getHours() * 60 * 60 +\n        d.getMinutes() * 60 +\n        d.getSeconds() +\n        d.getMilliseconds() * 0.001\n      const dateUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_DATE\n      )\n      gl.uniform4fv(dateUniform, [year, month, day, time])\n    }\n    if (uniformsRef.current.iFrame?.isNeeded) {\n      const timeDeltaUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_FRAME\n      )\n      const frame = uniformsRef.current.iFrame.value as number\n      gl.uniform1i(timeDeltaUniform, frame)\n      uniformsRef.current.iFrame.value = frame + 1\n    }\n    if (texturesArrRef.current.length > 0) {\n      for (let index = 0; index < texturesArrRef.current.length; index++) {\n        const texture = texturesArrRef.current[index]\n        if (!texture) return\n        const { isVideo, _webglTexture, source, flipY, isLoaded } = texture\n        if (!isLoaded || !_webglTexture || !source) return\n        if (uniformsRef.current[`iChannel${index}`]?.isNeeded) {\n          if (!shaderProgramRef.current) return\n          const iChannel = gl.getUniformLocation(\n            shaderProgramRef.current,\n            `iChannel${index}`\n          )\n          gl.activeTexture(gl.TEXTURE0 + index)\n          gl.bindTexture(gl.TEXTURE_2D, _webglTexture)\n          gl.uniform1i(iChannel, index)\n          if (isVideo) {\n            texture.updateTexture(\n              _webglTexture,\n              source as HTMLVideoElement,\n              flipY\n            )\n          }\n        }\n      }\n    }\n  }\n\n  const drawScene = (timestamp: number) => {\n    const gl = glRef.current\n    if (!gl) return\n    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight)\n    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)\n    gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBufferRef.current)\n    gl.vertexAttribPointer(\n      vertexPositionAttributeRef.current ?? 0,\n      3,\n      gl.FLOAT,\n      false,\n      0,\n      0\n    )\n    setUniforms(timestamp)\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\n    const mouseValue = uniformsRef.current.iMouse?.value\n    if (\n      uniformsRef.current.iMouse?.isNeeded &&\n      lerp !== 1 &&\n      Array.isArray(mouseValue)\n    ) {\n      const currentX = mouseValue[0] ?? 0\n      const currentY = mouseValue[1] ?? 0\n      mouseValue[0] = lerpVal(currentX, lastMouseArrRef.current[0] ?? 0, lerp)\n      mouseValue[1] = lerpVal(currentY, lastMouseArrRef.current[1] ?? 0, lerp)\n    }\n    if (\n      !prefersReducedMotionRef.current &&\n      (animateWhenNotVisibleRef.current || isVisibleRef.current)\n    ) {\n      animFrameIdRef.current = requestAnimationFrame(drawScene)\n    }\n  }\n\n  const addEventListeners = () => {\n    const options = { passive: true }\n    if (uniformsRef.current.iMouse?.isNeeded && canvasRef.current) {\n      canvasRef.current.addEventListener(\"mousemove\", mouseMove, options)\n      canvasRef.current.addEventListener(\"mouseout\", mouseUp, options)\n      canvasRef.current.addEventListener(\"mouseup\", mouseUp, options)\n      canvasRef.current.addEventListener(\"mousedown\", mouseDown, options)\n      canvasRef.current.addEventListener(\"touchmove\", mouseMove, options)\n      canvasRef.current.addEventListener(\"touchend\", mouseUp, options)\n      canvasRef.current.addEventListener(\"touchstart\", mouseDown, options)\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      window.addEventListener(\n        \"deviceorientation\",\n        onDeviceOrientationChange,\n        options\n      )\n    }\n    if (canvasRef.current) {\n      resizeObserverRef.current = new ResizeObserver(onResize)\n      resizeObserverRef.current.observe(canvasRef.current)\n      window.addEventListener(\"resize\", onResize, options)\n    }\n  }\n\n  const removeEventListeners = () => {\n    const options = { passive: true } as EventListenerOptions\n    if (uniformsRef.current.iMouse?.isNeeded && canvasRef.current) {\n      canvasRef.current.removeEventListener(\"mousemove\", mouseMove, options)\n      canvasRef.current.removeEventListener(\"mouseout\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"mouseup\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"mousedown\", mouseDown, options)\n      canvasRef.current.removeEventListener(\"touchmove\", mouseMove, options)\n      canvasRef.current.removeEventListener(\"touchend\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"touchstart\", mouseDown, options)\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      window.removeEventListener(\n        \"deviceorientation\",\n        onDeviceOrientationChange,\n        options\n      )\n    }\n    if (resizeObserverRef.current) {\n      resizeObserverRef.current.disconnect()\n      window.removeEventListener(\"resize\", onResize, options)\n    }\n  }\n\n  useEffect(() => {\n    propsUniformsRef.current = propUniforms\n  }, [propUniforms])\n\n  useEffect(() => {\n    animateWhenNotVisibleRef.current = animateWhenNotVisible\n    if (animateWhenNotVisible) {\n      isVisibleRef.current = true\n    }\n  }, [animateWhenNotVisible])\n\n  useEffect(() => {\n    const media = window.matchMedia(\"(prefers-reduced-motion: reduce)\")\n    const update = () => {\n      prefersReducedMotionRef.current = media.matches\n      if (media.matches) {\n        cancelAnimationFrame(animFrameIdRef.current ?? 0)\n        requestAnimationFrame(drawScene)\n      } else if (animateWhenNotVisibleRef.current || isVisibleRef.current) {\n        requestAnimationFrame(drawScene)\n      }\n    }\n    update()\n    media.addEventListener(\"change\", update)\n    return () => media.removeEventListener(\"change\", update)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [])\n\n  // Intersection Observer: pause animation when off-screen when animateWhenNotVisible is false\n  useEffect(() => {\n    if (animateWhenNotVisible || !canvasRef.current) return\n    const canvas = canvasRef.current\n    const observer = new IntersectionObserver(\n      (entries) => {\n        for (const entry of entries) {\n          isVisibleRef.current = entry.isIntersecting\n          if (entry.isIntersecting) {\n            requestAnimationFrame(drawScene)\n          }\n        }\n      },\n      { threshold: 0 }\n    )\n    observer.observe(canvas)\n    return () => observer.disconnect()\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [animateWhenNotVisible])\n\n  // Main effect for initialization and cleanup\n  useEffect(() => {\n    const textures = texturesArrRef.current\n\n    function init() {\n      initWebGL()\n      const gl = glRef.current\n      if (gl && canvasRef.current) {\n        gl.clearColor(...clearColor)\n        gl.clearDepth(1.0)\n        gl.enable(gl.DEPTH_TEST)\n        gl.depthFunc(gl.LEQUAL)\n        gl.viewport(0, 0, canvasRef.current.width, canvasRef.current.height)\n        canvasRef.current.height = canvasRef.current.clientHeight\n        canvasRef.current.width = canvasRef.current.clientWidth\n        processCustomUniforms()\n        processTextures()\n        initShaders(preProcessFragment(fs || BASIC_FS), vs || BASIC_VS)\n        initBuffers()\n        requestAnimationFrame(drawScene)\n        addEventListeners()\n        onResize()\n      }\n    }\n\n    initFrameIdRef.current = requestAnimationFrame(init)\n\n    // Cleanup function\n    return () => {\n      const gl = glRef.current\n      if (gl) {\n        gl.getExtension(\"WEBGL_lose_context\")?.loseContext()\n        gl.useProgram(null)\n        gl.deleteProgram(shaderProgramRef.current ?? null)\n        if (textures.length > 0) {\n          for (const texture of textures as Texture[]) {\n            gl.deleteTexture(texture._webglTexture)\n          }\n        }\n        shaderProgramRef.current = null\n      }\n      removeEventListeners()\n      cancelAnimationFrame(initFrameIdRef.current ?? 0)\n      cancelAnimationFrame(animFrameIdRef.current ?? 0)\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []) // Empty dependency array to run only once on mount\n\n  return (\n    <canvas\n      ref={canvasRef}\n      style={{ height: \"100%\", width: \"100%\", ...style }}\n      {...canvasProps}\n    />\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-chat-transcript.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-transcript.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Bubble,\n  BubbleContent,\n} from \"@/components/voice-agents/livekit/_ui/bubble\"\nimport {\n  Marker,\n  MarkerContent,\n  MarkerIcon,\n} from \"@/components/voice-agents/livekit/_ui/marker\"\nimport {\n  Message,\n  MessageContent,\n} from \"@/components/voice-agents/livekit/_ui/message\"\nimport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n} from \"@/components/voice-agents/livekit/_ui/message-scroller\"\nimport { AgentChatIndicator } from \"@/components/voice-agents/livekit/agent-chat-indicator\"\nimport {\n  type AgentState,\n  type ReceivedMessage,\n} from \"@livekit/components-react\"\nimport { type ComponentProps } from \"react\"\nimport { Streamdown } from \"streamdown\"\n\n/**\n * Props for the AgentChatTranscript component.\n */\nexport interface AgentChatTranscriptProps\n  extends ComponentProps<\"div\">,\n    ComponentProps<typeof MessageScrollerProvider>,\n    ComponentProps<typeof MessageScrollerViewport>,\n    ComponentProps<typeof MessageScrollerContent> {\n  /**\n   * Whether to automatically scroll to the bottom of the transcript when new messages are added.\n   * @defaultValue true\n   */\n  autoScroll?: boolean\n  /**\n   * The scroll anchor to use when auto-scrolling.\n   * @defaultValue false\n   */\n  scrollAnchor?: boolean | \"user\" | \"other\" | \"any\"\n  /**\n   * The scroll button render function\n   */\n  scrollButtonRender?: ComponentProps<typeof MessageScrollerButton>[\"render\"]\n  /**\n   * The scroll button behavior\n   */\n  scrollButtonBehavior?: ComponentProps<\n    typeof MessageScrollerButton\n  >[\"behavior\"]\n  /**\n   * The scroll button direction\n   */\n  scrollButtonDirection?: ComponentProps<\n    typeof MessageScrollerButton\n  >[\"direction\"]\n  /**\n   * The current state of the agent. When 'thinking', displays a loading indicator.\n   */\n  agentState?: AgentState\n  /**\n   * Array of messages to display in the transcript.\n   * @defaultValue []\n   */\n  messages?: ReceivedMessage[]\n  /**\n   * Additional CSS class names to apply to the conversation container.\n   */\n  className?: string\n}\n\n/**\n * A chat transcript component that displays a conversation between the user and agent.\n * Shows messages with timestamps and origin indicators, plus a thinking indicator\n * when the agent is processing.\n *\n * @extends ComponentProps<'div'>, ComponentProps<typeof MessageScrollerProvider>, ComponentProps<typeof MessageScrollerViewport>, ComponentProps<typeof MessageScrollerContent>\n *\n *\n * @example\n * ```tsx\n * <AgentChatTranscript\n *   agentState={agentState}\n *   messages={chatMessages}\n * />\n * ```\n */\nexport function AgentChatTranscript({\n  scrollAnchor,\n  autoScroll = true,\n  scrollMargin,\n  scrollEdgeThreshold,\n  preserveScrollOnPrepend,\n  scrollPreviousItemPeek,\n  defaultScrollPosition = \"last-anchor\",\n  scrollButtonRender,\n  scrollButtonBehavior,\n  scrollButtonDirection,\n  spacerClassName,\n  agentState,\n  messages = [],\n  className,\n  ...props\n}: AgentChatTranscriptProps) {\n  return (\n    <MessageScrollerProvider\n      autoScroll={autoScroll}\n      scrollMargin={scrollMargin}\n      defaultScrollPosition={defaultScrollPosition}\n      scrollEdgeThreshold={scrollEdgeThreshold}\n      scrollPreviousItemPeek={scrollPreviousItemPeek}\n    >\n      <MessageScroller className={className} {...props}>\n        <MessageScrollerViewport\n          preserveScrollOnPrepend={preserveScrollOnPrepend}\n        >\n          <MessageScrollerContent\n            spacerClassName={spacerClassName}\n            aria-busy={agentState === \"thinking\"}\n          >\n            {messages.map((receivedMessage) => {\n              const { id, timestamp, from, message } = receivedMessage\n              const time = new Date(timestamp)\n              const isUser = from?.isLocal\n              const locale =\n                typeof navigator !== \"undefined\" ? navigator.language : \"en-US\"\n              const title = time.toLocaleTimeString(locale, {\n                timeStyle: \"full\",\n              })\n              let _scrollAnchor = false\n\n              if (\n                scrollAnchor === \"any\" ||\n                (scrollAnchor === \"user\" && isUser) ||\n                (scrollAnchor === \"other\" && !isUser)\n              ) {\n                _scrollAnchor = true\n              }\n\n              return (\n                <MessageScrollerItem\n                  key={id}\n                  messageId={id}\n                  scrollAnchor={_scrollAnchor}\n                >\n                  <Message align={isUser ? \"end\" : \"start\"} title={title}>\n                    <MessageContent>\n                      <Bubble\n                        align={isUser ? \"end\" : \"start\"}\n                        variant={isUser ? \"secondary\" : \"ghost\"}\n                      >\n                        <BubbleContent>\n                          <Streamdown>{message}</Streamdown>\n                        </BubbleContent>\n                      </Bubble>\n                    </MessageContent>\n                  </Message>\n                </MessageScrollerItem>\n              )\n            })}\n\n            {/* Agent is thinking indicator */}\n            {agentState === \"thinking\" && (\n              <MessageScrollerItem>\n                <Marker role=\"status\">\n                  <MarkerIcon>\n                    <AgentChatIndicator size=\"sm\" />\n                  </MarkerIcon>\n                  <MarkerContent className=\"shimmer\">Thinking...</MarkerContent>\n                </Marker>\n              </MessageScrollerItem>\n            )}\n          </MessageScrollerContent>\n        </MessageScrollerViewport>\n\n        {/* Scroll to bottom button */}\n        <MessageScrollerButton\n          variant=\"outline\"\n          className=\"rounded-full\"\n          render={scrollButtonRender}\n          behavior={scrollButtonBehavior}\n          direction={scrollButtonDirection}\n        />\n      </MessageScroller>\n    </MessageScrollerProvider>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/bubble.tsx",
          "target": "@components/voice-agents/livekit/_ui/bubble.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction BubbleGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"bubble-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nconst bubbleVariants = cva(\n  \"group/bubble relative flex w-fit max-w-[80%] min-w-0 flex-col gap-1 group-data-[align=end]/message:self-end data-[align=end]:self-end data-[variant=ghost]:max-w-full\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80\",\n        secondary:\n          \"*:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]\",\n        muted:\n          \"*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]\",\n        tinted:\n          \"*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]\",\n        outline:\n          \"*:data-[slot=bubble-content]:border-border *:data-[slot=bubble-content]:bg-background [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30\",\n        ghost:\n          \"border-none *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50\",\n        destructive:\n          \"*:data-[slot=bubble-content]:bg-destructive/10 *:data-[slot=bubble-content]:text-destructive dark:*:data-[slot=bubble-content]:bg-destructive/20 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Bubble({\n  variant = \"default\",\n  align = \"start\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof bubbleVariants> & {\n    align?: \"start\" | \"end\"\n  }) {\n  return (\n    <div\n      data-slot=\"bubble\"\n      data-variant={variant}\n      data-align={align}\n      className={cn(bubbleVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BubbleContent({\n  asChild = false,\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  asChild?: boolean\n}) {\n  const Comp = asChild ? Slot.Root : \"div\"\n\n  return (\n    <Comp\n      data-slot=\"bubble-content\"\n      className={cn(\n        \"[button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-ring/50 w-fit max-w-full min-w-0 overflow-hidden rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed wrap-break-word group-data-[align=end]/bubble:self-end [button]:text-left [button,a]:transition-colors [button,a]:outline-none [button,a]:focus-visible:ring-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst bubbleReactionsVariants = cva(\n  \"absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm ring-3 ring-card has-[button]:p-0\",\n  {\n    variants: {\n      side: {\n        top: \"top-0 -translate-y-3/4\",\n        bottom: \"bottom-0 translate-y-3/4\",\n      },\n      align: {\n        start: \"left-3\",\n        end: \"right-3\",\n      },\n    },\n    defaultVariants: {\n      side: \"bottom\",\n      align: \"end\",\n    },\n  }\n)\n\nfunction BubbleReactions({\n  side = \"bottom\",\n  align = \"end\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  align?: \"start\" | \"end\"\n  side?: \"top\" | \"bottom\"\n}) {\n  return (\n    <div\n      data-slot=\"bubble-reactions\"\n      data-align={align}\n      data-side={side}\n      className={cn(bubbleReactionsVariants({ side, align }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { BubbleGroup, Bubble, BubbleContent, BubbleReactions }\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/marker.tsx",
          "target": "@components/voice-agents/livekit/_ui/marker.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst markerVariants = cva(\n  \"group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground\",\n  {\n    variants: {\n      variant: {\n        default: \"\",\n        separator:\n          \"before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border\",\n        border: \"border-b border-border pb-2\",\n      },\n    },\n  }\n)\n\nfunction Marker({\n  className,\n  variant = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof markerVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"div\"\n\n  return (\n    <Comp\n      data-slot=\"marker\"\n      data-variant={variant}\n      className={cn(markerVariants({ variant, className }))}\n      {...props}\n    />\n  )\n}\n\nfunction MarkerIcon({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"marker-icon\"\n      aria-hidden=\"true\"\n      className={cn(\n        \"size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MarkerContent({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"marker-content\"\n      className={cn(\n        \"*:[a]:hover:text-foreground min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Marker, MarkerIcon, MarkerContent, markerVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/message.tsx",
          "target": "@components/voice-agents/livekit/_ui/message.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction MessageGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction Message({\n  className,\n  align = \"start\",\n  ...props\n}: React.ComponentProps<\"div\"> & { align?: \"start\" | \"end\" }) {\n  return (\n    <div\n      data-slot=\"message\"\n      data-align={align}\n      className={cn(\n        \"group/message relative flex w-full min-w-0 gap-2 text-sm data-[align=end]:flex-row-reverse\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageAvatar({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-avatar\"\n      className={cn(\n        \"bg-muted flex w-fit min-w-8 shrink-0 items-center justify-center self-end overflow-hidden rounded-full group-has-data-[slot=message-footer]/message:-translate-y-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-content\"\n      className={cn(\n        \"flex w-full min-w-0 flex-col gap-2.5 wrap-break-word group-data-[align=end]/message:*:data-slot:self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-header\"\n      className={cn(\n        \"text-muted-foreground flex max-w-full min-w-0 items-center px-3 text-xs font-medium group-has-data-[variant=ghost]/message:px-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-footer\"\n      className={cn(\n        \"text-muted-foreground flex max-w-full min-w-0 items-center px-3 text-xs font-medium group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  MessageGroup,\n  Message,\n  MessageAvatar,\n  MessageContent,\n  MessageFooter,\n  MessageHeader,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/message-scroller.tsx",
          "target": "@components/voice-agents/livekit/_ui/message-scroller.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ArrowDownIcon } from \"lucide-react\"\nimport * as React from \"react\"\nimport { Button } from \"./button\"\n\ntype ScrollerContextValue = {\n  autoScroll: boolean\n  atEnd: boolean\n  atEndRef: React.RefObject<boolean>\n  atStart: boolean\n  defaultScrollPosition: \"first\" | \"last\" | \"last-anchor\"\n  scrollEdgeThreshold: number\n  scrollMargin: number\n  scrollPreviousItemPeek: number\n  setAtEnd: (atEnd: boolean) => void\n  setAtStart: (atStart: boolean) => void\n  viewportRef: React.RefObject<HTMLDivElement | null>\n}\n\nconst ScrollerContext = React.createContext<ScrollerContextValue | null>(null)\n\nexport interface MessageScrollerProviderProps {\n  children?: React.ReactNode\n  autoScroll?: boolean\n  scrollMargin?: number\n  defaultScrollPosition?: \"first\" | \"last\" | \"last-anchor\"\n  scrollEdgeThreshold?: number\n  scrollPreviousItemPeek?: number\n}\n\nfunction MessageScrollerProvider({\n  children,\n  autoScroll = true,\n  defaultScrollPosition = \"last-anchor\",\n  scrollEdgeThreshold = 8,\n  scrollMargin = 0,\n  scrollPreviousItemPeek = 0,\n}: MessageScrollerProviderProps) {\n  const viewportRef = React.useRef<HTMLDivElement>(null)\n  const atEndRef = React.useRef(true)\n  const [atEnd, setAtEnd] = React.useState(true)\n  const [atStart, setAtStart] = React.useState(true)\n  const updateAtEnd = React.useCallback((nextAtEnd: boolean) => {\n    atEndRef.current = nextAtEnd\n    setAtEnd(nextAtEnd)\n  }, [])\n  return (\n    <ScrollerContext.Provider\n      value={{\n        autoScroll,\n        atEnd,\n        atEndRef,\n        atStart,\n        defaultScrollPosition,\n        scrollEdgeThreshold,\n        scrollMargin,\n        scrollPreviousItemPeek,\n        setAtEnd: updateAtEnd,\n        setAtStart,\n        viewportRef,\n      }}\n    >\n      {children}\n    </ScrollerContext.Provider>\n  )\n}\n\nfunction useScroller() {\n  const context = React.useContext(ScrollerContext)\n  if (!context) {\n    throw new Error(\n      \"MessageScroller components require MessageScrollerProvider\"\n    )\n  }\n  return context\n}\n\nfunction MessageScroller({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-scroller\"\n      className={cn(\n        \"group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageScrollerViewport({\n  className,\n  preserveScrollOnPrepend = false,\n  onScroll,\n  style,\n  ...props\n}: React.ComponentProps<\"div\"> & { preserveScrollOnPrepend?: boolean }) {\n  const {\n    atEndRef,\n    autoScroll,\n    defaultScrollPosition,\n    scrollEdgeThreshold,\n    scrollMargin,\n    scrollPreviousItemPeek,\n    setAtEnd,\n    setAtStart,\n    viewportRef,\n  } = useScroller()\n\n  React.useLayoutEffect(() => {\n    const viewport = viewportRef.current\n    if (!viewport) return\n    const update = () => {\n      const atEnd =\n        viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <=\n        scrollEdgeThreshold\n      setAtEnd(atEnd)\n      setAtStart(viewport.scrollTop <= scrollEdgeThreshold)\n    }\n    if (defaultScrollPosition === \"last-anchor\") {\n      const anchors = viewport.querySelectorAll<HTMLElement>(\n        '[data-scroll-anchor=\"true\"]'\n      )\n      const anchor = anchors.item(anchors.length - 1)\n      if (anchor) anchor.scrollIntoView({ block: \"end\" })\n      else viewport.scrollTop = viewport.scrollHeight\n    } else if (defaultScrollPosition === \"last\") {\n      viewport.scrollTop = viewport.scrollHeight\n    }\n    let previousScrollHeight = viewport.scrollHeight\n    const observer = new MutationObserver((records) => {\n      const nextScrollHeight = viewport.scrollHeight\n      const prepended = records.some(\n        (record) =>\n          record.type === \"childList\" &&\n          record.addedNodes.length > 0 &&\n          (record.previousSibling === null ||\n            (record.previousSibling instanceof HTMLElement &&\n              record.previousSibling.dataset.slot ===\n                \"message-scroller-spacer\"))\n      )\n      if (preserveScrollOnPrepend && prepended) {\n        viewport.scrollTop += nextScrollHeight - previousScrollHeight\n      } else if (autoScroll && atEndRef.current) {\n        viewport.scrollTo({ top: nextScrollHeight })\n      }\n      previousScrollHeight = nextScrollHeight\n      update()\n    })\n    observer.observe(viewport, { childList: true, subtree: true })\n    update()\n    return () => observer.disconnect()\n  }, [\n    atEndRef,\n    autoScroll,\n    defaultScrollPosition,\n    preserveScrollOnPrepend,\n    scrollEdgeThreshold,\n    setAtEnd,\n    setAtStart,\n    viewportRef,\n  ])\n\n  return (\n    <div\n      ref={viewportRef}\n      data-slot=\"message-scroller-viewport\"\n      className={cn(\n        \"size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain\",\n        className\n      )}\n      style={{\n        scrollPaddingBlockStart: scrollPreviousItemPeek,\n        scrollPaddingBlockEnd: scrollMargin,\n        ...style,\n      }}\n      onScroll={(event) => {\n        const viewport = event.currentTarget\n        setAtEnd(\n          viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <=\n            scrollEdgeThreshold\n        )\n        setAtStart(viewport.scrollTop <= scrollEdgeThreshold)\n        onScroll?.(event)\n      }}\n      {...props}\n    />\n  )\n}\n\nfunction MessageScrollerContent({\n  className,\n  spacerClassName,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & { spacerClassName?: string }) {\n  return (\n    <div\n      data-slot=\"message-scroller-content\"\n      className={cn(\"flex min-h-full flex-col gap-8\", className)}\n      {...props}\n    >\n      {spacerClassName ? (\n        <div\n          aria-hidden=\"true\"\n          data-slot=\"message-scroller-spacer\"\n          className={cn(\"flex-1\", spacerClassName)}\n        />\n      ) : null}\n      {children}\n    </div>\n  )\n}\n\nfunction MessageScrollerItem({\n  className,\n  messageId,\n  scrollAnchor,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  messageId?: string\n  scrollAnchor?: boolean\n}) {\n  return (\n    <div\n      data-slot=\"message-scroller-item\"\n      data-message-id={messageId}\n      data-scroll-anchor={scrollAnchor || undefined}\n      className={cn(\"min-w-0 shrink-0\", className)}\n      {...props}\n    />\n  )\n}\n\nexport interface MessageScrollerButtonProps\n  extends Omit<React.ComponentProps<typeof Button>, \"children\"> {\n  behavior?: ScrollBehavior\n  direction?: \"start\" | \"end\"\n  render?: React.ReactElement\n  children?: React.ReactNode\n}\n\nfunction MessageScrollerButton({\n  behavior = \"smooth\",\n  direction = \"end\",\n  className,\n  children,\n  render,\n  onClick,\n  ...props\n}: MessageScrollerButtonProps) {\n  const { atEnd, atStart, viewportRef } = useScroller()\n  const inactive = direction === \"end\" ? atEnd : atStart\n  return (\n    <Button\n      asChild={Boolean(render)}\n      type=\"button\"\n      aria-hidden={inactive}\n      tabIndex={inactive ? -1 : 0}\n      className={cn(\n        \"bg-background absolute left-1/2 -translate-x-1/2 border transition-[opacity,transform] duration-200\",\n        direction === \"end\" ? \"bottom-4\" : \"top-4\",\n        inactive && \"pointer-events-none translate-y-2 opacity-0\",\n        className\n      )}\n      onClick={(event) => {\n        const viewport = viewportRef.current\n        viewport?.scrollTo({\n          top: direction === \"end\" ? viewport.scrollHeight : 0,\n          behavior,\n        })\n        onClick?.(event)\n      }}\n      {...props}\n    >\n      {render ?? (\n        <>\n          {children ?? (\n            <ArrowDownIcon\n              className={cn(direction === \"start\" && \"rotate-180\")}\n            />\n          )}\n          <span className=\"sr-only\">\n            {direction === \"end\" ? \"Scroll to end\" : \"Scroll to start\"}\n          </span>\n        </>\n      )}\n    </Button>\n  )\n}\n\nexport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/button.tsx",
          "target": "@components/voice-agents/livekit/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-chat-indicator.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-indicator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { motion, useReducedMotion, type MotionProps } from \"motion/react\"\nimport { type ComponentProps, type Ref } from \"react\"\n\nconst motionAnimationProps = {\n  variants: {\n    hidden: {\n      opacity: 0,\n      scale: 0.1,\n      transition: {\n        duration: 0.1,\n        ease: \"linear\" as const,\n      },\n    },\n    visible: {\n      opacity: [0.5, 1],\n      scale: [0.9, 1],\n      transition: {\n        type: \"spring\" as const,\n        bounce: 0,\n        duration: 0.5,\n        repeat: Infinity,\n        repeatType: \"mirror\" as const,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\nconst agentChatIndicatorVariants = cva(\n  \"bg-muted-foreground inline-block size-2.5 rounded-full\",\n  {\n    variants: {\n      size: {\n        sm: \"size-3\",\n        md: \"size-4\",\n        lg: \"size-6\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentChatIndicator component.\n */\nexport interface AgentChatIndicatorProps extends MotionProps {\n  /**\n   * The size of the indicator dot.\n   * @defaultValue 'md'\n   */\n  size?: \"sm\" | \"md\" | \"lg\"\n  /**\n   * Additional CSS class names to apply to the indicator.\n   */\n  className?: string\n  /**\n   * Allows getting a ref to the component instance.\\nOnce the component unmounts, React will set `ref.current` to `null`\\n(or call the ref with `null` if you passed a callback ref).\\n@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}\n   */\n  ref?: Ref<HTMLSpanElement>\n}\n\n/**\n * An animated indicator that shows the agent is processing or thinking.\n * Displays as a pulsing dot, typically used in chat interfaces.\n *\n * @extends ComponentProps<'span'>\n *\n * @example\n * ```tsx\n * {agentState === 'thinking' && <AgentChatIndicator size=\"md\" />}\n * ```\n */\nexport function AgentChatIndicator({\n  size = \"md\",\n  className,\n  ...props\n}: AgentChatIndicatorProps &\n  ComponentProps<\"span\"> &\n  VariantProps<typeof agentChatIndicatorVariants>) {\n  const prefersReducedMotion = useReducedMotion()\n\n  return (\n    <motion.span\n      {...(prefersReducedMotion\n        ? { initial: false, animate: { opacity: 1, scale: 1 } }\n        : motionAnimationProps)}\n      transition={{ duration: 0.1, ease: \"linear\" as const }}\n      className={cn(agentChatIndicatorVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-control-bar.tsx",
          "target": "@components/voice-agents/livekit/agent-control-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/voice-agents/livekit/_ui/button\"\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { AgentDisconnectButton } from \"@/components/voice-agents/livekit/agent-disconnect-button\"\nimport { AgentTrackControl } from \"@/components/voice-agents/livekit/agent-track-control\"\nimport {\n  AgentTrackToggle,\n  agentTrackToggleVariants,\n} from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport {\n  useInputControls,\n  usePublishPermissions,\n  type UseInputControlsProps,\n} from \"@/components/voice-agents/livekit/hooks/use-agent-control-bar\"\nimport { cn } from \"@/lib/utils\"\nimport { useChat } from \"@livekit/components-react\"\nimport { Track } from \"livekit-client\"\nimport { Loader, MessageSquareTextIcon, SendHorizontal } from \"lucide-react\"\nimport { motion, type MotionProps } from \"motion/react\"\nimport { useEffect, useRef, useState, type ComponentProps } from \"react\"\n\nconst LK_TOGGLE_VARIANT_1 = [\n  \"data-[state=off]:bg-accent data-[state=off]:hover:bg-foreground/10\",\n  \"data-[state=off]:[&_~_button]:bg-accent data-[state=off]:[&_~_button]:hover:bg-foreground/10\",\n  \"data-[state=off]:border-border data-[state=off]:hover:border-foreground/12\",\n  \"data-[state=off]:[&_~_button]:border-border data-[state=off]:[&_~_button]:hover:border-foreground/12\",\n  \"data-[state=off]:text-destructive data-[state=off]:hover:text-destructive data-[state=off]:focus:text-destructive\",\n  \"data-[state=off]:focus-visible:ring-foreground/12 data-[state=off]:focus-visible:border-ring\",\n  \"dark:data-[state=off]:[&_~_button]:bg-accent dark:data-[state=off]:[&_~_button]:hover:bg-foreground/10\",\n]\n\nconst LK_TOGGLE_VARIANT_2 = [\n  \"data-[state=off]:bg-accent data-[state=off]:hover:bg-foreground/10\",\n  \"data-[state=off]:border-border data-[state=off]:hover:border-foreground/12\",\n  \"data-[state=off]:focus-visible:border-ring data-[state=off]:focus-visible:ring-foreground/12\",\n  \"data-[state=off]:text-foreground data-[state=off]:hover:text-foreground data-[state=off]:focus:text-foreground\",\n  \"data-[state=on]:bg-blue-500/20 data-[state=on]:hover:bg-blue-500/30\",\n  \"data-[state=on]:border-blue-700/10 data-[state=on]:text-blue-700 data-[state=on]:ring-blue-700/30\",\n  \"data-[state=on]:focus-visible:border-blue-700/50\",\n  \"dark:data-[state=on]:bg-blue-500/20 dark:data-[state=on]:text-blue-300\",\n]\n\nconst MOTION_PROPS: MotionProps = {\n  variants: {\n    hidden: {\n      height: 0,\n      opacity: 0,\n      marginBottom: 0,\n    },\n    visible: {\n      height: \"auto\",\n      opacity: 1,\n      marginBottom: 12,\n    },\n  },\n  initial: \"hidden\",\n  transition: {\n    duration: 0.3,\n    ease: \"easeOut\",\n  },\n}\n\ninterface AgentChatInputProps {\n  chatOpen: boolean\n  onSend?: (message: string) => void\n  className?: string\n}\n\nfunction AgentChatInput({\n  chatOpen,\n  onSend = async () => {},\n  className,\n}: AgentChatInputProps) {\n  const inputRef = useRef<HTMLTextAreaElement>(null)\n  const [isSending, setIsSending] = useState(false)\n  const [message, setMessage] = useState<string>(\"\")\n  const isDisabled = isSending || message.trim().length === 0\n\n  const handleSend = async () => {\n    if (isDisabled) {\n      return\n    }\n\n    try {\n      setIsSending(true)\n      await onSend(message.trim())\n      setMessage(\"\")\n    } catch (error) {\n      console.error(error)\n    } finally {\n      setIsSending(false)\n    }\n  }\n\n  const handleKeyDown = async (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === \"Enter\" && !e.shiftKey) {\n      e.preventDefault()\n      handleSend()\n    }\n  }\n\n  const handleButtonClick = async () => {\n    if (isDisabled) return\n    await handleSend()\n  }\n\n  useEffect(() => {\n    if (chatOpen) return\n    // when not disabled refocus on input\n    inputRef.current?.focus()\n  }, [chatOpen])\n\n  return (\n    <div\n      className={cn(\n        \"mb-3 flex grow items-end gap-2 rounded-md pl-1 text-sm\",\n        className\n      )}\n    >\n      <textarea\n        autoFocus\n        ref={inputRef}\n        value={message}\n        disabled={!chatOpen || isSending}\n        placeholder=\"Type something...\"\n        onKeyDown={handleKeyDown}\n        onChange={(e) => setMessage(e.target.value)}\n        className=\"field-sizing-content max-h-16 min-h-8 flex-1 resize-none py-2 [scrollbar-width:thin] focus:outline-none disabled:cursor-not-allowed disabled:opacity-50\"\n      />\n      <Button\n        size=\"icon\"\n        type=\"button\"\n        disabled={isDisabled}\n        variant={isDisabled ? \"secondary\" : \"default\"}\n        title={isSending ? \"Sending...\" : \"Send\"}\n        onClick={handleButtonClick}\n        className=\"self-end disabled:cursor-not-allowed\"\n      >\n        {isSending ? <Loader className=\"animate-spin\" /> : <SendHorizontal />}\n      </Button>\n    </div>\n  )\n}\n\n/** Configuration for which controls to display in the AgentControlBar. */\nexport interface AgentControlBarControls {\n  /**\n   * Whether to show the leave/disconnect button.\n   *\n   * @defaultValue true\n   */\n  leave?: boolean\n  /**\n   * Whether to show the camera toggle control.\n   *\n   * @defaultValue true (if camera publish permission is granted)\n   */\n  camera?: boolean\n  /**\n   * Whether to show the microphone toggle control.\n   *\n   * @defaultValue true (if microphone publish permission is granted)\n   */\n  microphone?: boolean\n  /**\n   * Whether to show the screen share toggle control.\n   *\n   * @defaultValue true (if screen share publish permission is granted)\n   */\n  screenShare?: boolean\n  /**\n   * Whether to show the chat toggle control.\n   *\n   * @defaultValue true (if data publish permission is granted)\n   */\n  chat?: boolean\n}\n\nexport interface AgentControlBarProps extends UseInputControlsProps {\n  /**\n   * The visual style of the control bar.\n   *\n   * @default 'default'\n   */\n  variant?: \"default\" | \"outline\" | \"livekit\"\n  /**\n   * This takes an object with the following keys: `leave`, `microphone`, `screenShare`, `camera`,\n   * `chat`. Each key maps to a boolean value that determines whether the control is displayed.\n   *\n   * @default\n   * {\n   *   leave: true,\n   *   microphone: true,\n   *   screenShare: true,\n   *   camera: true,\n   *   chat: true,\n   * }\n   */\n  controls?: AgentControlBarControls\n  /**\n   * Whether to save user choices.\n   *\n   * @default true\n   */\n  saveUserChoices?: boolean\n  /**\n   * Whether the agent is connected to a session.\n   *\n   * @default false\n   */\n  isConnected?: boolean\n  /**\n   * Whether the chat input interface is open.\n   *\n   * @default false\n   */\n  isChatOpen?: boolean\n  /** The callback for when the user disconnects. */\n  onDisconnect?: () => void\n  /** The callback for when the chat is opened or closed. */\n  onIsChatOpenChange?: (open: boolean) => void\n  /** The callback for when a device error occurs. */\n  onDeviceError?: (error: { source: Track.Source; error: Error }) => void\n}\n\n/**\n * A control bar specifically designed for voice assistant interfaces. Provides controls for\n * microphone, camera, screen share, chat, and disconnect. Includes an expandable chat input for\n * text-based interaction with the agent.\n *\n * @example\n *\n * ```tsx\n * <AgentControlBar\n *   variant=\"livekit\"\n *   isConnected={true}\n *   onDisconnect={() => handleDisconnect()}\n *   controls={{\n *     microphone: true,\n *     camera: true,\n *     screenShare: false,\n *     chat: true,\n *     leave: true,\n *   }}\n * />;\n * ```\n *\n * @extends ComponentProps<'div'>\n */\nexport function AgentControlBar({\n  variant = \"default\",\n  controls,\n  isChatOpen = false,\n  isConnected = false,\n  saveUserChoices = true,\n  onDisconnect,\n  onDeviceError,\n  onIsChatOpenChange,\n  className,\n  ...props\n}: AgentControlBarProps & ComponentProps<\"div\">) {\n  const { send } = useChat()\n  const publishPermissions = usePublishPermissions()\n  const [isChatOpenUncontrolled, setIsChatOpenUncontrolled] =\n    useState(isChatOpen)\n  const {\n    microphoneTrack,\n    cameraToggle,\n    microphoneToggle,\n    screenShareToggle,\n    handleAudioDeviceChange,\n    handleVideoDeviceChange,\n    handleMicrophoneDeviceSelectError,\n    handleCameraDeviceSelectError,\n  } = useInputControls({ onDeviceError, saveUserChoices })\n\n  const handleSendMessage = async (message: string) => {\n    await send(message)\n  }\n\n  const visibleControls = {\n    leave: controls?.leave ?? true,\n    microphone: controls?.microphone ?? publishPermissions.microphone,\n    screenShare: controls?.screenShare ?? publishPermissions.screenShare,\n    camera: controls?.camera ?? publishPermissions.camera,\n    chat: controls?.chat ?? publishPermissions.data,\n  }\n\n  const isEmpty = Object.values(visibleControls).every((value) => !value)\n\n  if (isEmpty) {\n    console.warn(\n      \"AgentControlBar: `visibleControls` contains only false values.\"\n    )\n    return null\n  }\n\n  return (\n    <div\n      aria-label=\"Voice assistant controls\"\n      className={cn(\n        \"bg-background border-input/50 dark:border-muted @container/agent-control-bar flex flex-col border p-3 drop-shadow-md/3\",\n        variant === \"livekit\" ? \"rounded-[31px]\" : \"rounded-lg\",\n        className\n      )}\n      {...props}\n    >\n      <motion.div\n        {...MOTION_PROPS}\n        inert={!(isChatOpen || isChatOpenUncontrolled)}\n        animate={isChatOpen || isChatOpenUncontrolled ? \"visible\" : \"hidden\"}\n        className=\"border-input/50 flex w-full items-start overflow-hidden border-b\"\n      >\n        <AgentChatInput\n          chatOpen={isChatOpen || isChatOpenUncontrolled}\n          onSend={handleSendMessage}\n          className={cn(variant === \"livekit\" && \"[&_button]:rounded-full\")}\n        />\n      </motion.div>\n\n      <div className=\"flex gap-1\">\n        <div className=\"flex grow gap-1\">\n          {/* Toggle Microphone */}\n          {visibleControls.microphone && (\n            <AgentTrackControl\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              kind=\"audioinput\"\n              aria-label=\"Toggle microphone\"\n              source={Track.Source.Microphone}\n              pressed={microphoneToggle.enabled}\n              disabled={microphoneToggle.pending}\n              audioTrack={microphoneTrack}\n              onPressedChange={microphoneToggle.toggle}\n              onActiveDeviceChange={handleAudioDeviceChange}\n              onMediaDeviceError={handleMicrophoneDeviceSelectError}\n              className={cn(\n                variant === \"livekit\" && [\n                  LK_TOGGLE_VARIANT_1,\n                  \"rounded-full [&_button:first-child]:rounded-l-full [&_button:last-child]:rounded-r-full\",\n                ]\n              )}\n            />\n          )}\n\n          {/* Toggle Camera */}\n          {visibleControls.camera && (\n            <AgentTrackControl\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              kind=\"videoinput\"\n              aria-label=\"Toggle camera\"\n              source={Track.Source.Camera}\n              pressed={cameraToggle.enabled}\n              pending={cameraToggle.pending}\n              disabled={cameraToggle.pending}\n              onPressedChange={cameraToggle.toggle}\n              onMediaDeviceError={handleCameraDeviceSelectError}\n              onActiveDeviceChange={handleVideoDeviceChange}\n              className={cn(\n                variant === \"livekit\" && [\n                  LK_TOGGLE_VARIANT_1,\n                  \"rounded-full [&_button:first-child]:rounded-l-full [&_button:last-child]:rounded-r-full\",\n                ]\n              )}\n            />\n          )}\n\n          {/* Toggle Screen Share */}\n          {visibleControls.screenShare && (\n            <AgentTrackToggle\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              aria-label=\"Toggle screen share\"\n              source={Track.Source.ScreenShare}\n              pressed={screenShareToggle.enabled}\n              disabled={screenShareToggle.pending}\n              onPressedChange={screenShareToggle.toggle}\n              className={cn(\n                variant === \"livekit\" && [LK_TOGGLE_VARIANT_2, \"rounded-full\"]\n              )}\n            />\n          )}\n\n          {/* Toggle Transcript */}\n          {visibleControls.chat && (\n            <Toggle\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              pressed={isChatOpen || isChatOpenUncontrolled}\n              aria-label=\"Toggle transcript\"\n              onPressedChange={(state) => {\n                if (!onIsChatOpenChange) setIsChatOpenUncontrolled(state)\n                else onIsChatOpenChange(state)\n              }}\n              className={agentTrackToggleVariants({\n                variant: variant === \"outline\" ? \"outline\" : \"default\",\n                className: cn(\n                  variant === \"livekit\" && [LK_TOGGLE_VARIANT_2, \"rounded-full\"]\n                ),\n              })}\n            >\n              <MessageSquareTextIcon />\n            </Toggle>\n          )}\n        </div>\n\n        {/* Disconnect */}\n        {visibleControls.leave && (\n          <AgentDisconnectButton\n            onClick={onDisconnect}\n            disabled={!isConnected}\n            className={cn(\n              variant === \"livekit\" &&\n                \"bg-destructive/10 dark:bg-destructive/10 text-destructive hover:bg-destructive/20 dark:hover:bg-destructive/20 focus:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/4 rounded-full font-mono text-xs font-bold tracking-wider\"\n            )}\n          >\n            <span className=\"sr-only uppercase @sm/agent-control-bar:not-sr-only\">\n              End{\" \"}\n              <span className=\"sr-only @md/agent-control-bar:not-sr-only\">\n                call\n              </span>\n            </span>\n          </AgentDisconnectButton>\n        )}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/toggle.tsx",
          "target": "@components/voice-agents/livekit/_ui/toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline:\n          \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-9 min-w-9 px-2\",\n        sm: \"h-8 min-w-8 px-1.5\",\n        lg: \"h-10 min-w-10 px-2.5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n  VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      className={cn(toggleVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-disconnect-button.tsx",
          "target": "@components/voice-agents/livekit/agent-disconnect-button.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Button,\n  type buttonVariants,\n} from \"@/components/voice-agents/livekit/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { useSessionContext } from \"@livekit/components-react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { PhoneOffIcon } from \"lucide-react\"\nimport { type ComponentProps } from \"react\"\n\n/**\n * Props for the AgentDisconnectButton component.\n */\nexport interface AgentDisconnectButtonProps\n  extends ComponentProps<\"button\">,\n    VariantProps<typeof buttonVariants> {\n  /**\n   * Custom icon to display. Defaults to PhoneOffIcon.\n   */\n  icon?: React.ReactNode\n  /**\n   * The size of the button.\n   * @default 'default'\n   */\n  size?: \"default\" | \"sm\" | \"lg\" | \"icon\"\n  /**\n   * The variant of the button.\n   * @default 'destructive'\n   */\n  variant?: \"default\" | \"outline\" | \"destructive\" | \"ghost\" | \"link\"\n  /**\n   * The children to render.\n   */\n  children?: React.ReactNode\n  /**\n   * The callback for when the button is clicked.\n   */\n  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\n/**\n * A button to disconnect from the current agent session.\n * Calls the session's end() method when clicked.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentDisconnectButton onClick={() => console.log('Disconnecting...')} />\n * ```\n */\nexport function AgentDisconnectButton({\n  icon,\n  size = \"default\",\n  variant = \"destructive\",\n  children,\n  onClick,\n  ...props\n}: AgentDisconnectButtonProps) {\n  const { end } = useSessionContext()\n  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n    onClick?.(event)\n    if (typeof end === \"function\") {\n      end()\n    }\n  }\n\n  return (\n    <Button size={size} variant={variant} onClick={handleClick} {...props}>\n      {icon ?? <PhoneOffIcon />}\n      {children ?? (\n        <span className={cn(size?.includes(\"icon\") && \"sr-only\")}>\n          End call\n        </span>\n      )}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-control.tsx",
          "target": "@components/voice-agents/livekit/agent-track-control.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/voice-agents/livekit/_ui/select\"\nimport { type toggleVariants } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { AgentAudioVisualizerBar } from \"@/components/voice-agents/livekit/agent-audio-visualizer-bar\"\nimport { AgentTrackToggle } from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMaybeRoomContext,\n  useMediaDeviceSelect,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { useEffect, useMemo, useState } from \"react\"\n\nconst selectVariants = cva(\n  [\n    \"rounded-l-none shadow-none pl-2 \",\n    \"text-foreground hover:text-muted-foreground\",\n    \"peer-data-[state=on]/track:bg-muted peer-data-[state=on]/track:hover:bg-foreground/10\",\n    \"peer-data-[state=off]/track:text-destructive\",\n    \"peer-data-[state=off]/track:focus-visible:border-destructive peer-data-[state=off]/track:focus-visible:ring-destructive/30\",\n    \"[&_svg]:opacity-100\",\n  ],\n  {\n    variants: {\n      variant: {\n        default: [\n          \"border-none\",\n          \"peer-data-[state=off]/track:bg-destructive/10\",\n          \"peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"peer-data-[state=off]/track:[&_svg]:text-destructive!\",\n\n          \"dark:peer-data-[state=on]/track:bg-accent\",\n          \"dark:peer-data-[state=on]/track:hover:bg-foreground/10\",\n          \"dark:peer-data-[state=off]/track:bg-destructive/10\",\n          \"dark:peer-data-[state=off]/track:hover:bg-destructive/15\",\n        ],\n        outline: [\n          \"border border-l-0\",\n          \"peer-data-[state=off]/track:border-destructive/20\",\n          \"peer-data-[state=off]/track:bg-destructive/10\",\n          \"peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"peer-data-[state=off]/track:[&_svg]:text-destructive!\",\n          \"peer-data-[state=on]/track:hover:border-foreground/12\",\n\n          \"dark:peer-data-[state=off]/track:bg-destructive/10\",\n          \"dark:peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"dark:peer-data-[state=on]/track:bg-accent\",\n          \"dark:peer-data-[state=on]/track:hover:bg-foreground/10\",\n        ],\n      },\n      size: {\n        default: \"w-[180px]\",\n        sm: \"w-auto\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\n/**\n * Props for the TrackDeviceSelect component. */\ntype TrackDeviceSelectProps = React.ComponentProps<typeof SelectTrigger> &\n  VariantProps<typeof selectVariants> & {\n    /**\n     * The type of media device (audioinput or videoinput).\n     */\n    kind: MediaDeviceKind\n    /**\n     * Array of available devices\n     */\n    devices: MediaDeviceInfo[]\n    /**\n     * Active device ID\n     */\n    activeDeviceId?: string\n    /**\n     * The size of the select.\n     * @defaultValue 'default'\n     */\n    size?: \"default\" | \"sm\"\n    /**\n     * The variant of the select.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\" | null\n    /**\n     * Whether to request permissions for the media device.\n     */\n    requestPermissions?: boolean\n    /**\n     * Callback when the select is opened or closed.\n     */\n    onOpen: (open: boolean) => void\n    /**\n     * Callback when the active device changes.\n     */\n    onActiveDeviceChange?: (deviceId: string) => void\n  }\n\n/**\n * A select component for selecting a media device.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <TrackDeviceSelect\n *   size=\"sm\"\n *   variant=\"outline\"\n *   kind=\"audioinput\"\n *   devices={devices}\n *   activeDeviceId={activeDeviceId}\n *   onOpen={setOpen}\n *   onActiveDeviceChange={setActiveDeviceId}\n * />\n * ```\n */\nfunction TrackDeviceSelect({\n  kind,\n  devices,\n  activeDeviceId,\n  size = \"default\",\n  variant = \"default\",\n  className,\n  onOpen,\n  onActiveDeviceChange,\n  ...props\n}: TrackDeviceSelectProps) {\n  const [open, setOpen] = useState(false)\n\n  const handleOpenChange = (open: boolean) => {\n    setOpen(open)\n    onOpen(open)\n  }\n\n  if (devices.length < 2) {\n    return null\n  }\n\n  return (\n    <Select\n      open={open}\n      value={activeDeviceId}\n      onOpenChange={handleOpenChange}\n      onValueChange={onActiveDeviceChange}\n    >\n      <SelectTrigger\n        className={cn(selectVariants({ size, variant }), className)}\n        {...props}\n      >\n        {size !== \"sm\" && (\n          <SelectValue\n            className=\"font-mono text-sm\"\n            placeholder={`Select a ${kind}`}\n          />\n        )}\n      </SelectTrigger>\n      <SelectContent position=\"popper\">\n        {devices.map((device) => (\n          <SelectItem\n            key={device.deviceId}\n            value={device.deviceId}\n            className=\"font-mono text-xs\"\n          >\n            {device.label}\n          </SelectItem>\n        ))}\n      </SelectContent>\n    </Select>\n  )\n}\n\n/**\n * Props for the AgentTrackControl component.\n */\nexport type AgentTrackControlProps = VariantProps<typeof toggleVariants> & {\n  /**\n   * The type of media device (audioinput or videoinput).\n   */\n  kind: MediaDeviceKind\n  /**\n   * The track source to control (Microphone, Camera, or ScreenShare).\n   */\n  source: \"camera\" | \"microphone\" | \"screen_share\"\n  /**\n   * Whether the track is currently enabled/published.\n   */\n  pressed?: boolean\n  /**\n   * Whether the control is in a pending/loading state.\n   */\n  pending?: boolean\n  /**\n   * Whether the control is disabled.\n   */\n  disabled?: boolean\n  /**\n   * The audio track reference for visualization (only for microphone).\n   */\n  audioTrack?: TrackReferenceOrPlaceholder\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Callback when the pressed state changes.\n   */\n  onPressedChange?: (pressed: boolean) => void\n  /**\n   * Callback when a media device error occurs.\n   */\n  onMediaDeviceError?: (error: Error) => void\n  /**\n   * Callback when the active device changes.\n   */\n  onActiveDeviceChange?: (deviceId: string) => void\n}\n\n/**\n * A combined track toggle and device selector control.\n * Includes a toggle button and a dropdown to select the active device.\n * For microphone tracks, displays an audio visualizer.\n *\n * @example\n * ```tsx\n * <AgentTrackControl\n *   kind=\"audioinput\"\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   audioTrack={micTrackRef}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n *   onActiveDeviceChange={(deviceId) => setMicDevice(deviceId)}\n * />\n * ```\n */\nexport function AgentTrackControl({\n  kind,\n  variant = \"default\",\n  source,\n  pressed,\n  pending,\n  disabled,\n  className,\n  audioTrack,\n  onPressedChange,\n  onMediaDeviceError,\n  onActiveDeviceChange,\n}: AgentTrackControlProps) {\n  const room = useMaybeRoomContext()\n  const [requestPermissionsState, setRequestPermissionsState] = useState(false)\n  const { devices, activeDeviceId, setActiveMediaDevice } =\n    useMediaDeviceSelect({\n      room,\n      kind,\n      requestPermissions: requestPermissionsState,\n      onError: onMediaDeviceError,\n    })\n\n  useEffect(() => {\n    // A track was already acquired elsewhere (e.g. session.start()), so permission is already\n    // granted — safe to fetch labeled devices without a second getUserMedia prompt. Without\n    // this, the list stays label-less until a page reload, since the device observer only\n    // re-fetches when `requestPermissions` changes value. Screen share has no `kind` and no\n    // associated device list, so it should never trigger a mic/camera permission request.\n    if (pressed && kind) {\n      setRequestPermissionsState(true)\n    }\n  }, [pressed, kind])\n\n  const handleOpenChange = (open: boolean) => {\n    if (open) {\n      setRequestPermissionsState(true)\n    }\n  }\n\n  const handleActiveDeviceChange = (deviceId: string) => {\n    setActiveMediaDevice(deviceId)\n    onActiveDeviceChange?.(deviceId)\n  }\n\n  const filteredDevices = useMemo(\n    () => devices.filter((d) => d.deviceId !== \"\"),\n    [devices]\n  )\n  // Before permission is granted, the browser reports devices with blank ids, which get filtered\n  // out here — that's an *unknown* device count, not a confirmed empty one. Only treat it as\n  // \"no devices\" once a permission-gated check has actually run and still come up empty;\n  // otherwise the toggle disables itself before the user ever gets a chance to grant permission.\n  const noDevices =\n    Boolean(kind) && requestPermissionsState && filteredDevices.length === 0\n  const resolvedPressed = pressed && !noDevices\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center gap-0 rounded-md\",\n        variant === \"outline\" && \"shadow-xs [&_button]:shadow-none\",\n        className\n      )}\n    >\n      <AgentTrackToggle\n        source={source}\n        pending={pending}\n        variant={variant ?? \"default\"}\n        pressed={resolvedPressed}\n        disabled={noDevices || disabled}\n        onPressedChange={onPressedChange}\n        className=\"peer/track group/track focus:z-10 has-[.audiovisualizer]:w-auto has-[.audiovisualizer]:px-3 has-[~_button]:rounded-r-none has-[~_button]:border-r-0 has-[~_button]:pr-2 has-[~_button]:pl-3\"\n      >\n        {audioTrack && (\n          <AgentAudioVisualizerBar\n            size=\"icon\"\n            barCount={3}\n            state={resolvedPressed ? \"speaking\" : \"disconnected\"}\n            audioTrack={resolvedPressed ? audioTrack : undefined}\n            className=\"audiovisualizer flex h-6 w-auto items-center justify-center gap-0.5\"\n          >\n            <span\n              className={cn([\n                \"h-full min-h-0.5 w-0.5 origin-center\",\n                \"group-data-[state=on]/track:bg-foreground group-data-[state=off]/track:bg-destructive\",\n                \"data-lk-muted:bg-muted\",\n              ])}\n            />\n          </AgentAudioVisualizerBar>\n        )}\n      </AgentTrackToggle>\n      {kind && (\n        <TrackDeviceSelect\n          size=\"sm\"\n          kind={kind}\n          variant={variant}\n          devices={filteredDevices}\n          activeDeviceId={activeDeviceId}\n          onOpen={handleOpenChange}\n          onActiveDeviceChange={handleActiveDeviceChange}\n          className={cn([\n            \"relative\",\n            'before:bg-border before:absolute before:inset-y-0 before:left-0 before:my-2.5 before:w-px has-[~_button]:before:content-[\"\"]',\n            !resolvedPressed && \"before:bg-destructive/20\",\n          ])}\n        />\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/select.tsx",
          "target": "@components/voice-agents/livekit/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='text-'])]:text-muted-foreground flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"item-aligned\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span\n        data-slot=\"select-item-indicator\"\n        className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n      >\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-toggle.tsx",
          "target": "@components/voice-agents/livekit/agent-track-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Track } from \"livekit-client\"\nimport {\n  LoaderIcon,\n  MicIcon,\n  MicOffIcon,\n  MonitorOffIcon,\n  MonitorUpIcon,\n  VideoIcon,\n  VideoOffIcon,\n} from \"lucide-react\"\nimport { Fragment, useMemo, useState, type ComponentProps } from \"react\"\n\nexport const agentTrackToggleVariants = cva([\"size-9\"], {\n  variants: {\n    size: {\n      default: \"h-9 px-2 min-w-9\",\n      sm: \"h-8 px-1.5 min-w-8\",\n      lg: \"h-10 px-2.5 min-w-10\",\n    },\n    variant: {\n      default: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive\",\n        \"data-[state=off]:hover:bg-destructive/15\",\n        \"data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n        \"data-[state=on]:hover:bg-foreground/10\",\n      ],\n      outline: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive data-[state=off]:border-destructive/20\",\n        \"data-[state=off]:hover:bg-destructive/15 data-[state=off]:hover:text-destructive\",\n        \"data-[state=off]:focus:text-destructive\",\n        \"data-[state=off]:focus-visible:border-destructive data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:hover:bg-foreground/10 data-[state=on]:hover:border-foreground/12\",\n        \"dark:data-[state=on]:hover:bg-foreground/10\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n})\n\nfunction getSourceIcon(\n  source: Track.Source,\n  enabled: boolean,\n  pending = false\n) {\n  if (pending) {\n    return LoaderIcon\n  }\n\n  switch (source) {\n    case Track.Source.Microphone:\n      return enabled ? MicIcon : MicOffIcon\n    case Track.Source.Camera:\n      return enabled ? VideoIcon : VideoOffIcon\n    case Track.Source.ScreenShare:\n      return enabled ? MonitorUpIcon : MonitorOffIcon\n    default:\n      return Fragment\n  }\n}\n\n/**\n * Props for the AgentTrackToggle component.\n */\nexport type AgentTrackToggleProps = VariantProps<\n  typeof agentTrackToggleVariants\n> &\n  ComponentProps<\"button\"> & {\n    /**\n     * The size of the toggle.\n     */\n    size?: \"sm\" | \"default\" | \"lg\"\n    /**\n     * The variant of the toggle.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\"\n    /**\n     * The track source to toggle (Microphone, Camera, or ScreenShare).\n     */\n    source: \"camera\" | \"microphone\" | \"screen_share\"\n    /**\n     * Whether the toggle is in a pending/loading state.\n     * When true, displays a loading spinner icon.\n     * @defaultValue false\n     */\n    pending?: boolean\n    /**\n     * Whether the toggle is currently pressed/enabled.\n     * @defaultValue false\n     */\n    pressed?: boolean\n    /**\n     * The default pressed state when uncontrolled.\n     * @defaultValue false\n     */\n    defaultPressed?: boolean\n    /**\n     * Callback fired when the pressed state changes.\n     */\n    onPressedChange?: (pressed: boolean) => void\n  }\n\n/**\n * A toggle button for controlling track publishing state.\n * Displays appropriate icons based on the track source and state.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentTrackToggle\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n * />\n * ```\n */\nexport function AgentTrackToggle({\n  size = \"default\",\n  variant = \"default\",\n  source,\n  pending = false,\n  pressed,\n  defaultPressed = false,\n  className,\n  onPressedChange,\n  ...props\n}: AgentTrackToggleProps) {\n  const [uncontrolledPressed, setUncontrolledPressed] = useState(\n    defaultPressed ?? false\n  )\n  const isControlled = pressed !== undefined\n  const resolvedPressed = useMemo(\n    () => (isControlled ? pressed : uncontrolledPressed) ?? false,\n    [isControlled, pressed, uncontrolledPressed]\n  )\n  const IconComponent = getSourceIcon(\n    source as Track.Source,\n    resolvedPressed,\n    pending\n  )\n  const handlePressedChange = (nextPressed: boolean) => {\n    if (!isControlled) {\n      setUncontrolledPressed(nextPressed)\n    }\n    onPressedChange?.(nextPressed)\n  }\n\n  return (\n    <Toggle\n      size={size}\n      variant={variant}\n      pressed={isControlled ? pressed : undefined}\n      defaultPressed={isControlled ? undefined : defaultPressed}\n      aria-label={`Toggle ${source}`}\n      onPressedChange={handlePressedChange}\n      className={cn(\n        agentTrackToggleVariants({\n          size,\n          variant: variant ?? \"default\",\n          className,\n        })\n      )}\n      {...props}\n    >\n      <IconComponent className={cn(pending && \"animate-spin\")} />\n      {props.children}\n    </Toggle>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-control-bar.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-control-bar.ts",
          "type": "registry:component",
          "content": "import {\n  useLocalParticipantPermissions,\n  usePersistentUserChoices,\n  useSessionContext,\n  useTrackToggle,\n  type TrackReference,\n} from \"@livekit/components-react\"\nimport { Track } from \"livekit-client\"\nimport { useCallback } from \"react\"\n\nconst trackSourceToProtocol = (source: Track.Source) => {\n  // NOTE: this mapping avoids importing the protocol package as that leads to a significant bundle size increase\n  switch (source) {\n    case Track.Source.Camera:\n      return 1\n    case Track.Source.Microphone:\n      return 2\n    case Track.Source.ScreenShare:\n      return 3\n    default:\n      return 0\n  }\n}\n\nexport interface PublishPermissions {\n  camera: boolean\n  microphone: boolean\n  screenShare: boolean\n  data: boolean\n}\n\nexport function usePublishPermissions(): PublishPermissions {\n  const localPermissions = useLocalParticipantPermissions()\n\n  const canPublishSource = (source: Track.Source) => {\n    return (\n      !!localPermissions?.canPublish &&\n      (localPermissions.canPublishSources.length === 0 ||\n        localPermissions.canPublishSources.includes(\n          trackSourceToProtocol(source)\n        ))\n    )\n  }\n\n  return {\n    camera: canPublishSource(Track.Source.Camera),\n    microphone: canPublishSource(Track.Source.Microphone),\n    screenShare: canPublishSource(Track.Source.ScreenShare),\n    data: localPermissions?.canPublishData ?? false,\n  }\n}\n\nexport interface UseInputControlsProps {\n  saveUserChoices?: boolean\n  onDisconnect?: () => void\n  onDeviceError?: (error: { source: Track.Source; error: Error }) => void\n}\n\nexport interface UseInputControlsReturn {\n  microphoneTrack?: TrackReference\n  microphoneToggle: ReturnType<typeof useTrackToggle<Track.Source.Microphone>>\n  cameraToggle: ReturnType<typeof useTrackToggle<Track.Source.Camera>>\n  screenShareToggle: ReturnType<typeof useTrackToggle<Track.Source.ScreenShare>>\n  handleAudioDeviceChange: (deviceId: string) => void\n  handleVideoDeviceChange: (deviceId: string) => void\n  handleMicrophoneDeviceSelectError: (error: Error) => void\n  handleCameraDeviceSelectError: (error: Error) => void\n}\n\nexport function useInputControls({\n  saveUserChoices = true,\n  onDeviceError,\n}: UseInputControlsProps = {}): UseInputControlsReturn {\n  const {\n    local: { microphoneTrack },\n  } = useSessionContext()\n\n  const microphoneToggle = useTrackToggle({\n    source: Track.Source.Microphone,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.Microphone, error }),\n  })\n\n  const cameraToggle = useTrackToggle({\n    source: Track.Source.Camera,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.Camera, error }),\n  })\n\n  const screenShareToggle = useTrackToggle({\n    source: Track.Source.ScreenShare,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.ScreenShare, error }),\n  })\n\n  const {\n    saveAudioInputEnabled,\n    saveVideoInputEnabled,\n    saveAudioInputDeviceId,\n    saveVideoInputDeviceId,\n  } = usePersistentUserChoices({\n    preventLoad: !saveUserChoices,\n    preventSave: !saveUserChoices,\n  })\n\n  const handleAudioDeviceChange = useCallback(\n    (deviceId: string) => {\n      saveAudioInputDeviceId(deviceId ?? \"default\")\n    },\n    [saveAudioInputDeviceId]\n  )\n\n  const handleVideoDeviceChange = useCallback(\n    (deviceId: string) => {\n      saveVideoInputDeviceId(deviceId ?? \"default\")\n    },\n    [saveVideoInputDeviceId]\n  )\n\n  const handleToggleCamera = useCallback(\n    async (enabled?: boolean) => {\n      if (screenShareToggle.enabled) {\n        screenShareToggle.toggle(false)\n      }\n      await cameraToggle.toggle(enabled)\n      // persist video input enabled preference\n      saveVideoInputEnabled(!cameraToggle.enabled)\n    },\n    [cameraToggle, screenShareToggle, saveVideoInputEnabled]\n  )\n\n  const handleToggleMicrophone = useCallback(\n    async (enabled?: boolean) => {\n      await microphoneToggle.toggle(enabled)\n      // persist audio input enabled preference\n      saveAudioInputEnabled(!microphoneToggle.enabled)\n    },\n    [microphoneToggle, saveAudioInputEnabled]\n  )\n\n  const handleToggleScreenShare = useCallback(\n    async (enabled?: boolean) => {\n      if (cameraToggle.enabled) {\n        cameraToggle.toggle(false)\n      }\n      await screenShareToggle.toggle(enabled)\n    },\n    [cameraToggle, screenShareToggle]\n  )\n  const handleMicrophoneDeviceSelectError = useCallback(\n    (error: Error) =>\n      onDeviceError?.({ source: Track.Source.Microphone, error }),\n    [onDeviceError]\n  )\n\n  const handleCameraDeviceSelectError = useCallback(\n    (error: Error) => onDeviceError?.({ source: Track.Source.Camera, error }),\n    [onDeviceError]\n  )\n\n  return {\n    microphoneTrack,\n    cameraToggle: {\n      ...cameraToggle,\n      toggle: handleToggleCamera,\n    },\n    microphoneToggle: {\n      ...microphoneToggle,\n      toggle: handleToggleMicrophone,\n    },\n    screenShareToggle: {\n      ...screenShareToggle,\n      toggle: handleToggleScreenShare,\n    },\n    handleAudioDeviceChange,\n    handleVideoDeviceChange,\n    handleMicrophoneDeviceSelectError,\n    handleCameraDeviceSelectError,\n  }\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/blocks/agent-session-view-01/components/tile-view.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-session-view-01/components/tile-view.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport {\n  useLocalParticipant,\n  useTracks,\n  useVoiceAssistant,\n  VideoTrack,\n  type TrackReference,\n} from \"@livekit/components-react\"\nimport { Track } from \"livekit-client\"\nimport { AnimatePresence, motion, type MotionProps } from \"motion/react\"\nimport React, { useMemo } from \"react\"\nimport { type AudioVisualizerConfig } from \"./agent-session-block\"\nimport { AudioVisualizer } from \"./audio-visualizer\"\n\nconst ANIMATION_TRANSITION: MotionProps[\"transition\"] = {\n  type: \"spring\",\n  stiffness: 675,\n  damping: 75,\n  mass: 1,\n}\n\nconst tileViewClassNames = {\n  // GRID\n  // 2 Columns x 3 Rows\n  grid: [\n    \"h-full w-full\",\n    \"grid gap-x-2 place-content-center\",\n    \"grid-cols-[1fr_1fr] grid-rows-[90px_1fr_90px]\",\n  ],\n  // Agent\n  // chatOpen: true,\n  // hasSecondTile: true\n  // layout: Column 1 / Row 1\n  // align: x-end y-center\n  agentChatOpenWithSecondTile: [\n    \"col-start-1 row-start-1\",\n    \"self-center justify-self-end\",\n  ],\n  // Agent\n  // chatOpen: true,\n  // hasSecondTile: false\n  // layout: Column 1 / Row 1 / Column-Span 2\n  // align: x-center y-center\n  agentChatOpenWithoutSecondTile: [\n    \"col-start-1 row-start-1\",\n    \"col-span-2\",\n    \"place-content-center\",\n  ],\n  // Agent\n  // chatOpen: false\n  // layout: Column 1 / Row 1 / Column-Span 2 / Row-Span 3\n  // align: x-center y-center\n  agentChatClosed: [\n    \"col-start-1 row-start-1\",\n    \"col-span-2 row-span-3\",\n    \"place-content-center\",\n  ],\n  // Second tile\n  // chatOpen: true,\n  // hasSecondTile: true\n  // layout: Column 2 / Row 1\n  // align: x-start y-center\n  secondTileChatOpen: [\n    \"col-start-2 row-start-1\",\n    \"self-center justify-self-start\",\n  ],\n  // Second tile\n  // chatOpen: false,\n  // hasSecondTile: false\n  // layout: Column 2 / Row 2\n  // align: x-end y-end\n  secondTileChatClosed: [\"col-start-2 row-start-3\", \"place-content-end\"],\n}\n\nexport function useLocalTrackRef(source: Track.Source) {\n  const { localParticipant } = useLocalParticipant()\n  const publication = localParticipant.getTrackPublication(source)\n  const trackRef = useMemo<TrackReference | undefined>(\n    () =>\n      publication\n        ? { source, participant: localParticipant, publication }\n        : undefined,\n    [source, publication, localParticipant]\n  )\n  return trackRef\n}\n\ninterface TileLayoutProps {\n  isChatOpen: boolean\n  audioVisualizer?: AudioVisualizerConfig\n}\n\nexport function TileLayout({ isChatOpen, audioVisualizer }: TileLayoutProps) {\n  const { videoTrack: agentVideoTrack } = useVoiceAssistant()\n  const [screenShareTrack] = useTracks([Track.Source.ScreenShare])\n  const cameraTrack: TrackReference | undefined = useLocalTrackRef(\n    Track.Source.Camera\n  )\n\n  const isCameraEnabled = cameraTrack && !cameraTrack.publication.isMuted\n  const isScreenShareEnabled =\n    screenShareTrack && !screenShareTrack.publication.isMuted\n  const hasSecondTile = isCameraEnabled || isScreenShareEnabled\n\n  const animationDelay = isChatOpen ? 0 : 0.15\n  const isAvatar = agentVideoTrack !== undefined\n  const videoWidth = agentVideoTrack?.publication.dimensions?.width ?? 0\n  const videoHeight = agentVideoTrack?.publication.dimensions?.height ?? 0\n\n  const { type: audioVisualizerType = \"bar\", ...audioVisualizerConfig } =\n    audioVisualizer ?? {}\n\n  return (\n    <div className=\"pointer-events-none absolute inset-x-0 top-8 bottom-24 z-50 @md/agent-session-block:top-12 @md/agent-session-block:bottom-40\">\n      <div className=\"relative mx-auto h-full max-w-2xl px-4 @md/agent-session-block:px-0\">\n        <div className={cn(tileViewClassNames.grid)}>\n          {/* Agent */}\n          <div\n            className={cn([\n              \"grid\",\n              !isChatOpen && tileViewClassNames.agentChatClosed,\n              isChatOpen &&\n                hasSecondTile &&\n                tileViewClassNames.agentChatOpenWithSecondTile,\n              isChatOpen &&\n                !hasSecondTile &&\n                tileViewClassNames.agentChatOpenWithoutSecondTile,\n            ])}\n          >\n            <AnimatePresence mode=\"popLayout\">\n              {!isAvatar && (\n                // Audio Agent\n                <motion.div\n                  key=\"agent\"\n                  layoutId=\"agent\"\n                  initial={{ opacity: 0 }}\n                  animate={{ opacity: 1 }}\n                  transition={{\n                    ...ANIMATION_TRANSITION,\n                    delay: animationDelay,\n                  }}\n                  className={cn(\"relative aspect-square h-[90px]\")}\n                >\n                  <AudioVisualizer\n                    key=\"audio-visualizer\"\n                    initial={{ scale: 1 }}\n                    animate={{ scale: isChatOpen ? 0.2 : 1 }}\n                    transition={{\n                      ...ANIMATION_TRANSITION,\n                      delay: animationDelay,\n                    }}\n                    type={audioVisualizerType}\n                    config={audioVisualizerConfig}\n                    className={cn(\n                      \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\",\n                      \"bg-background rounded-[50px] border border-transparent transition-[border,drop-shadow]\",\n                      isChatOpen && \"border-input shadow-2xl/10 delay-200\"\n                    )}\n                    style={{ color: audioVisualizer?.color }}\n                  />\n                </motion.div>\n              )}\n\n              {isAvatar && (\n                // Avatar Agent\n                <motion.div\n                  key=\"avatar\"\n                  layoutId=\"avatar\"\n                  initial={{\n                    scale: 1,\n                    opacity: 1,\n                    maskImage:\n                      \"radial-gradient(circle, rgba(0, 0, 0, 1) 0, rgba(0, 0, 0, 1) 20px, transparent 20px)\",\n                    filter: \"blur(20px)\",\n                  }}\n                  animate={{\n                    maskImage:\n                      \"radial-gradient(circle, rgba(0, 0, 0, 1) 0, rgba(0, 0, 0, 1) 500px, transparent 500px)\",\n                    filter: \"blur(0px)\",\n                    borderRadius: isChatOpen ? 6 : 12,\n                  }}\n                  transition={{\n                    ...ANIMATION_TRANSITION,\n                    delay: animationDelay,\n                    maskImage: {\n                      duration: 1,\n                    },\n                    filter: {\n                      duration: 1,\n                    },\n                  }}\n                  className={cn(\n                    \"overflow-hidden bg-black drop-shadow-xl/80\",\n                    isChatOpen ? \"h-[90px]\" : \"h-auto w-full\"\n                  )}\n                >\n                  <VideoTrack\n                    width={videoWidth}\n                    height={videoHeight}\n                    trackRef={agentVideoTrack}\n                    className={cn(isChatOpen && \"size-[90px] object-cover\")}\n                  />\n                </motion.div>\n              )}\n            </AnimatePresence>\n          </div>\n\n          <div\n            className={cn([\n              \"grid\",\n              isChatOpen && tileViewClassNames.secondTileChatOpen,\n              !isChatOpen && tileViewClassNames.secondTileChatClosed,\n            ])}\n          >\n            {/* Camera & Screen Share */}\n            <AnimatePresence>\n              {((cameraTrack && isCameraEnabled) ||\n                (screenShareTrack && isScreenShareEnabled)) && (\n                <motion.div\n                  key=\"camera\"\n                  layout=\"position\"\n                  layoutId=\"camera\"\n                  initial={{\n                    opacity: 0,\n                    scale: 0,\n                  }}\n                  animate={{\n                    opacity: 1,\n                    scale: 1,\n                  }}\n                  exit={{\n                    opacity: 0,\n                    scale: 0,\n                  }}\n                  transition={{\n                    ...ANIMATION_TRANSITION,\n                    delay: animationDelay,\n                  }}\n                  className=\"aspect-square size-[90px] drop-shadow-lg/20\"\n                >\n                  <VideoTrack\n                    trackRef={cameraTrack || screenShareTrack}\n                    width={\n                      (cameraTrack || screenShareTrack)?.publication.dimensions\n                        ?.width ?? 0\n                    }\n                    height={\n                      (cameraTrack || screenShareTrack)?.publication.dimensions\n                        ?.height ?? 0\n                    }\n                    className=\"bg-muted aspect-square size-[90px] rounded-md object-cover\"\n                  />\n                </motion.div>\n              )}\n            </AnimatePresence>\n          </div>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/blocks/agent-session-view-01/components/audio-visualizer.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-session-view-01/components/audio-visualizer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  AgentAudioVisualizerBar,\n  type AgentAudioVisualizerBarProps,\n} from \"@/components/voice-agents/livekit/agent-audio-visualizer-bar\"\nimport {\n  AgentAudioVisualizerGrid,\n  type AgentAudioVisualizerGridProps,\n} from \"@/components/voice-agents/livekit/agent-audio-visualizer-grid\"\nimport {\n  AgentAudioVisualizerRadial,\n  type AgentAudioVisualizerRadialProps,\n} from \"@/components/voice-agents/livekit/agent-audio-visualizer-radial\"\nimport {\n  AgentAudioVisualizerWave,\n  type AgentAudioVisualizerWaveProps,\n} from \"@/components/voice-agents/livekit/agent-audio-visualizer-wave\"\nimport { cn } from \"@/lib/utils\"\nimport { useVoiceAssistant } from \"@livekit/components-react\"\nimport { motion, type MotionProps } from \"motion/react\"\nimport React from \"react\"\n\nconst MotionAgentAudioVisualizerBar = motion.create(AgentAudioVisualizerBar)\nconst MotionAgentAudioVisualizerGrid = motion.create(AgentAudioVisualizerGrid)\nconst MotionAgentAudioVisualizerRadial = motion.create(\n  AgentAudioVisualizerRadial\n)\nconst MotionAgentAudioVisualizerWave = motion.create(AgentAudioVisualizerWave)\n\nfunction getGridSize(\n  rowCount: number,\n  columnCount: number\n): AgentAudioVisualizerBarProps[\"size\"] {\n  const totalCount = rowCount * columnCount\n\n  if (totalCount < 100) {\n    return \"xl\"\n  } else if (totalCount < 200) {\n    return \"lg\"\n  } else if (totalCount < 300) {\n    return \"md\"\n  }\n\n  return \"sm\"\n}\n\nfunction getBarSize(barCount: number): AgentAudioVisualizerBarProps[\"size\"] {\n  if (barCount <= 5) {\n    return \"xl\"\n  } else if (barCount <= 10) {\n    return \"lg\"\n  } else if (barCount <= 15) {\n    return \"md\"\n  } else if (barCount <= 30) {\n    return \"sm\"\n  }\n\n  return \"icon\"\n}\n\nfunction getBarClassName(size: AgentAudioVisualizerBarProps[\"size\"]) {\n  if (size == \"xl\") {\n    return \"size-[450px] *:min-h-[64px] *:w-[64px] gap-4\"\n  } else if (size == \"lg\") {\n    return \"size-[450px] *:min-h-[48px] *:w-[48px]\"\n  } else if (size == \"md\") {\n    return \"size-[350px] @md/agent-session-block:size-[450px]  *:min-h-[32px] *:w-[32px]\"\n  } else if (size == \"sm\") {\n    return \"size-[300px] @md/agent-session-block:size-[450px] *:min-h-[16px] *:w-[16px]\"\n  }\n\n  return \"size-[300px] @md/agent-session-block:size-[450px] *:min-h-[4px] *:w-[4px]\"\n}\n\ninterface AudioVisualizerProps extends MotionProps {\n  type: \"bar\" | \"wave\" | \"grid\" | \"radial\"\n  config?:\n    | AgentAudioVisualizerBarProps\n    | AgentAudioVisualizerWaveProps\n    | AgentAudioVisualizerGridProps\n    | AgentAudioVisualizerRadialProps\n  className?: string\n}\n\nexport function AudioVisualizer({\n  type,\n  config,\n  className,\n  ...props\n}: AudioVisualizerProps) {\n  const { state, audioTrack } = useVoiceAssistant()\n\n  // `state`/`audioTrack` always reflect the live agent session; any same-named field on\n  // `config` is ignored by spreading it before these are set explicitly below.\n  switch (type) {\n    case \"wave\": {\n      return (\n        <motion.div className={className} {...props}>\n          <MotionAgentAudioVisualizerWave\n            {...config}\n            state={state}\n            audioTrack={audioTrack}\n            className=\"size-[300px] @md/agent-session-block:size-[450px]\"\n          />\n        </motion.div>\n      )\n    }\n    case \"grid\": {\n      const {\n        size,\n        radius,\n        rowCount = 15,\n        columnCount = 15,\n      } = config as AgentAudioVisualizerGridProps\n\n      return (\n        <MotionAgentAudioVisualizerGrid\n          {...config}\n          size={size ?? getGridSize(rowCount, columnCount)}\n          state={state}\n          audioTrack={audioTrack}\n          rowCount={rowCount}\n          columnCount={columnCount}\n          radius={radius ?? Math.round(Math.min(rowCount, columnCount) / 4)}\n          className={cn(\n            \"size-[350px] gap-0 p-20 *:place-self-center @md/agent-session-block:size-[450px]\",\n            className\n          )}\n          {...props}\n        />\n      )\n    }\n    case \"radial\": {\n      const { radius = 100, barCount = 25 } =\n        config as AgentAudioVisualizerRadialProps\n      return (\n        <motion.div className={className} {...props}>\n          <MotionAgentAudioVisualizerRadial\n            {...config}\n            size=\"xl\"\n            state={state}\n            radius={radius}\n            barCount={barCount}\n            audioTrack={audioTrack}\n            className=\"size-[450px]\"\n          />\n        </motion.div>\n      )\n    }\n    default: {\n      const { size, barCount = 5 } =\n        (config as AgentAudioVisualizerBarProps) ?? {}\n      const _size = size ?? getBarSize(barCount)\n      const sizedClassName = getBarClassName(_size)\n\n      return (\n        <MotionAgentAudioVisualizerBar\n          {...config}\n          size={_size}\n          state={state}\n          barCount={barCount}\n          audioTrack={audioTrack}\n          className={cn(sizedClassName, className)}\n          {...props}\n        >\n          <span className=\"min-h-2.5 w-2.5 rounded-full bg-current/10 transition-colors duration-250 ease-linear data-[lk-highlighted=true]:bg-current\" />\n        </MotionAgentAudioVisualizerBar>\n      )\n    }\n  }\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "livekit-agent-popup-01",
      "type": "registry:block",
      "title": "Livekit Agent Popup 01",
      "description": "Agent Popup",
      "dependencies": [
        "@livekit/components-react@2.9.24",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "livekit-client@2.22.3",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "radix-ui@1.6.7",
        "streamdown@2.4.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/livekit/blocks/agent-popup-01/components/agent-popup-block.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-popup-01/components/agent-popup-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { type AgentControlBarControls } from \"@/components/voice-agents/livekit/agent-control-bar\"\nimport { AgentSessionProvider } from \"@/components/voice-agents/livekit/agent-session-provider\"\nimport type { AudioVisualizerConfig } from \"@/components/voice-agents/livekit/blocks/agent-session-view-01/components/agent-session-block\"\nimport { useAgent, useSession } from \"@livekit/components-react\"\nimport {\n  type TokenSourceConfigurable,\n  type TokenSourceFixed,\n} from \"livekit-client\"\nimport {\n  useCallback,\n  useEffect,\n  useRef,\n  useState,\n  type ComponentProps,\n} from \"react\"\nimport { PopupView } from \"./popup-view\"\nimport { Trigger } from \"./trigger\"\n\nconst DEFAULT_CONTROLS: AgentControlBarControls = {\n  leave: false,\n  microphone: true,\n  chat: false,\n  camera: false,\n  screenShare: false,\n}\n\nexport interface AgentPopupError {\n  title: string\n  description: string\n}\n\nfunction TriggerProvider({ ...props }: ComponentProps<typeof Trigger>) {\n  const { isConnected } = useAgent()\n\n  return <Trigger {...props} isConnected={isConnected} />\n}\n\nexport interface AgentPopupProps {\n  /** Logo shown in the trigger bubble in place of the default agent icon. */\n  logo?: string\n  /** @default 'Agent' */\n  agentName?: string\n  /** Where to fetch a LiveKit session token from. See `useSession`'s `tokenSource` argument. */\n  tokenSource: TokenSourceConfigurable | TokenSourceFixed\n  /** Retained for API compatibility with LiveKit's complete popup block. */\n  themeMode?: \"dark\" | \"light\"\n  /**\n   * Message shown above the controls before the first chat message is sent.\n   *\n   * @default 'Agent is listening, ask it a question'\n   */\n  preConnectMessage?: string\n  /**\n   * An object with the following keys: leave, microphone, screenShare, camera, chat. Each key maps\n   * to a boolean value that determines whether the control is displayed.\n   *\n   * @default { leave: false, microphone: true, chat: false, camera: false, screenShare: false }\n   */\n  controls?: AgentControlBarControls\n  /** Brand color used for the trigger bubble's idle ring/disc and fallback icon contrast. */\n  triggerColor?: `#${string}`\n  /**\n   * Shows a pre-connect buffer state with a shimmer message before messages appear.\n   *\n   * @default true\n   */\n  isPreConnectBufferEnabled?: boolean\n  /**\n   * Configures the visualizer style rendered in the main tile area.\n   *\n   * @default { type: 'bar', size: 'lg' }\n   */\n  audioVisualizer?: AudioVisualizerConfig\n}\n\nexport function AgentPopup_01({\n  logo,\n  themeMode,\n  tokenSource,\n  triggerColor,\n  agentName = \"Agent\",\n  controls = DEFAULT_CONTROLS,\n  isPreConnectBufferEnabled,\n  preConnectMessage,\n  audioVisualizer = {\n    type: \"bar\",\n    size: \"lg\",\n  },\n}: AgentPopupProps) {\n  const session = useSession(tokenSource)\n  const [popupOpen, setPopupOpen] = useState(false)\n  const [error, setError] = useState<AgentPopupError>()\n\n  // Drive the session lifecycle off the popup-open state. Opening the popup\n  // connects; closing it (or unmounting) tears the room down so we don't\n  // leave a mic-hot connection while the bubble sits idle.\n  //\n  // useSession returns a fresh object on every connectionState change (the\n  // discriminated union swaps shape), so we can't depend on `session`\n  // directly - that would tear down + restart the room every time it\n  // transitioned through connecting -> connected. We pin the start/end\n  // calls via a ref instead, and only react to popupOpen.\n  const sessionRef = useRef(session)\n  sessionRef.current = session\n\n  useEffect(() => {\n    if (!popupOpen) return\n    let cancelled = false\n    sessionRef.current.start().catch((cause) => {\n      if (cancelled) return\n\n      console.error(\"agent-popup-01: session.start failed:\", cause)\n      setError({\n        title: \"Could not connect to the agent\",\n        description: cause instanceof Error ? cause.message : String(cause),\n      })\n    })\n    return () => {\n      cancelled = true\n      void sessionRef.current.end()\n    }\n  }, [popupOpen])\n\n  const handleToggle = useCallback(() => {\n    setPopupOpen((open) => {\n      const next = !open\n      if (!next) setError(undefined)\n      return next\n    })\n  }, [])\n\n  const finalControls = {\n    ...DEFAULT_CONTROLS,\n    ...controls,\n  }\n\n  return (\n    <AgentSessionProvider session={session}>\n      <TriggerProvider\n        logo={logo}\n        error={error}\n        color={triggerColor}\n        agentName={agentName}\n        isPressed={popupOpen}\n        onToggle={handleToggle}\n        className=\"fixed right-4 bottom-4 z-50\"\n      />\n      {popupOpen && (\n        <PopupView\n          logo={logo}\n          error={error}\n          agentName={agentName}\n          themeMode={themeMode}\n          isPreConnectBufferEnabled={isPreConnectBufferEnabled}\n          preConnectMessage={preConnectMessage}\n          audioVisualizer={audioVisualizer}\n          controls={finalControls}\n          onDisconnect={handleToggle}\n        />\n      )}\n    </AgentSessionProvider>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-control-bar.tsx",
          "target": "@components/voice-agents/livekit/agent-control-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/voice-agents/livekit/_ui/button\"\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { AgentDisconnectButton } from \"@/components/voice-agents/livekit/agent-disconnect-button\"\nimport { AgentTrackControl } from \"@/components/voice-agents/livekit/agent-track-control\"\nimport {\n  AgentTrackToggle,\n  agentTrackToggleVariants,\n} from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport {\n  useInputControls,\n  usePublishPermissions,\n  type UseInputControlsProps,\n} from \"@/components/voice-agents/livekit/hooks/use-agent-control-bar\"\nimport { cn } from \"@/lib/utils\"\nimport { useChat } from \"@livekit/components-react\"\nimport { Track } from \"livekit-client\"\nimport { Loader, MessageSquareTextIcon, SendHorizontal } from \"lucide-react\"\nimport { motion, type MotionProps } from \"motion/react\"\nimport { useEffect, useRef, useState, type ComponentProps } from \"react\"\n\nconst LK_TOGGLE_VARIANT_1 = [\n  \"data-[state=off]:bg-accent data-[state=off]:hover:bg-foreground/10\",\n  \"data-[state=off]:[&_~_button]:bg-accent data-[state=off]:[&_~_button]:hover:bg-foreground/10\",\n  \"data-[state=off]:border-border data-[state=off]:hover:border-foreground/12\",\n  \"data-[state=off]:[&_~_button]:border-border data-[state=off]:[&_~_button]:hover:border-foreground/12\",\n  \"data-[state=off]:text-destructive data-[state=off]:hover:text-destructive data-[state=off]:focus:text-destructive\",\n  \"data-[state=off]:focus-visible:ring-foreground/12 data-[state=off]:focus-visible:border-ring\",\n  \"dark:data-[state=off]:[&_~_button]:bg-accent dark:data-[state=off]:[&_~_button]:hover:bg-foreground/10\",\n]\n\nconst LK_TOGGLE_VARIANT_2 = [\n  \"data-[state=off]:bg-accent data-[state=off]:hover:bg-foreground/10\",\n  \"data-[state=off]:border-border data-[state=off]:hover:border-foreground/12\",\n  \"data-[state=off]:focus-visible:border-ring data-[state=off]:focus-visible:ring-foreground/12\",\n  \"data-[state=off]:text-foreground data-[state=off]:hover:text-foreground data-[state=off]:focus:text-foreground\",\n  \"data-[state=on]:bg-blue-500/20 data-[state=on]:hover:bg-blue-500/30\",\n  \"data-[state=on]:border-blue-700/10 data-[state=on]:text-blue-700 data-[state=on]:ring-blue-700/30\",\n  \"data-[state=on]:focus-visible:border-blue-700/50\",\n  \"dark:data-[state=on]:bg-blue-500/20 dark:data-[state=on]:text-blue-300\",\n]\n\nconst MOTION_PROPS: MotionProps = {\n  variants: {\n    hidden: {\n      height: 0,\n      opacity: 0,\n      marginBottom: 0,\n    },\n    visible: {\n      height: \"auto\",\n      opacity: 1,\n      marginBottom: 12,\n    },\n  },\n  initial: \"hidden\",\n  transition: {\n    duration: 0.3,\n    ease: \"easeOut\",\n  },\n}\n\ninterface AgentChatInputProps {\n  chatOpen: boolean\n  onSend?: (message: string) => void\n  className?: string\n}\n\nfunction AgentChatInput({\n  chatOpen,\n  onSend = async () => {},\n  className,\n}: AgentChatInputProps) {\n  const inputRef = useRef<HTMLTextAreaElement>(null)\n  const [isSending, setIsSending] = useState(false)\n  const [message, setMessage] = useState<string>(\"\")\n  const isDisabled = isSending || message.trim().length === 0\n\n  const handleSend = async () => {\n    if (isDisabled) {\n      return\n    }\n\n    try {\n      setIsSending(true)\n      await onSend(message.trim())\n      setMessage(\"\")\n    } catch (error) {\n      console.error(error)\n    } finally {\n      setIsSending(false)\n    }\n  }\n\n  const handleKeyDown = async (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === \"Enter\" && !e.shiftKey) {\n      e.preventDefault()\n      handleSend()\n    }\n  }\n\n  const handleButtonClick = async () => {\n    if (isDisabled) return\n    await handleSend()\n  }\n\n  useEffect(() => {\n    if (chatOpen) return\n    // when not disabled refocus on input\n    inputRef.current?.focus()\n  }, [chatOpen])\n\n  return (\n    <div\n      className={cn(\n        \"mb-3 flex grow items-end gap-2 rounded-md pl-1 text-sm\",\n        className\n      )}\n    >\n      <textarea\n        autoFocus\n        ref={inputRef}\n        value={message}\n        disabled={!chatOpen || isSending}\n        placeholder=\"Type something...\"\n        onKeyDown={handleKeyDown}\n        onChange={(e) => setMessage(e.target.value)}\n        className=\"field-sizing-content max-h-16 min-h-8 flex-1 resize-none py-2 [scrollbar-width:thin] focus:outline-none disabled:cursor-not-allowed disabled:opacity-50\"\n      />\n      <Button\n        size=\"icon\"\n        type=\"button\"\n        disabled={isDisabled}\n        variant={isDisabled ? \"secondary\" : \"default\"}\n        title={isSending ? \"Sending...\" : \"Send\"}\n        onClick={handleButtonClick}\n        className=\"self-end disabled:cursor-not-allowed\"\n      >\n        {isSending ? <Loader className=\"animate-spin\" /> : <SendHorizontal />}\n      </Button>\n    </div>\n  )\n}\n\n/** Configuration for which controls to display in the AgentControlBar. */\nexport interface AgentControlBarControls {\n  /**\n   * Whether to show the leave/disconnect button.\n   *\n   * @defaultValue true\n   */\n  leave?: boolean\n  /**\n   * Whether to show the camera toggle control.\n   *\n   * @defaultValue true (if camera publish permission is granted)\n   */\n  camera?: boolean\n  /**\n   * Whether to show the microphone toggle control.\n   *\n   * @defaultValue true (if microphone publish permission is granted)\n   */\n  microphone?: boolean\n  /**\n   * Whether to show the screen share toggle control.\n   *\n   * @defaultValue true (if screen share publish permission is granted)\n   */\n  screenShare?: boolean\n  /**\n   * Whether to show the chat toggle control.\n   *\n   * @defaultValue true (if data publish permission is granted)\n   */\n  chat?: boolean\n}\n\nexport interface AgentControlBarProps extends UseInputControlsProps {\n  /**\n   * The visual style of the control bar.\n   *\n   * @default 'default'\n   */\n  variant?: \"default\" | \"outline\" | \"livekit\"\n  /**\n   * This takes an object with the following keys: `leave`, `microphone`, `screenShare`, `camera`,\n   * `chat`. Each key maps to a boolean value that determines whether the control is displayed.\n   *\n   * @default\n   * {\n   *   leave: true,\n   *   microphone: true,\n   *   screenShare: true,\n   *   camera: true,\n   *   chat: true,\n   * }\n   */\n  controls?: AgentControlBarControls\n  /**\n   * Whether to save user choices.\n   *\n   * @default true\n   */\n  saveUserChoices?: boolean\n  /**\n   * Whether the agent is connected to a session.\n   *\n   * @default false\n   */\n  isConnected?: boolean\n  /**\n   * Whether the chat input interface is open.\n   *\n   * @default false\n   */\n  isChatOpen?: boolean\n  /** The callback for when the user disconnects. */\n  onDisconnect?: () => void\n  /** The callback for when the chat is opened or closed. */\n  onIsChatOpenChange?: (open: boolean) => void\n  /** The callback for when a device error occurs. */\n  onDeviceError?: (error: { source: Track.Source; error: Error }) => void\n}\n\n/**\n * A control bar specifically designed for voice assistant interfaces. Provides controls for\n * microphone, camera, screen share, chat, and disconnect. Includes an expandable chat input for\n * text-based interaction with the agent.\n *\n * @example\n *\n * ```tsx\n * <AgentControlBar\n *   variant=\"livekit\"\n *   isConnected={true}\n *   onDisconnect={() => handleDisconnect()}\n *   controls={{\n *     microphone: true,\n *     camera: true,\n *     screenShare: false,\n *     chat: true,\n *     leave: true,\n *   }}\n * />;\n * ```\n *\n * @extends ComponentProps<'div'>\n */\nexport function AgentControlBar({\n  variant = \"default\",\n  controls,\n  isChatOpen = false,\n  isConnected = false,\n  saveUserChoices = true,\n  onDisconnect,\n  onDeviceError,\n  onIsChatOpenChange,\n  className,\n  ...props\n}: AgentControlBarProps & ComponentProps<\"div\">) {\n  const { send } = useChat()\n  const publishPermissions = usePublishPermissions()\n  const [isChatOpenUncontrolled, setIsChatOpenUncontrolled] =\n    useState(isChatOpen)\n  const {\n    microphoneTrack,\n    cameraToggle,\n    microphoneToggle,\n    screenShareToggle,\n    handleAudioDeviceChange,\n    handleVideoDeviceChange,\n    handleMicrophoneDeviceSelectError,\n    handleCameraDeviceSelectError,\n  } = useInputControls({ onDeviceError, saveUserChoices })\n\n  const handleSendMessage = async (message: string) => {\n    await send(message)\n  }\n\n  const visibleControls = {\n    leave: controls?.leave ?? true,\n    microphone: controls?.microphone ?? publishPermissions.microphone,\n    screenShare: controls?.screenShare ?? publishPermissions.screenShare,\n    camera: controls?.camera ?? publishPermissions.camera,\n    chat: controls?.chat ?? publishPermissions.data,\n  }\n\n  const isEmpty = Object.values(visibleControls).every((value) => !value)\n\n  if (isEmpty) {\n    console.warn(\n      \"AgentControlBar: `visibleControls` contains only false values.\"\n    )\n    return null\n  }\n\n  return (\n    <div\n      aria-label=\"Voice assistant controls\"\n      className={cn(\n        \"bg-background border-input/50 dark:border-muted @container/agent-control-bar flex flex-col border p-3 drop-shadow-md/3\",\n        variant === \"livekit\" ? \"rounded-[31px]\" : \"rounded-lg\",\n        className\n      )}\n      {...props}\n    >\n      <motion.div\n        {...MOTION_PROPS}\n        inert={!(isChatOpen || isChatOpenUncontrolled)}\n        animate={isChatOpen || isChatOpenUncontrolled ? \"visible\" : \"hidden\"}\n        className=\"border-input/50 flex w-full items-start overflow-hidden border-b\"\n      >\n        <AgentChatInput\n          chatOpen={isChatOpen || isChatOpenUncontrolled}\n          onSend={handleSendMessage}\n          className={cn(variant === \"livekit\" && \"[&_button]:rounded-full\")}\n        />\n      </motion.div>\n\n      <div className=\"flex gap-1\">\n        <div className=\"flex grow gap-1\">\n          {/* Toggle Microphone */}\n          {visibleControls.microphone && (\n            <AgentTrackControl\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              kind=\"audioinput\"\n              aria-label=\"Toggle microphone\"\n              source={Track.Source.Microphone}\n              pressed={microphoneToggle.enabled}\n              disabled={microphoneToggle.pending}\n              audioTrack={microphoneTrack}\n              onPressedChange={microphoneToggle.toggle}\n              onActiveDeviceChange={handleAudioDeviceChange}\n              onMediaDeviceError={handleMicrophoneDeviceSelectError}\n              className={cn(\n                variant === \"livekit\" && [\n                  LK_TOGGLE_VARIANT_1,\n                  \"rounded-full [&_button:first-child]:rounded-l-full [&_button:last-child]:rounded-r-full\",\n                ]\n              )}\n            />\n          )}\n\n          {/* Toggle Camera */}\n          {visibleControls.camera && (\n            <AgentTrackControl\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              kind=\"videoinput\"\n              aria-label=\"Toggle camera\"\n              source={Track.Source.Camera}\n              pressed={cameraToggle.enabled}\n              pending={cameraToggle.pending}\n              disabled={cameraToggle.pending}\n              onPressedChange={cameraToggle.toggle}\n              onMediaDeviceError={handleCameraDeviceSelectError}\n              onActiveDeviceChange={handleVideoDeviceChange}\n              className={cn(\n                variant === \"livekit\" && [\n                  LK_TOGGLE_VARIANT_1,\n                  \"rounded-full [&_button:first-child]:rounded-l-full [&_button:last-child]:rounded-r-full\",\n                ]\n              )}\n            />\n          )}\n\n          {/* Toggle Screen Share */}\n          {visibleControls.screenShare && (\n            <AgentTrackToggle\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              aria-label=\"Toggle screen share\"\n              source={Track.Source.ScreenShare}\n              pressed={screenShareToggle.enabled}\n              disabled={screenShareToggle.pending}\n              onPressedChange={screenShareToggle.toggle}\n              className={cn(\n                variant === \"livekit\" && [LK_TOGGLE_VARIANT_2, \"rounded-full\"]\n              )}\n            />\n          )}\n\n          {/* Toggle Transcript */}\n          {visibleControls.chat && (\n            <Toggle\n              variant={variant === \"outline\" ? \"outline\" : \"default\"}\n              pressed={isChatOpen || isChatOpenUncontrolled}\n              aria-label=\"Toggle transcript\"\n              onPressedChange={(state) => {\n                if (!onIsChatOpenChange) setIsChatOpenUncontrolled(state)\n                else onIsChatOpenChange(state)\n              }}\n              className={agentTrackToggleVariants({\n                variant: variant === \"outline\" ? \"outline\" : \"default\",\n                className: cn(\n                  variant === \"livekit\" && [LK_TOGGLE_VARIANT_2, \"rounded-full\"]\n                ),\n              })}\n            >\n              <MessageSquareTextIcon />\n            </Toggle>\n          )}\n        </div>\n\n        {/* Disconnect */}\n        {visibleControls.leave && (\n          <AgentDisconnectButton\n            onClick={onDisconnect}\n            disabled={!isConnected}\n            className={cn(\n              variant === \"livekit\" &&\n                \"bg-destructive/10 dark:bg-destructive/10 text-destructive hover:bg-destructive/20 dark:hover:bg-destructive/20 focus:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/4 rounded-full font-mono text-xs font-bold tracking-wider\"\n            )}\n          >\n            <span className=\"sr-only uppercase @sm/agent-control-bar:not-sr-only\">\n              End{\" \"}\n              <span className=\"sr-only @md/agent-control-bar:not-sr-only\">\n                call\n              </span>\n            </span>\n          </AgentDisconnectButton>\n        )}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/button.tsx",
          "target": "@components/voice-agents/livekit/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/toggle.tsx",
          "target": "@components/voice-agents/livekit/_ui/toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-transparent\",\n        outline:\n          \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n      },\n      size: {\n        default: \"h-9 min-w-9 px-2\",\n        sm: \"h-8 min-w-8 px-1.5\",\n        lg: \"h-10 min-w-10 px-2.5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n  VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root\n      data-slot=\"toggle\"\n      className={cn(toggleVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-disconnect-button.tsx",
          "target": "@components/voice-agents/livekit/agent-disconnect-button.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Button,\n  type buttonVariants,\n} from \"@/components/voice-agents/livekit/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { useSessionContext } from \"@livekit/components-react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { PhoneOffIcon } from \"lucide-react\"\nimport { type ComponentProps } from \"react\"\n\n/**\n * Props for the AgentDisconnectButton component.\n */\nexport interface AgentDisconnectButtonProps\n  extends ComponentProps<\"button\">,\n    VariantProps<typeof buttonVariants> {\n  /**\n   * Custom icon to display. Defaults to PhoneOffIcon.\n   */\n  icon?: React.ReactNode\n  /**\n   * The size of the button.\n   * @default 'default'\n   */\n  size?: \"default\" | \"sm\" | \"lg\" | \"icon\"\n  /**\n   * The variant of the button.\n   * @default 'destructive'\n   */\n  variant?: \"default\" | \"outline\" | \"destructive\" | \"ghost\" | \"link\"\n  /**\n   * The children to render.\n   */\n  children?: React.ReactNode\n  /**\n   * The callback for when the button is clicked.\n   */\n  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\n/**\n * A button to disconnect from the current agent session.\n * Calls the session's end() method when clicked.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentDisconnectButton onClick={() => console.log('Disconnecting...')} />\n * ```\n */\nexport function AgentDisconnectButton({\n  icon,\n  size = \"default\",\n  variant = \"destructive\",\n  children,\n  onClick,\n  ...props\n}: AgentDisconnectButtonProps) {\n  const { end } = useSessionContext()\n  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n    onClick?.(event)\n    if (typeof end === \"function\") {\n      end()\n    }\n  }\n\n  return (\n    <Button size={size} variant={variant} onClick={handleClick} {...props}>\n      {icon ?? <PhoneOffIcon />}\n      {children ?? (\n        <span className={cn(size?.includes(\"icon\") && \"sr-only\")}>\n          End call\n        </span>\n      )}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-control.tsx",
          "target": "@components/voice-agents/livekit/agent-track-control.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/voice-agents/livekit/_ui/select\"\nimport { type toggleVariants } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { AgentAudioVisualizerBar } from \"@/components/voice-agents/livekit/agent-audio-visualizer-bar\"\nimport { AgentTrackToggle } from \"@/components/voice-agents/livekit/agent-track-toggle\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMaybeRoomContext,\n  useMediaDeviceSelect,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { useEffect, useMemo, useState } from \"react\"\n\nconst selectVariants = cva(\n  [\n    \"rounded-l-none shadow-none pl-2 \",\n    \"text-foreground hover:text-muted-foreground\",\n    \"peer-data-[state=on]/track:bg-muted peer-data-[state=on]/track:hover:bg-foreground/10\",\n    \"peer-data-[state=off]/track:text-destructive\",\n    \"peer-data-[state=off]/track:focus-visible:border-destructive peer-data-[state=off]/track:focus-visible:ring-destructive/30\",\n    \"[&_svg]:opacity-100\",\n  ],\n  {\n    variants: {\n      variant: {\n        default: [\n          \"border-none\",\n          \"peer-data-[state=off]/track:bg-destructive/10\",\n          \"peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"peer-data-[state=off]/track:[&_svg]:text-destructive!\",\n\n          \"dark:peer-data-[state=on]/track:bg-accent\",\n          \"dark:peer-data-[state=on]/track:hover:bg-foreground/10\",\n          \"dark:peer-data-[state=off]/track:bg-destructive/10\",\n          \"dark:peer-data-[state=off]/track:hover:bg-destructive/15\",\n        ],\n        outline: [\n          \"border border-l-0\",\n          \"peer-data-[state=off]/track:border-destructive/20\",\n          \"peer-data-[state=off]/track:bg-destructive/10\",\n          \"peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"peer-data-[state=off]/track:[&_svg]:text-destructive!\",\n          \"peer-data-[state=on]/track:hover:border-foreground/12\",\n\n          \"dark:peer-data-[state=off]/track:bg-destructive/10\",\n          \"dark:peer-data-[state=off]/track:hover:bg-destructive/15\",\n          \"dark:peer-data-[state=on]/track:bg-accent\",\n          \"dark:peer-data-[state=on]/track:hover:bg-foreground/10\",\n        ],\n      },\n      size: {\n        default: \"w-[180px]\",\n        sm: \"w-auto\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\n/**\n * Props for the TrackDeviceSelect component. */\ntype TrackDeviceSelectProps = React.ComponentProps<typeof SelectTrigger> &\n  VariantProps<typeof selectVariants> & {\n    /**\n     * The type of media device (audioinput or videoinput).\n     */\n    kind: MediaDeviceKind\n    /**\n     * Array of available devices\n     */\n    devices: MediaDeviceInfo[]\n    /**\n     * Active device ID\n     */\n    activeDeviceId?: string\n    /**\n     * The size of the select.\n     * @defaultValue 'default'\n     */\n    size?: \"default\" | \"sm\"\n    /**\n     * The variant of the select.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\" | null\n    /**\n     * Whether to request permissions for the media device.\n     */\n    requestPermissions?: boolean\n    /**\n     * Callback when the select is opened or closed.\n     */\n    onOpen: (open: boolean) => void\n    /**\n     * Callback when the active device changes.\n     */\n    onActiveDeviceChange?: (deviceId: string) => void\n  }\n\n/**\n * A select component for selecting a media device.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <TrackDeviceSelect\n *   size=\"sm\"\n *   variant=\"outline\"\n *   kind=\"audioinput\"\n *   devices={devices}\n *   activeDeviceId={activeDeviceId}\n *   onOpen={setOpen}\n *   onActiveDeviceChange={setActiveDeviceId}\n * />\n * ```\n */\nfunction TrackDeviceSelect({\n  kind,\n  devices,\n  activeDeviceId,\n  size = \"default\",\n  variant = \"default\",\n  className,\n  onOpen,\n  onActiveDeviceChange,\n  ...props\n}: TrackDeviceSelectProps) {\n  const [open, setOpen] = useState(false)\n\n  const handleOpenChange = (open: boolean) => {\n    setOpen(open)\n    onOpen(open)\n  }\n\n  if (devices.length < 2) {\n    return null\n  }\n\n  return (\n    <Select\n      open={open}\n      value={activeDeviceId}\n      onOpenChange={handleOpenChange}\n      onValueChange={onActiveDeviceChange}\n    >\n      <SelectTrigger\n        className={cn(selectVariants({ size, variant }), className)}\n        {...props}\n      >\n        {size !== \"sm\" && (\n          <SelectValue\n            className=\"font-mono text-sm\"\n            placeholder={`Select a ${kind}`}\n          />\n        )}\n      </SelectTrigger>\n      <SelectContent position=\"popper\">\n        {devices.map((device) => (\n          <SelectItem\n            key={device.deviceId}\n            value={device.deviceId}\n            className=\"font-mono text-xs\"\n          >\n            {device.label}\n          </SelectItem>\n        ))}\n      </SelectContent>\n    </Select>\n  )\n}\n\n/**\n * Props for the AgentTrackControl component.\n */\nexport type AgentTrackControlProps = VariantProps<typeof toggleVariants> & {\n  /**\n   * The type of media device (audioinput or videoinput).\n   */\n  kind: MediaDeviceKind\n  /**\n   * The track source to control (Microphone, Camera, or ScreenShare).\n   */\n  source: \"camera\" | \"microphone\" | \"screen_share\"\n  /**\n   * Whether the track is currently enabled/published.\n   */\n  pressed?: boolean\n  /**\n   * Whether the control is in a pending/loading state.\n   */\n  pending?: boolean\n  /**\n   * Whether the control is disabled.\n   */\n  disabled?: boolean\n  /**\n   * The audio track reference for visualization (only for microphone).\n   */\n  audioTrack?: TrackReferenceOrPlaceholder\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Callback when the pressed state changes.\n   */\n  onPressedChange?: (pressed: boolean) => void\n  /**\n   * Callback when a media device error occurs.\n   */\n  onMediaDeviceError?: (error: Error) => void\n  /**\n   * Callback when the active device changes.\n   */\n  onActiveDeviceChange?: (deviceId: string) => void\n}\n\n/**\n * A combined track toggle and device selector control.\n * Includes a toggle button and a dropdown to select the active device.\n * For microphone tracks, displays an audio visualizer.\n *\n * @example\n * ```tsx\n * <AgentTrackControl\n *   kind=\"audioinput\"\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   audioTrack={micTrackRef}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n *   onActiveDeviceChange={(deviceId) => setMicDevice(deviceId)}\n * />\n * ```\n */\nexport function AgentTrackControl({\n  kind,\n  variant = \"default\",\n  source,\n  pressed,\n  pending,\n  disabled,\n  className,\n  audioTrack,\n  onPressedChange,\n  onMediaDeviceError,\n  onActiveDeviceChange,\n}: AgentTrackControlProps) {\n  const room = useMaybeRoomContext()\n  const [requestPermissionsState, setRequestPermissionsState] = useState(false)\n  const { devices, activeDeviceId, setActiveMediaDevice } =\n    useMediaDeviceSelect({\n      room,\n      kind,\n      requestPermissions: requestPermissionsState,\n      onError: onMediaDeviceError,\n    })\n\n  useEffect(() => {\n    // A track was already acquired elsewhere (e.g. session.start()), so permission is already\n    // granted — safe to fetch labeled devices without a second getUserMedia prompt. Without\n    // this, the list stays label-less until a page reload, since the device observer only\n    // re-fetches when `requestPermissions` changes value. Screen share has no `kind` and no\n    // associated device list, so it should never trigger a mic/camera permission request.\n    if (pressed && kind) {\n      setRequestPermissionsState(true)\n    }\n  }, [pressed, kind])\n\n  const handleOpenChange = (open: boolean) => {\n    if (open) {\n      setRequestPermissionsState(true)\n    }\n  }\n\n  const handleActiveDeviceChange = (deviceId: string) => {\n    setActiveMediaDevice(deviceId)\n    onActiveDeviceChange?.(deviceId)\n  }\n\n  const filteredDevices = useMemo(\n    () => devices.filter((d) => d.deviceId !== \"\"),\n    [devices]\n  )\n  // Before permission is granted, the browser reports devices with blank ids, which get filtered\n  // out here — that's an *unknown* device count, not a confirmed empty one. Only treat it as\n  // \"no devices\" once a permission-gated check has actually run and still come up empty;\n  // otherwise the toggle disables itself before the user ever gets a chance to grant permission.\n  const noDevices =\n    Boolean(kind) && requestPermissionsState && filteredDevices.length === 0\n  const resolvedPressed = pressed && !noDevices\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center gap-0 rounded-md\",\n        variant === \"outline\" && \"shadow-xs [&_button]:shadow-none\",\n        className\n      )}\n    >\n      <AgentTrackToggle\n        source={source}\n        pending={pending}\n        variant={variant ?? \"default\"}\n        pressed={resolvedPressed}\n        disabled={noDevices || disabled}\n        onPressedChange={onPressedChange}\n        className=\"peer/track group/track focus:z-10 has-[.audiovisualizer]:w-auto has-[.audiovisualizer]:px-3 has-[~_button]:rounded-r-none has-[~_button]:border-r-0 has-[~_button]:pr-2 has-[~_button]:pl-3\"\n      >\n        {audioTrack && (\n          <AgentAudioVisualizerBar\n            size=\"icon\"\n            barCount={3}\n            state={resolvedPressed ? \"speaking\" : \"disconnected\"}\n            audioTrack={resolvedPressed ? audioTrack : undefined}\n            className=\"audiovisualizer flex h-6 w-auto items-center justify-center gap-0.5\"\n          >\n            <span\n              className={cn([\n                \"h-full min-h-0.5 w-0.5 origin-center\",\n                \"group-data-[state=on]/track:bg-foreground group-data-[state=off]/track:bg-destructive\",\n                \"data-lk-muted:bg-muted\",\n              ])}\n            />\n          </AgentAudioVisualizerBar>\n        )}\n      </AgentTrackToggle>\n      {kind && (\n        <TrackDeviceSelect\n          size=\"sm\"\n          kind={kind}\n          variant={variant}\n          devices={filteredDevices}\n          activeDeviceId={activeDeviceId}\n          onOpen={handleOpenChange}\n          onActiveDeviceChange={handleActiveDeviceChange}\n          className={cn([\n            \"relative\",\n            'before:bg-border before:absolute before:inset-y-0 before:left-0 before:my-2.5 before:w-px has-[~_button]:before:content-[\"\"]',\n            !resolvedPressed && \"before:bg-destructive/20\",\n          ])}\n        />\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/select.tsx",
          "target": "@components/voice-agents/livekit/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='text-'])]:text-muted-foreground flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"item-aligned\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span\n        data-slot=\"select-item-indicator\"\n        className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n      >\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerBarAnimator } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { type LocalAudioTrack, type RemoteAudioTrack } from \"livekit-client\"\nimport React, {\n  Children,\n  cloneElement,\n  isValidElement,\n  useMemo,\n  type ComponentProps,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nfunction cloneSingleChild(\n  children: ReactNode | ReactNode[],\n  props?: Record<string, unknown>,\n  key?: unknown\n) {\n  return Children.map(children, (child) => {\n    // Checking isValidElement is the safe way and avoids a typescript error too.\n    if (isValidElement(child) && Children.only(children)) {\n      const childProps = child.props as Record<string, unknown>\n      if (childProps.className) {\n        // make sure we retain classnames of both passed props and child\n        props ??= {}\n        props.className = cn(\n          childProps.className as string,\n          props.className as string\n        )\n        props.style = {\n          ...(childProps.style as CSSProperties),\n          ...(props.style as CSSProperties),\n        }\n      }\n      return cloneElement(child, {\n        ...props,\n        key: key ? String(key) : undefined,\n      })\n    }\n    return child\n  })\n}\n\nexport const AgentAudioVisualizerBarElementVariants = cva(\n  [\n    \"rounded-full transition-colors duration-250 ease-linear\",\n    \"bg-current/10 data-[lk-highlighted=true]:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: \"w-[4px] min-h-[4px]\",\n        sm: \"w-[8px] min-h-[8px]\",\n        md: \"w-[16px] min-h-[16px]\",\n        lg: \"w-[32px] min-h-[32px]\",\n        xl: \"w-[64px] min-h-[64px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\nexport const AgentAudioVisualizerBarVariants = cva(\n  \"relative flex items-center justify-center\",\n  {\n    variants: {\n      size: {\n        icon: \"h-[24px] gap-[2px]\",\n        sm: \"h-[56px] gap-[4px]\",\n        md: \"h-[112px] gap-[8px]\",\n        lg: \"h-[224px] gap-[16px]\",\n        xl: \"h-[448px] gap-[32px]\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentAudioVisualizerBar component.\n */\nexport interface AgentAudioVisualizerBarProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the bars in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The number of bars to display in the visualizer.\n   * If not provided, defaults based on size: 3 for 'icon'/'sm', 5 for others.\n   */\n  barCount?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match barCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Custom div element to render as grid cells. Each child receives data-lk-index,\n   * data-lk-highlighted props and style props for height. Must be a single div element.\n   */\n  children?: ReactNode\n}\n\n/**\n * A bar-style audio visualizer that responds to agent state and audio levels.\n * Displays animated bars that react to the current agent state (connecting, thinking, speaking, etc.)\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerBar\n *   size=\"md\"\n *   state=\"speaking\"\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerBar({\n  size = \"md\",\n  state = \"connecting\",\n  color,\n  barCount,\n  audioTrack,\n  volumeBands,\n  className,\n  children,\n  style,\n  ...props\n}: AgentAudioVisualizerBarProps &\n  VariantProps<typeof AgentAudioVisualizerBarVariants> &\n  ComponentProps<\"div\">) {\n  const _barCount = useMemo(() => {\n    if (barCount) {\n      return barCount\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 3\n      default:\n        return 5\n    }\n  }, [barCount, size])\n\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: _barCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, _barCount)\n    : multibandVolume\n\n  const sequencerInterval = useMemo(() => {\n    switch (state) {\n      case \"connecting\":\n        return 2000 / _barCount\n      case \"initializing\":\n        return 2000\n      case \"listening\":\n        return 500\n      case \"thinking\":\n        return 150\n      default:\n        return 1000\n    }\n  }, [state, _barCount])\n\n  const highlightedIndices = useAgentAudioVisualizerBarAnimator(\n    state,\n    _barCount,\n    sequencerInterval\n  )\n\n  const bands = useMemo(\n    () =>\n      state === \"speaking\" ? resolvedVolumeBands : new Array(_barCount).fill(0),\n    [state, resolvedVolumeBands, _barCount]\n  )\n\n  if (children && Array.isArray(children)) {\n    throw new Error(\n      \"AgentAudioVisualizerBar children must be a single element.\"\n    )\n  }\n\n  return (\n    <div\n      data-lk-state={state}\n      style={{ ...style, color } as CSSProperties}\n      className={cn(AgentAudioVisualizerBarVariants({ size }), className)}\n      {...props}\n    >\n      {bands.map((band: number, idx: number) =>\n        children ? (\n          <React.Fragment key={idx}>\n            {cloneSingleChild(children, {\n              \"data-lk-index\": idx,\n              \"data-lk-highlighted\": highlightedIndices.includes(idx),\n              style: { height: `${band * 100}%` },\n            })}\n          </React.Fragment>\n        ) : (\n          <div\n            key={idx}\n            data-lk-index={idx}\n            data-lk-highlighted={highlightedIndices.includes(idx)}\n            style={{ height: `${band * 100}%` }}\n            className={cn(AgentAudioVisualizerBarElementVariants({ size }))}\n          />\n        )\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-bar.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nfunction generateConnectingSequenceBar(columns: number): number[][] {\n  const seq = []\n\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, columns - 1 - x])\n  }\n\n  return seq\n}\n\nfunction generateListeningSequenceBar(columns: number): number[][] {\n  const center = Math.floor(columns / 2)\n  const noIndex = -1\n\n  return [[center], [noIndex]]\n}\n\nexport function useAgentAudioVisualizerBarAnimator(\n  state: AgentState | undefined,\n  columns: number,\n  interval: number\n): number[] {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<number[][]>([[]])\n\n  useEffect(() => {\n    if (state === \"thinking\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      const sequence = [...generateConnectingSequenceBar(columns)]\n      setSequence(sequence)\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequenceBar(columns))\n    } else if (state === undefined || state === \"speaking\") {\n      setSequence([new Array(columns).fill(0).map((_, idx) => idx)])\n    } else {\n      setSequence([[]])\n    }\n    setIndex(0)\n  }, [state, columns])\n\n  const animationFrameId = useRef<number | null>(null)\n  useEffect(() => {\n    if (prefersReducedMotion || sequence.length <= 1) return\n\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        setIndex((prev) => prev + 1)\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, columns, state, sequence.length, prefersReducedMotion])\n\n  return sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? []\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-track-toggle.tsx",
          "target": "@components/voice-agents/livekit/agent-track-toggle.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Toggle } from \"@/components/voice-agents/livekit/_ui/toggle\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Track } from \"livekit-client\"\nimport {\n  LoaderIcon,\n  MicIcon,\n  MicOffIcon,\n  MonitorOffIcon,\n  MonitorUpIcon,\n  VideoIcon,\n  VideoOffIcon,\n} from \"lucide-react\"\nimport { Fragment, useMemo, useState, type ComponentProps } from \"react\"\n\nexport const agentTrackToggleVariants = cva([\"size-9\"], {\n  variants: {\n    size: {\n      default: \"h-9 px-2 min-w-9\",\n      sm: \"h-8 px-1.5 min-w-8\",\n      lg: \"h-10 px-2.5 min-w-10\",\n    },\n    variant: {\n      default: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive\",\n        \"data-[state=off]:hover:bg-destructive/15\",\n        \"data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n        \"data-[state=on]:hover:bg-foreground/10\",\n      ],\n      outline: [\n        \"data-[state=off]:bg-destructive/10 data-[state=off]:text-destructive data-[state=off]:border-destructive/20\",\n        \"data-[state=off]:hover:bg-destructive/15 data-[state=off]:hover:text-destructive\",\n        \"data-[state=off]:focus:text-destructive\",\n        \"data-[state=off]:focus-visible:border-destructive data-[state=off]:focus-visible:ring-destructive/30\",\n        \"data-[state=on]:hover:bg-foreground/10 data-[state=on]:hover:border-foreground/12\",\n        \"dark:data-[state=on]:hover:bg-foreground/10\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"default\",\n  },\n})\n\nfunction getSourceIcon(\n  source: Track.Source,\n  enabled: boolean,\n  pending = false\n) {\n  if (pending) {\n    return LoaderIcon\n  }\n\n  switch (source) {\n    case Track.Source.Microphone:\n      return enabled ? MicIcon : MicOffIcon\n    case Track.Source.Camera:\n      return enabled ? VideoIcon : VideoOffIcon\n    case Track.Source.ScreenShare:\n      return enabled ? MonitorUpIcon : MonitorOffIcon\n    default:\n      return Fragment\n  }\n}\n\n/**\n * Props for the AgentTrackToggle component.\n */\nexport type AgentTrackToggleProps = VariantProps<\n  typeof agentTrackToggleVariants\n> &\n  ComponentProps<\"button\"> & {\n    /**\n     * The size of the toggle.\n     */\n    size?: \"sm\" | \"default\" | \"lg\"\n    /**\n     * The variant of the toggle.\n     * @defaultValue 'default'\n     */\n    variant?: \"default\" | \"outline\"\n    /**\n     * The track source to toggle (Microphone, Camera, or ScreenShare).\n     */\n    source: \"camera\" | \"microphone\" | \"screen_share\"\n    /**\n     * Whether the toggle is in a pending/loading state.\n     * When true, displays a loading spinner icon.\n     * @defaultValue false\n     */\n    pending?: boolean\n    /**\n     * Whether the toggle is currently pressed/enabled.\n     * @defaultValue false\n     */\n    pressed?: boolean\n    /**\n     * The default pressed state when uncontrolled.\n     * @defaultValue false\n     */\n    defaultPressed?: boolean\n    /**\n     * Callback fired when the pressed state changes.\n     */\n    onPressedChange?: (pressed: boolean) => void\n  }\n\n/**\n * A toggle button for controlling track publishing state.\n * Displays appropriate icons based on the track source and state.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <AgentTrackToggle\n *   source={Track.Source.Microphone}\n *   pressed={isMicEnabled}\n *   onPressedChange={(pressed) => setMicEnabled(pressed)}\n * />\n * ```\n */\nexport function AgentTrackToggle({\n  size = \"default\",\n  variant = \"default\",\n  source,\n  pending = false,\n  pressed,\n  defaultPressed = false,\n  className,\n  onPressedChange,\n  ...props\n}: AgentTrackToggleProps) {\n  const [uncontrolledPressed, setUncontrolledPressed] = useState(\n    defaultPressed ?? false\n  )\n  const isControlled = pressed !== undefined\n  const resolvedPressed = useMemo(\n    () => (isControlled ? pressed : uncontrolledPressed) ?? false,\n    [isControlled, pressed, uncontrolledPressed]\n  )\n  const IconComponent = getSourceIcon(\n    source as Track.Source,\n    resolvedPressed,\n    pending\n  )\n  const handlePressedChange = (nextPressed: boolean) => {\n    if (!isControlled) {\n      setUncontrolledPressed(nextPressed)\n    }\n    onPressedChange?.(nextPressed)\n  }\n\n  return (\n    <Toggle\n      size={size}\n      variant={variant}\n      pressed={isControlled ? pressed : undefined}\n      defaultPressed={isControlled ? undefined : defaultPressed}\n      aria-label={`Toggle ${source}`}\n      onPressedChange={handlePressedChange}\n      className={cn(\n        agentTrackToggleVariants({\n          size,\n          variant: variant ?? \"default\",\n          className,\n        })\n      )}\n      {...props}\n    >\n      <IconComponent className={cn(pending && \"animate-spin\")} />\n      {props.children}\n    </Toggle>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-control-bar.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-control-bar.ts",
          "type": "registry:component",
          "content": "import {\n  useLocalParticipantPermissions,\n  usePersistentUserChoices,\n  useSessionContext,\n  useTrackToggle,\n  type TrackReference,\n} from \"@livekit/components-react\"\nimport { Track } from \"livekit-client\"\nimport { useCallback } from \"react\"\n\nconst trackSourceToProtocol = (source: Track.Source) => {\n  // NOTE: this mapping avoids importing the protocol package as that leads to a significant bundle size increase\n  switch (source) {\n    case Track.Source.Camera:\n      return 1\n    case Track.Source.Microphone:\n      return 2\n    case Track.Source.ScreenShare:\n      return 3\n    default:\n      return 0\n  }\n}\n\nexport interface PublishPermissions {\n  camera: boolean\n  microphone: boolean\n  screenShare: boolean\n  data: boolean\n}\n\nexport function usePublishPermissions(): PublishPermissions {\n  const localPermissions = useLocalParticipantPermissions()\n\n  const canPublishSource = (source: Track.Source) => {\n    return (\n      !!localPermissions?.canPublish &&\n      (localPermissions.canPublishSources.length === 0 ||\n        localPermissions.canPublishSources.includes(\n          trackSourceToProtocol(source)\n        ))\n    )\n  }\n\n  return {\n    camera: canPublishSource(Track.Source.Camera),\n    microphone: canPublishSource(Track.Source.Microphone),\n    screenShare: canPublishSource(Track.Source.ScreenShare),\n    data: localPermissions?.canPublishData ?? false,\n  }\n}\n\nexport interface UseInputControlsProps {\n  saveUserChoices?: boolean\n  onDisconnect?: () => void\n  onDeviceError?: (error: { source: Track.Source; error: Error }) => void\n}\n\nexport interface UseInputControlsReturn {\n  microphoneTrack?: TrackReference\n  microphoneToggle: ReturnType<typeof useTrackToggle<Track.Source.Microphone>>\n  cameraToggle: ReturnType<typeof useTrackToggle<Track.Source.Camera>>\n  screenShareToggle: ReturnType<typeof useTrackToggle<Track.Source.ScreenShare>>\n  handleAudioDeviceChange: (deviceId: string) => void\n  handleVideoDeviceChange: (deviceId: string) => void\n  handleMicrophoneDeviceSelectError: (error: Error) => void\n  handleCameraDeviceSelectError: (error: Error) => void\n}\n\nexport function useInputControls({\n  saveUserChoices = true,\n  onDeviceError,\n}: UseInputControlsProps = {}): UseInputControlsReturn {\n  const {\n    local: { microphoneTrack },\n  } = useSessionContext()\n\n  const microphoneToggle = useTrackToggle({\n    source: Track.Source.Microphone,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.Microphone, error }),\n  })\n\n  const cameraToggle = useTrackToggle({\n    source: Track.Source.Camera,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.Camera, error }),\n  })\n\n  const screenShareToggle = useTrackToggle({\n    source: Track.Source.ScreenShare,\n    onDeviceError: (error) =>\n      onDeviceError?.({ source: Track.Source.ScreenShare, error }),\n  })\n\n  const {\n    saveAudioInputEnabled,\n    saveVideoInputEnabled,\n    saveAudioInputDeviceId,\n    saveVideoInputDeviceId,\n  } = usePersistentUserChoices({\n    preventLoad: !saveUserChoices,\n    preventSave: !saveUserChoices,\n  })\n\n  const handleAudioDeviceChange = useCallback(\n    (deviceId: string) => {\n      saveAudioInputDeviceId(deviceId ?? \"default\")\n    },\n    [saveAudioInputDeviceId]\n  )\n\n  const handleVideoDeviceChange = useCallback(\n    (deviceId: string) => {\n      saveVideoInputDeviceId(deviceId ?? \"default\")\n    },\n    [saveVideoInputDeviceId]\n  )\n\n  const handleToggleCamera = useCallback(\n    async (enabled?: boolean) => {\n      if (screenShareToggle.enabled) {\n        screenShareToggle.toggle(false)\n      }\n      await cameraToggle.toggle(enabled)\n      // persist video input enabled preference\n      saveVideoInputEnabled(!cameraToggle.enabled)\n    },\n    [cameraToggle, screenShareToggle, saveVideoInputEnabled]\n  )\n\n  const handleToggleMicrophone = useCallback(\n    async (enabled?: boolean) => {\n      await microphoneToggle.toggle(enabled)\n      // persist audio input enabled preference\n      saveAudioInputEnabled(!microphoneToggle.enabled)\n    },\n    [microphoneToggle, saveAudioInputEnabled]\n  )\n\n  const handleToggleScreenShare = useCallback(\n    async (enabled?: boolean) => {\n      if (cameraToggle.enabled) {\n        cameraToggle.toggle(false)\n      }\n      await screenShareToggle.toggle(enabled)\n    },\n    [cameraToggle, screenShareToggle]\n  )\n  const handleMicrophoneDeviceSelectError = useCallback(\n    (error: Error) =>\n      onDeviceError?.({ source: Track.Source.Microphone, error }),\n    [onDeviceError]\n  )\n\n  const handleCameraDeviceSelectError = useCallback(\n    (error: Error) => onDeviceError?.({ source: Track.Source.Camera, error }),\n    [onDeviceError]\n  )\n\n  return {\n    microphoneTrack,\n    cameraToggle: {\n      ...cameraToggle,\n      toggle: handleToggleCamera,\n    },\n    microphoneToggle: {\n      ...microphoneToggle,\n      toggle: handleToggleMicrophone,\n    },\n    screenShareToggle: {\n      ...screenShareToggle,\n      toggle: handleToggleScreenShare,\n    },\n    handleAudioDeviceChange,\n    handleVideoDeviceChange,\n    handleMicrophoneDeviceSelectError,\n    handleCameraDeviceSelectError,\n  }\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-session-provider.tsx",
          "target": "@components/voice-agents/livekit/agent-session-provider.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  RoomAudioRenderer,\n  SessionProvider,\n  type RoomAudioRendererProps,\n  type SessionProviderProps,\n  type UseSessionReturn,\n} from \"@livekit/components-react\"\nimport { type Room } from \"livekit-client\"\n\n/**\n * Props for the AgentSessionProvider component.\n * Combines SessionProviderProps with RoomAudioRendererProps.\n */\nexport type AgentSessionProviderProps = SessionProviderProps &\n  RoomAudioRendererProps & {\n    /**\n     * The room to provide.\n     */\n    room?: Room\n    /**\n     * The volume to set for the audio renderer.\n     */\n    volume?: number\n    /**\n     * Whether to mute the audio renderer.\n     */\n    muted?: boolean\n    /**\n     * The session to provide.\n     */\n    session: UseSessionReturn\n    /**\n     * The children to render.\n     */\n    children: React.ReactNode\n  }\n\n/**\n * A provider component for agent sessions that wraps SessionProvider\n * and includes RoomAudioRenderer for audio playback.\n *\n * @example\n * ```tsx\n * <AgentSessionProvider session={agentSession}>\n *   <AgentControlBar />\n *   <AgentChatTranscript />\n * </AgentSessionProvider>\n * ```\n */\nexport function AgentSessionProvider({\n  session,\n  children,\n  ...roomAudioRendererProps\n}: AgentSessionProviderProps) {\n  return (\n    <SessionProvider session={session}>\n      {children}\n      <RoomAudioRenderer {...roomAudioRendererProps} />\n    </SessionProvider>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/blocks/agent-session-view-01/components/agent-session-block.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-session-view-01/components/agent-session-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { type AgentAudioVisualizerBarProps } from \"@/components/voice-agents/livekit/agent-audio-visualizer-bar\"\nimport { type AgentAudioVisualizerGridProps } from \"@/components/voice-agents/livekit/agent-audio-visualizer-grid\"\nimport { type AgentAudioVisualizerRadialProps } from \"@/components/voice-agents/livekit/agent-audio-visualizer-radial\"\nimport { type AgentAudioVisualizerWaveProps } from \"@/components/voice-agents/livekit/agent-audio-visualizer-wave\"\nimport { AgentChatTranscript } from \"@/components/voice-agents/livekit/agent-chat-transcript\"\nimport {\n  AgentControlBar,\n  type AgentControlBarControls,\n} from \"@/components/voice-agents/livekit/agent-control-bar\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useAgent,\n  useSessionContext,\n  useSessionMessages,\n} from \"@livekit/components-react\"\nimport { AnimatePresence, motion, type MotionProps } from \"motion/react\"\nimport React, { useEffect, useRef, useState } from \"react\"\nimport { TileLayout } from \"./tile-view\"\n\n/**\n * Configures the visualizer style rendered in the main tile area. `type` selects the\n * visualizer, and the remaining fields are exactly the props of the matching\n * `AgentAudioVisualizer*` component (e.g. `type: 'grid'` accepts `rowCount`/`columnCount`,\n * `type: 'wave'` accepts `lineWidth`, etc).\n */\nexport type AudioVisualizerConfig =\n  | ({ type?: \"bar\" } & AgentAudioVisualizerBarProps)\n  | ({ type: \"wave\" } & AgentAudioVisualizerWaveProps)\n  | ({ type: \"grid\" } & AgentAudioVisualizerGridProps)\n  | ({ type: \"radial\" } & AgentAudioVisualizerRadialProps)\n\nconst DEFAULT_CONTROLS: AgentControlBarControls = {\n  leave: true,\n  microphone: true,\n  chat: false,\n  camera: false,\n  screenShare: false,\n}\n\nconst BOTTOM_VIEW_MOTION_PROPS: MotionProps = {\n  variants: {\n    visible: {\n      opacity: 1,\n      translateY: \"0%\",\n    },\n    hidden: {\n      opacity: 0,\n      translateY: \"100%\",\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n  transition: {\n    duration: 0.3,\n    delay: 0.5,\n    ease: \"easeOut\",\n  },\n}\n\nconst CHAT_MOTION_PROPS: MotionProps = {\n  variants: {\n    hidden: {\n      opacity: 0,\n      transition: {\n        ease: \"easeOut\",\n        duration: 0.3,\n      },\n    },\n    visible: {\n      opacity: 1,\n      transition: {\n        delay: 0.2,\n        ease: \"easeOut\",\n        duration: 0.3,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\nconst SHIMMER_MOTION_PROPS: MotionProps = {\n  variants: {\n    visible: {\n      opacity: 1,\n      transition: {\n        ease: \"easeIn\",\n        duration: 0.5,\n        delay: 0.8,\n      },\n    },\n    hidden: {\n      opacity: 0,\n      transition: {\n        ease: \"easeIn\",\n        duration: 0.5,\n        delay: 0,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\ninterface FadeProps {\n  top?: boolean\n  bottom?: boolean\n  className?: string\n}\n\nexport function Fade({ top = false, bottom = false, className }: FadeProps) {\n  return (\n    <div\n      className={cn(\n        \"from-background pointer-events-none h-4 bg-linear-to-b to-transparent\",\n        top && \"bg-linear-to-b\",\n        bottom && \"bg-linear-to-t\",\n        className\n      )}\n    />\n  )\n}\n\nexport interface AgentSessionView_01Props {\n  /**\n   * Retained for API compatibility with LiveKit's complete block.\n   * This distribution omits the separately licensed aura visualizer.\n   */\n  themeMode?: \"dark\" | \"light\"\n  /**\n   * Message shown above the controls before the first chat message is sent.\n   *\n   * @default 'Agent is listening, ask it a question'\n   */\n  preConnectMessage?: string\n  /**\n   * An object with the following keys: leave, microphone, screenShare, camera, chat.\n   * Each key maps to a boolean value that determines whether the control is displayed.\n   *\n   * @default {\n   *   leave: true,\n   *   microphone: true,\n   *   chat: false,\n   *   camera: false,\n   *   screenShare: false,\n   * }\n   */\n  controls?: AgentControlBarControls\n  /** Whether device choices are read from and saved to local storage. */\n  saveUserChoices?: boolean\n  /**\n   * Shows a pre-connect buffer state with a shimmer message before messages appear.\n   *\n   * @default true\n   */\n  isPreConnectBufferEnabled?: boolean\n  /**\n   * Configures the visualizer style rendered in the main tile area.\n   *\n   * @default { type: 'bar' }\n   */\n  audioVisualizer?: AudioVisualizerConfig\n  /** Optional class name merged onto the outer `<section>` container. */\n  className?: string\n  /** Called when the user clicks the leave control, in addition to ending the session. */\n  onDisconnect?: () => void\n}\n\nexport function AgentSessionView_01({\n  preConnectMessage = \"Agent is listening, ask it a question\",\n  controls = DEFAULT_CONTROLS,\n  saveUserChoices = true,\n  isPreConnectBufferEnabled = true,\n  audioVisualizer = { type: \"bar\" },\n  themeMode,\n  onDisconnect,\n  ref,\n  className,\n  ...props\n}: React.ComponentProps<\"section\"> & AgentSessionView_01Props) {\n  const session = useSessionContext()\n  const { messages } = useSessionMessages(session)\n  const [isChatOpen, setIsChatOpen] = useState(false)\n  const scrollAreaRef = useRef<HTMLDivElement>(null)\n  const { state: agentState } = useAgent()\n\n  useEffect(() => {\n    const lastMessage = messages.at(-1)\n    const lastMessageIsLocal = lastMessage?.from?.isLocal === true\n\n    if (scrollAreaRef.current && lastMessageIsLocal) {\n      scrollAreaRef.current.scrollTop = scrollAreaRef.current.scrollHeight\n    }\n  }, [messages])\n\n  const finalControls = {\n    ...DEFAULT_CONTROLS,\n    ...controls,\n  }\n\n  return (\n    <section\n      ref={ref}\n      data-theme-mode={themeMode}\n      className={cn(\n        \"bg-background @container/agent-session-block relative z-10 h-full w-full overflow-hidden\",\n        className\n      )}\n      {...props}\n    >\n      <Fade top className=\"absolute inset-x-4 top-0 z-10 h-40\" />\n      {/* transcript */}\n      <AnimatePresence>\n        {isChatOpen && (\n          <motion.div\n            {...CHAT_MOTION_PROPS}\n            className=\"absolute inset-x-0 top-0 bottom-[135px] overflow-hidden @md/agent-session-block:bottom-[170px]\"\n          >\n            <AgentChatTranscript\n              agentState={agentState}\n              messages={messages}\n              className=\"mx-auto max-w-2xl **:data-[slot=message-scroller-content]:p-4 **:data-[slot=message-scroller-content]:pt-40! @md/agent-session-block:**:data-[slot=message-scroller-content]:p-6\"\n            />\n          </motion.div>\n        )}\n      </AnimatePresence>\n\n      {/* Tile layout */}\n      <TileLayout isChatOpen={isChatOpen} audioVisualizer={audioVisualizer} />\n\n      {/* Bottom */}\n      <motion.div\n        {...BOTTOM_VIEW_MOTION_PROPS}\n        className=\"absolute inset-x-3 bottom-0 z-50 @md/agent-session-block:inset-x-12\"\n      >\n        {/* Pre-connect message */}\n        {isPreConnectBufferEnabled && (\n          <AnimatePresence>\n            {messages.length === 0 && (\n              <motion.p\n                key=\"pre-connect-message\"\n                aria-hidden={messages.length > 0}\n                {...SHIMMER_MOTION_PROPS}\n                className=\"shimmer shimmer-duration-2000 text-muted-foreground pointer-events-none mx-auto block w-full max-w-2xl pb-4 text-center text-sm\"\n              >\n                {preConnectMessage}\n              </motion.p>\n            )}\n          </AnimatePresence>\n        )}\n        <div className=\"bg-background relative mx-auto max-w-2xl pb-3 @md/agent-session-block:pb-12\">\n          <AgentControlBar\n            variant=\"livekit\"\n            controls={finalControls}\n            isChatOpen={isChatOpen}\n            isConnected={session.isConnected}\n            saveUserChoices={saveUserChoices}\n            onDisconnect={onDisconnect ?? session.end}\n            onIsChatOpenChange={setIsChatOpen}\n          />\n        </div>\n      </motion.div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-grid.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-grid.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  useAgentAudioVisualizerGridAnimator,\n  type Coordinate,\n} from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport type { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport React, {\n  Children,\n  cloneElement,\n  isValidElement,\n  memo,\n  useMemo,\n  type ComponentProps,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nfunction cloneSingleChild(\n  children: ReactNode | ReactNode[],\n  props?: Record<string, unknown>,\n  key?: unknown\n) {\n  return Children.map(children, (child) => {\n    // Checking isValidElement is the safe way and avoids a typescript error too.\n    if (isValidElement(child) && Children.only(children)) {\n      const childProps = child.props as Record<string, unknown>\n      if (childProps.className) {\n        // make sure we retain classnames of both passed props and child\n        props ??= {}\n        props.className = cn(\n          childProps.className as string,\n          props.className as string\n        )\n        props.style = {\n          ...(childProps.style as CSSProperties),\n          ...(props.style as CSSProperties),\n        }\n      }\n      return cloneElement(child, {\n        ...props,\n        key: key ? String(key) : undefined,\n      })\n    }\n    return child\n  })\n}\n\nexport const AgentAudioVisualizerGridCellVariants = cva(\n  [\n    \"w-1 h-1 rounded-full bg-current/10 place-self-center transition-all ease-out\",\n    \"data-[lk-highlighted=true]:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: [\"w-[2px] h-[2px]\"],\n        sm: [\"w-[4px] h-[4px]\"],\n        md: [\"w-[8px] h-[8px]\"],\n        lg: [\"w-[12px] h-[12px]\"],\n        xl: [\"w-[16px] h-[16px]\"],\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\nexport const AgentAudioVisualizerGridVariants = cva(\"grid\", {\n  variants: {\n    size: {\n      icon: [\"gap-[2px]\"],\n      sm: [\"gap-[4px]\"],\n      md: [\"gap-[8px]\"],\n      lg: [\"gap-[12px]\"],\n      xl: [\"gap-[16px]\"],\n    },\n  },\n  defaultVariants: {\n    size: \"md\",\n  },\n})\n\n/**\n * Configuration options for the grid visualizer.\n */\nexport interface GridOptions {\n  /**\n   * The radius for the animation spread effect.\n   */\n  radius?: number\n  /**\n   * The interval in milliseconds between animation frames.\n   * @defaultValue 100\n   */\n  interval?: number\n  /**\n   * The number of rows in the grid.\n   * @defaultValue 5\n   */\n  rowCount?: number\n  /**\n   * The number of columns in the grid.\n   * @defaultValue 5\n   */\n  columnCount?: number\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\nconst sizeDefaults = {\n  icon: 3,\n  sm: 5,\n  md: 5,\n  lg: 5,\n  xl: 5,\n}\n\nfunction useGrid(\n  size: VariantProps<typeof AgentAudioVisualizerGridVariants>[\"size\"] = \"md\",\n  columnCount = sizeDefaults[size as keyof typeof sizeDefaults],\n  rowCount = sizeDefaults[size as keyof typeof sizeDefaults]\n) {\n  return useMemo(() => {\n    const _columnCount = columnCount\n    const _rowCount = rowCount ?? columnCount\n    const items = new Array(_columnCount * _rowCount)\n      .fill(0)\n      .map((_, idx) => idx)\n\n    return { columnCount: _columnCount, rowCount: _rowCount, items }\n  }, [columnCount, rowCount])\n}\n\ninterface GridCellProps {\n  index: number\n  state: AgentState\n  interval: number\n  rowCount: number\n  columnCount: number\n  volumeBands: number[]\n  highlightedCoordinate: Coordinate\n  children?: ReactNode\n}\n\nconst GridCell = memo(function GridCell({\n  index,\n  state,\n  interval,\n  rowCount,\n  columnCount,\n  volumeBands,\n  highlightedCoordinate,\n  children,\n}: GridCellProps) {\n  if (state === \"speaking\") {\n    const y = Math.floor(index / columnCount)\n    const rowMidPoint = Math.floor(rowCount / 2)\n    const volumeChunks = 1 / (rowMidPoint + 1)\n    const distanceToMid = Math.abs(rowMidPoint - y)\n    const threshold = distanceToMid * volumeChunks\n    const isHighlighted = (volumeBands[index % columnCount] ?? 0) >= threshold\n\n    return cloneSingleChild(children, {\n      \"data-lk-index\": index,\n      \"data-lk-highlighted\": isHighlighted,\n    })\n  }\n\n  const isHighlighted =\n    highlightedCoordinate.x === index % columnCount &&\n    highlightedCoordinate.y === Math.floor(index / columnCount)\n\n  const transitionDurationInSeconds = interval / (isHighlighted ? 1000 : 100)\n\n  return cloneSingleChild(children, {\n    \"data-lk-index\": index,\n    \"data-lk-highlighted\": isHighlighted,\n    style: {\n      transitionDuration: `${transitionDurationInSeconds}s`,\n    },\n  })\n})\n\n/**\n * Props for the AgentAudioVisualizerGrid component.\n */\nexport type AgentAudioVisualizerGridProps = GridOptions & {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the grid cells in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match columnCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n  /**\n   * Custom element to render as grid cells. Each child receives data-lk-index\n   * and data-lk-highlighted props.\n   */\n  children?: ReactNode\n} & VariantProps<typeof AgentAudioVisualizerGridVariants>\n\n/**\n * A grid-style audio visualizer that responds to agent state and audio levels.\n * Displays an animated grid of cells that react to the current agent state\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerGrid\n *   size=\"md\"\n *   state=\"speaking\"\n *   rowCount={5}\n *   columnCount={5}\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerGrid({\n  size = \"md\",\n  state = \"connecting\",\n  radius,\n  color,\n  rowCount: _rowCount = 5,\n  columnCount: _columnCount = 5,\n  interval = 100,\n  className,\n  children,\n  audioTrack,\n  volumeBands,\n  style,\n  ...props\n}: AgentAudioVisualizerGridProps & ComponentProps<\"div\">) {\n  const { columnCount, rowCount, items } = useGrid(\n    size,\n    _columnCount,\n    _rowCount\n  )\n  const highlightedCoordinate = useAgentAudioVisualizerGridAnimator(\n    state,\n    rowCount,\n    columnCount,\n    interval,\n    radius\n  )\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: columnCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, columnCount)\n    : multibandVolume\n\n  if (children && Array.isArray(children)) {\n    throw new Error(\n      \"AgentAudioVisualizerGrid children must be a single element.\"\n    )\n  }\n\n  return (\n    <div\n      data-lk-state={state}\n      className={cn(AgentAudioVisualizerGridVariants({ size }), className)}\n      style={\n        {\n          ...style,\n          gridTemplateColumns: `repeat(${columnCount}, 1fr)`,\n          color,\n        } as CSSProperties\n      }\n      {...props}\n    >\n      {items.map((idx) => (\n        <GridCell\n          key={idx}\n          index={idx}\n          state={state}\n          interval={interval}\n          rowCount={rowCount}\n          columnCount={columnCount}\n          volumeBands={resolvedVolumeBands}\n          highlightedCoordinate={highlightedCoordinate}\n        >\n          {children ?? (\n            <div className={AgentAudioVisualizerGridCellVariants({ size })} />\n          )}\n        </GridCell>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-grid.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useState } from \"react\"\n\nexport interface Coordinate {\n  x: number\n  y: number\n}\n\nexport function generateConnectingSequence(\n  rows: number,\n  columns: number,\n  radius: number\n) {\n  const seq = []\n  const centerY = Math.floor(rows / 2)\n\n  // Calculate the boundaries of the ring based on the ring distance\n  const topLeft = {\n    x: Math.max(0, centerY - radius),\n    y: Math.max(0, centerY - radius),\n  }\n  const bottomRight = {\n    x: columns - 1 - topLeft.x,\n    y: Math.min(rows - 1, centerY + radius),\n  }\n\n  // Top edge\n  for (let x = topLeft.x; x <= bottomRight.x; x++) {\n    seq.push({ x, y: topLeft.y })\n  }\n\n  // Right edge\n  for (let y = topLeft.y + 1; y <= bottomRight.y; y++) {\n    seq.push({ x: bottomRight.x, y })\n  }\n\n  // Bottom edge\n  for (let x = bottomRight.x - 1; x >= topLeft.x; x--) {\n    seq.push({ x, y: bottomRight.y })\n  }\n\n  // Left edge\n  for (let y = bottomRight.y - 1; y > topLeft.y; y--) {\n    seq.push({ x: topLeft.x, y })\n  }\n\n  return seq\n}\n\nexport function generateListeningSequence(rows: number, columns: number) {\n  const center = { x: Math.floor(columns / 2), y: Math.floor(rows / 2) }\n  const noIndex = { x: -1, y: -1 }\n\n  return [\n    center,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n    noIndex,\n  ]\n}\n\nexport function generateThinkingSequence(rows: number, columns: number) {\n  const seq = []\n  const y = Math.floor(rows / 2)\n  for (let x = 0; x < columns; x++) {\n    seq.push({ x, y })\n  }\n  for (let x = columns - 1; x >= 0; x--) {\n    seq.push({ x, y })\n  }\n\n  return seq\n}\n\nexport function useAgentAudioVisualizerGridAnimator(\n  state: AgentState,\n  rows: number,\n  columns: number,\n  interval: number,\n  radius?: number\n): Coordinate {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<Coordinate[]>(() => [\n    {\n      x: Math.floor(columns / 2),\n      y: Math.floor(rows / 2),\n    },\n  ])\n\n  useEffect(() => {\n    const clampedRadius = radius\n      ? Math.min(radius, Math.floor(Math.max(rows, columns) / 2))\n      : Math.floor(Math.max(rows, columns) / 2)\n\n    if (state === \"thinking\") {\n      setSequence(generateThinkingSequence(rows, columns))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      const sequence = [\n        ...generateConnectingSequence(rows, columns, clampedRadius),\n      ]\n      setSequence(sequence)\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequence(rows, columns))\n    } else {\n      setSequence([{ x: Math.floor(columns / 2), y: Math.floor(rows / 2) }])\n    }\n    setIndex(0)\n  }, [state, rows, columns, radius])\n\n  useEffect(() => {\n    if (state === \"speaking\" || prefersReducedMotion) {\n      return\n    }\n\n    const indexInterval = setInterval(() => {\n      setIndex((prev) => {\n        return prev + 1\n      })\n    }, interval)\n\n    return () => clearInterval(indexInterval)\n  }, [interval, columns, rows, state, sequence.length, prefersReducedMotion])\n\n  return (\n    sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? {\n      x: Math.floor(columns / 2),\n      y: Math.floor(rows / 2),\n    }\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-radial.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-radial.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerRadialAnimator } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useMultibandTrackVolume,\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { type LocalAudioTrack, type RemoteAudioTrack } from \"livekit-client\"\nimport { useMemo, type ComponentProps, type CSSProperties } from \"react\"\n\n/**\n * Resizes an array of per-band volume values to exactly `count` entries.\n * Excess values are trimmed from the end; if there are too few, the last\n * value is duplicated to fill the remainder. An empty array is padded with 0s.\n */\nexport function normalizeVolumeBands(bands: number[], count: number): number[] {\n  if (bands.length === count) return bands\n  if (bands.length > count) return bands.slice(0, count)\n  const lastValue = bands[bands.length - 1] ?? 0\n  return [...bands, ...new Array(count - bands.length).fill(lastValue)]\n}\n\nexport const AgentAudioVisualizerRadialVariants = cva(\n  [\n    \"relative flex items-center justify-center\",\n    \"**:data-lk-index:bg-current/10\",\n    \"**:data-lk-index:absolute **:data-lk-index:top-1/2 **:data-lk-index:left-1/2 **:data-lk-index:origin-bottom **:data-lk-index:-translate-x-1/2\",\n    \"**:data-lk-index:rounded-full **:data-lk-index:transition-colors **:data-lk-index:duration-150 **:data-lk-index:ease-linear **:data-lk-index:data-[lk-highlighted=true]:bg-current\",\n    \"has-data-[lk-state=connecting]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=initializing]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=listening]:**:data-lk-index:duration-300\",\n    \"has-data-[lk-state=thinking]:animate-spin has-data-[lk-state=thinking]:[animation-duration:5s] motion-reduce:animate-none has-data-[lk-state=thinking]:**:data-lk-index:bg-current\",\n  ],\n  {\n    variants: {\n      size: {\n        icon: [\"h-[24px] gap-[2px]\"],\n        sm: [\"h-[56px] gap-[4px]\"],\n        md: [\"h-[112px] gap-[8px]\"],\n        lg: [\"h-[224px] gap-[16px]\"],\n        xl: [\"h-[448px] gap-[32px]\"],\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentAudioVisualizerRadial component.\n */\nexport interface AgentAudioVisualizerRadialProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'md'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The current state of the agent. Determines the animation pattern.\n   * @defaultValue 'connecting'\n   */\n  state?: AgentState\n  /**\n   * The color of the radial bars in hexidecimal format.\n   */\n  color?: `#${string}`\n  /**\n   * The radius (distance from center) for the radial bars.\n   * If not provided, defaults based on size.\n   */\n  radius?: number\n  /**\n   * The number of bars to display around the circle.\n   * Should be divisible by 4 for optimal visual results.\n   * If not provided, defaults to 12 for 'icon'/'sm', 24 for others.\n   */\n  barCount?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume values (0-1) to use instead of the values computed from the audioTrack.\n   * The volumeBands.length should match barCount.\n   */\n  volumeBands?: number[]\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\n/**\n * A radial (circular) audio visualizer that responds to agent state and audio levels.\n * Displays animated bars arranged in a circle that react to the current agent state\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example\n * ```tsx\n * <AgentAudioVisualizerRadial\n *   size=\"lg\"\n *   state=\"speaking\"\n *   barCount={24}\n *   audioTrack={agentAudioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerRadial({\n  size = \"md\",\n  state = \"connecting\",\n  color,\n  radius,\n  barCount,\n  audioTrack,\n  volumeBands,\n  className,\n  style,\n  ...props\n}: AgentAudioVisualizerRadialProps &\n  ComponentProps<\"div\"> &\n  VariantProps<typeof AgentAudioVisualizerRadialVariants>) {\n  const _barCount = useMemo(() => {\n    if (barCount) {\n      return barCount\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 12\n      default:\n        return 24\n    }\n  }, [barCount, size])\n\n  const multibandVolume = useMultibandTrackVolume(audioTrack, {\n    bands: _barCount,\n    loPass: 100,\n    hiPass: 200,\n  })\n  const resolvedVolumeBands = volumeBands\n    ? normalizeVolumeBands(volumeBands, _barCount)\n    : multibandVolume\n\n  const sequencerInterval = useMemo(() => {\n    switch (state) {\n      case \"connecting\":\n      case \"listening\":\n        return 500\n      case \"initializing\":\n        return 250\n      case \"thinking\":\n        return Infinity\n      default:\n        return 1000\n    }\n  }, [state])\n\n  const distanceFromCenter = useMemo(() => {\n    if (radius) {\n      return radius\n    }\n    switch (size) {\n      case \"icon\":\n        return 6\n      case \"xl\":\n        return 128\n      case \"lg\":\n        return 64\n      case \"sm\":\n        return 16\n      case \"md\":\n      default:\n        return 32\n    }\n  }, [size, radius])\n\n  if (_barCount % 4 !== 0) {\n    console.warn(\"barCount should be divisible by 4 for optimal visual results\")\n  }\n\n  const highlightedIndices = useAgentAudioVisualizerRadialAnimator(\n    state,\n    _barCount,\n    sequencerInterval\n  )\n\n  const dotSize = useMemo(() => {\n    return (distanceFromCenter * Math.PI) / _barCount\n  }, [distanceFromCenter, _barCount])\n\n  return (\n    <div\n      data-lk-state={state}\n      className={cn(\n        AgentAudioVisualizerRadialVariants({ size }),\n        \"relative\",\n        className\n      )}\n      style={{ ...style, color } as CSSProperties}\n      {...props}\n    >\n      {resolvedVolumeBands.map((band, idx) => {\n        const angle = (idx / _barCount) * Math.PI * 2\n\n        return (\n          <div\n            key={`${_barCount}-${idx}`}\n            data-lk-state={state}\n            className=\"absolute top-1/2 left-1/2 h-1 w-1 -translate-x-1/2 -translate-y-1/2\"\n            style={{\n              transformOrigin: \"center\",\n              transform: `rotate(${angle}rad) translateY(${distanceFromCenter}px)`,\n            }}\n          >\n            <div\n              data-lk-index={idx}\n              data-lk-highlighted={highlightedIndices.includes(idx)}\n              style={{\n                width: dotSize,\n                minHeight: dotSize,\n                height: state === \"speaking\" ? `${dotSize * 10 * band}px` : 0,\n              }}\n            />\n          </div>\n        )\n      })}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-radial.ts",
          "type": "registry:component",
          "content": "import { type AgentState } from \"@livekit/components-react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nfunction findGcdLessThan(columns: number, max: number = columns): number {\n  function gcd(a: number, b: number): number {\n    while (b !== 0) {\n      const t = b\n      b = a % b\n      a = t\n    }\n    return a\n  }\n  for (let i = max; i >= 1; i--) {\n    if (gcd(columns, i) === i) {\n      return i\n    }\n  }\n  return 1\n}\n\nfunction generateConnectingSequenceBar(columns: number): number[][] {\n  const seq = []\n  const center = Math.floor(columns / 2)\n\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, (x + center) % columns])\n  }\n\n  return seq\n}\n\nfunction generateListeningSequenceBar(columns: number): number[][] {\n  const divisor =\n    columns > 8\n      ? columns / findGcdLessThan(columns, 4)\n      : findGcdLessThan(columns, 2)\n\n  return Array.from({ length: divisor }, (_, idx) => [\n    ...Array(Math.floor(columns / divisor))\n      .fill(1)\n      .map((_, idx2) => idx2 * divisor + idx),\n  ])\n}\n\nexport const useAgentAudioVisualizerRadialAnimator = (\n  state: AgentState | undefined,\n  barCount: number,\n  interval: number\n): number[] => {\n  const prefersReducedMotion = useReducedMotion()\n  const [index, setIndex] = useState(0)\n  const [sequence, setSequence] = useState<number[][]>([[]])\n\n  useEffect(() => {\n    if (state === \"thinking\") {\n      setSequence(generateListeningSequenceBar(barCount))\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      setSequence(generateConnectingSequenceBar(barCount))\n    } else if (state === \"listening\") {\n      setSequence(generateListeningSequenceBar(barCount))\n    } else if (state === undefined || state === \"speaking\") {\n      setSequence([new Array(barCount).fill(0).map((_, idx) => idx)])\n    } else {\n      setSequence([[]])\n    }\n    setIndex(0)\n  }, [state, barCount])\n\n  const animationFrameId = useRef<number | null>(null)\n  useEffect(() => {\n    if (\n      prefersReducedMotion ||\n      sequence.length <= 1 ||\n      !Number.isFinite(interval)\n    )\n      return\n\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        setIndex((prev) => prev + 1)\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, barCount, state, sequence.length, prefersReducedMotion])\n\n  return sequence[prefersReducedMotion ? 0 : index % sequence.length] ?? []\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-audio-visualizer-wave.tsx",
          "target": "@components/voice-agents/livekit/agent-audio-visualizer-wave.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useAgentAudioVisualizerWave } from \"@/components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave\"\nimport { ReactShaderToy } from \"@/components/voice-agents/livekit/react-shader-toy\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  type AgentState,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport type { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport { useMemo, type ComponentProps } from \"react\"\n\nconst DEFAULT_COLOR = \"#1FD5F9\"\n\nfunction hexToRgb(hexColor: string) {\n  try {\n    const rgbColor = hexColor.match(\n      /^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n    )\n\n    if (rgbColor) {\n      const [, r, g, b] = rgbColor\n      const color = [r, g, b].map((c = \"00\") => parseInt(c, 16) / 255)\n\n      return color\n    }\n  } catch {\n    console.error(\n      `Invalid hex color '${hexColor}'.\\nFalling back to default color '${DEFAULT_COLOR}'.`\n    )\n  }\n\n  return hexToRgb(DEFAULT_COLOR)\n}\n\nconst shaderSource = `\nconst float TAU = 6.28318530718;\n\n// Noise for dithering\nvec2 randFibo(vec2 p) {\n  p = fract(p * vec2(443.897, 441.423));\n  p += dot(p, p.yx + 19.19);\n  return fract((p.xx + p.yx) * p.xy);\n}\n\n// Luma for alpha\nfloat luma(vec3 color) {\n  return dot(color, vec3(0.299, 0.587, 0.114));\n}\n\n// RGB to HSV\nvec3 rgb2hsv(vec3 c) {\n  vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n  vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n  vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n  float d = q.x - min(q.w, q.y);\n  float e = 1.0e-10;\n  return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n}\n\n// HSV to RGB\nvec3 hsv2rgb(vec3 c) {\n  vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n  vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n  return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n}\n\n// Bell curve function for attenuation from center with rounded top\nfloat bellCurve(float distanceFromCenter, float maxDistance) {\n  float normalizedDistance = distanceFromCenter / maxDistance;\n  // Use cosine with high power for smooth rounded top\n  return pow(cos(normalizedDistance * (3.14159265359 / 4.0)), 16.0);\n}\n\n// Calculate the sine wave\nfloat oscilloscopeWave(float x, float centerX, float time) {\n  float relativeX = x - centerX;\n  float maxDistance = centerX;\n  float distanceFromCenter = abs(relativeX);\n\n  // Apply bell curve for amplitude attenuation\n  float bell = bellCurve(distanceFromCenter, maxDistance);\n\n  // Calculate wave with uniforms and bell curve attenuation\n  float wave = sin(relativeX * uFrequency + time * uSpeed) * uAmplitude * bell;\n\n  return wave;\n}\n\nvoid mainImage(out vec4 fragColor, in vec2 fragCoord) {\n  vec2 uv = fragCoord / iResolution.xy;\n  vec2 pos = uv - 0.5;\n\n  // Calculate center and positions\n  float centerX = 0.5;\n  float centerY = 0.5;\n  float x = uv.x;\n  float y = uv.y;\n\n  // Convert line width from pixels to UV space\n  // Use the average of width and height to handle aspect ratio\n  float pixelSize = 2.0 / (iResolution.x + iResolution.y);\n  float lineWidthUV = uLineWidth * pixelSize;\n  float smoothingUV = uSmoothing * pixelSize;\n\n  // Find minimum distance to the wave by sampling nearby points\n  // This gives us consistent line width without high-frequency artifacts\n  const int NUM_SAMPLES = 50; // Must be const for GLSL loop\n  float minDist = 1000.0;\n  float sampleRange = 0.02; // Range to search for closest point\n\n  for(int i = 0; i < NUM_SAMPLES; i++) {\n    float offset = (float(i) / float(NUM_SAMPLES - 1) - 0.5) * sampleRange;\n    float sampleX = x + offset;\n    float waveY = centerY + oscilloscopeWave(sampleX, centerX, iTime);\n\n    // Calculate distance from current pixel to this point on the wave\n    vec2 wavePoint = vec2(sampleX, waveY);\n    vec2 currentPoint = vec2(x, y);\n    float dist = distance(currentPoint, wavePoint);\n\n    minDist = min(minDist, dist);\n  }\n\n  // Solid line with smooth edges using minimum distance\n  float line = smoothstep(lineWidthUV + smoothingUV, lineWidthUV - smoothingUV, minDist);\n\n  vec3 color = uColor;\n  if(abs(uColorShift) > 0.01) {\n    // Keep the center 50% at base color, then ramp shift across outer 25% on each side.\n    float centerBandHalfWidth = 0.2;\n    float edgeBandWidth = 0.5;\n    float distanceFromCenter = abs(x - centerX);\n    float edgeFactor = clamp((distanceFromCenter - centerBandHalfWidth) / edgeBandWidth, 0.0, 1.0);\n    vec3 hsv = rgb2hsv(color);\n    // Hue shift is zero in the center band and strongest at far edges.\n    hsv.x = fract(hsv.x + edgeFactor * uColorShift * 0.3);\n    color = hsv2rgb(hsv);\n  }\n\n  // Apply line intensity\n  color *= line;\n\n  // Add dithering for smoother gradients\n  // color += (randFibo(fragCoord).x - 0.5) / 255.0;\n\n  // Calculate alpha based on line intensity\n  float alpha = line * uMix;\n\n  fragColor = vec4(color * uMix, alpha);\n}`\n\ninterface WaveShaderProps {\n  /**\n   * Class name\n   * @default ''\n   */\n  className?: string\n  /**\n   * Speed of the oscilloscope\n   * @default 10\n   */\n  speed?: number\n  /**\n   * Amplitude of the oscilloscope\n   * @default 0.02\n   */\n  amplitude?: number\n  /**\n   * Frequency of the oscilloscope\n   * @default 20.0\n   */\n  frequency?: number\n  /**\n   * Color of the oscilloscope in hexidecimal format.\n   * @default '#1FD5F9'\n   */\n  color?: `#${string}`\n  /**\n   * Hue shift amount applied toward the outside of the wave. Center remains at the base color.\n   * @default 0.05\n   */\n  colorShift?: number\n  /**\n   * Mix of the oscilloscope\n   * @default 1.0\n   */\n  mix?: number\n  /**\n   * Line width of the oscilloscope in pixels\n   * @default 2.0\n   */\n  lineWidth?: number\n  /**\n   * Blur of the oscilloscope in pixels\n   * @default 0.5\n   */\n  blur?: number\n}\n\nfunction WaveShader({\n  speed = 10,\n  color = \"#1FD5F9\",\n  colorShift = 0.05,\n  mix = 1.0,\n  amplitude = 0.02,\n  frequency = 20.0,\n  lineWidth = 2.0,\n  blur = 0.5,\n  ref,\n  className,\n  ...props\n}: WaveShaderProps & ComponentProps<\"div\">) {\n  const rgbColor = useMemo(() => hexToRgb(color), [color])\n\n  return (\n    <div ref={ref} className={className} {...props}>\n      <ReactShaderToy\n        fs={shaderSource}\n        devicePixelRatio={globalThis.devicePixelRatio ?? 1}\n        uniforms={{\n          uSpeed: { type: \"1f\", value: speed },\n          uAmplitude: { type: \"1f\", value: amplitude },\n          uFrequency: { type: \"1f\", value: frequency },\n          uMix: { type: \"1f\", value: mix },\n          uLineWidth: { type: \"1f\", value: lineWidth },\n          uSmoothing: { type: \"1f\", value: blur },\n          uColor: { type: \"3fv\", value: rgbColor },\n          uColorShift: { type: \"1f\", value: colorShift },\n        }}\n        onError={(error) => {\n          console.error(\"Shader error:\", error)\n        }}\n        onWarning={(warning) => {\n          console.warn(\"Shader warning:\", warning)\n        }}\n        style={{ width: \"100%\", height: \"100%\" }}\n      />\n    </div>\n  )\n}\n\nWaveShader.displayName = \"WaveShader\"\n\nexport const AgentAudioVisualizerWaveVariants = cva([\"aspect-square\"], {\n  variants: {\n    size: {\n      icon: \"h-[24px]\",\n      sm: \"h-[56px]\",\n      md: \"h-[112px]\",\n      lg: \"h-[224px]\",\n      xl: \"h-[448px]\",\n    },\n  },\n  defaultVariants: {\n    size: \"lg\",\n  },\n})\n\nexport interface AgentAudioVisualizerWaveProps {\n  /**\n   * The size of the visualizer.\n   * @defaultValue 'lg'\n   */\n  size?: \"icon\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n  /**\n   * The agent state.\n   * @defaultValue 'speaking'\n   */\n  state?: AgentState\n  /**\n   * The color of the wave in hexidecimal format.\n   * @defaultValue '#1FD5F9'\n   */\n  color?: `#${string}`\n  /**\n   * The color shift of the wave. Higher values increase hue variation toward the edges.\n   * @defaultValue 0.05\n   */\n  colorShift?: number\n  /**\n   * The line width of the wave in pixels.\n   * @defaultValue 2.0\n   */\n  lineWidth?: number\n  /**\n   * The blur of the wave in pixels.\n   * @defaultValue 0.5\n   */\n  blur?: number\n  /**\n   * The audio track to visualize. Can be a local/remote audio track or a track reference.\n   */\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  /**\n   * Volume value (0-1) to use instead of the value computed from the audioTrack.\n   */\n  volume?: number\n  /**\n   * Additional CSS class names to apply to the container.\n   */\n  className?: string\n}\n\n/**\n * A wave-style audio visualizer that responds to agent state and audio levels.\n * Displays an animated wave that reacts to the current agent state (connecting, thinking, speaking, etc.)\n * and audio volume when speaking.\n *\n * @extends ComponentProps<'div'>\n *\n * @example ```tsx\n * <AgentAudioVisualizerWave\n *   size=\"lg\"\n *   state=\"speaking\"\n *   color=\"#1FD5F9\"\n *   colorShift={0.3}\n *   lineWidth={2}\n *   blur={0.5}\n *   audioTrack={audioTrack}\n * />\n * ```\n */\nexport function AgentAudioVisualizerWave({\n  size = \"lg\",\n  state = \"speaking\",\n  color,\n  colorShift = 0.05,\n  lineWidth,\n  blur,\n  audioTrack,\n  volume,\n  className,\n  ref,\n  ...props\n}: AgentAudioVisualizerWaveProps &\n  ComponentProps<\"div\"> &\n  VariantProps<typeof AgentAudioVisualizerWaveVariants>) {\n  const _lineWidth = useMemo(() => {\n    if (lineWidth !== undefined) {\n      return lineWidth\n    }\n    switch (size) {\n      case \"icon\":\n      case \"sm\":\n        return 2\n      default:\n        return 1\n    }\n  }, [lineWidth, size])\n\n  const { speed, amplitude, frequency, opacity } = useAgentAudioVisualizerWave({\n    state,\n    audioTrack,\n    volume,\n  })\n\n  return (\n    <WaveShader\n      ref={ref}\n      data-lk-state={state}\n      speed={speed}\n      color={color}\n      colorShift={colorShift}\n      mix={opacity}\n      amplitude={amplitude}\n      frequency={frequency}\n      lineWidth={_lineWidth}\n      blur={blur}\n      className={cn(\n        AgentAudioVisualizerWaveVariants({ size }),\n        \"mask-[linear-gradient(90deg,transparent_0%,black_20%,black_80%,transparent_100%)]\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave.ts",
          "target": "@components/voice-agents/livekit/hooks/use-agent-audio-visualizer-wave.ts",
          "type": "registry:component",
          "content": "import {\n  useTrackVolume,\n  type AgentState,\n  type TrackReference,\n  type TrackReferenceOrPlaceholder,\n} from \"@livekit/components-react\"\nimport { LocalAudioTrack, RemoteAudioTrack } from \"livekit-client\"\nimport {\n  animate,\n  useMotionValue,\n  useMotionValueEvent,\n  useReducedMotion,\n  type AnimationPlaybackControlsWithThen,\n  type ValueAnimationTransition,\n} from \"motion/react\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nconst DEFAULT_SPEED = 5\nconst DEFAULT_AMPLITUDE = 0.025\nconst DEFAULT_FREQUENCY = 10\nconst DEFAULT_TRANSITION: ValueAnimationTransition = {\n  duration: 0.2,\n  ease: \"easeOut\",\n}\n\nfunction useAnimatedValue<T>(initialValue: T) {\n  const [value, setValue] = useState(initialValue)\n  const motionValue = useMotionValue(initialValue)\n  const controlsRef = useRef<AnimationPlaybackControlsWithThen | null>(null)\n  useMotionValueEvent(motionValue, \"change\", (value) => setValue(value as T))\n\n  const animateFn = useCallback(\n    (targetValue: T | T[], transition: ValueAnimationTransition) => {\n      controlsRef.current = animate(motionValue, targetValue, transition)\n    },\n    [motionValue]\n  )\n\n  return { value, controls: controlsRef, animate: animateFn }\n}\n\ninterface UseAgentAudioVisualizerWaveAnimatorArgs {\n  state?: AgentState\n  audioTrack?: LocalAudioTrack | RemoteAudioTrack | TrackReferenceOrPlaceholder\n  volume?: number\n}\n\nexport function useAgentAudioVisualizerWave({\n  state,\n  audioTrack,\n  volume: volumeProp,\n}: UseAgentAudioVisualizerWaveAnimatorArgs) {\n  const prefersReducedMotion = useReducedMotion()\n  const [speed, setSpeed] = useState(DEFAULT_SPEED)\n  const { value: amplitude, animate: animateAmplitude } =\n    useAnimatedValue(DEFAULT_AMPLITUDE)\n  const { value: frequency, animate: animateFrequency } =\n    useAnimatedValue(DEFAULT_FREQUENCY)\n  const { value: opacity, animate: animateOpacity } = useAnimatedValue(1.0)\n\n  const trackVolume = useTrackVolume(audioTrack as TrackReference, {\n    fftSize: 512,\n    smoothingTimeConstant: 0.55,\n  })\n  const volume = volumeProp ?? trackVolume\n\n  useEffect(() => {\n    switch (state) {\n      case \"disconnected\":\n        setSpeed(DEFAULT_SPEED)\n        animateAmplitude(0, DEFAULT_TRANSITION)\n        animateFrequency(0, DEFAULT_TRANSITION)\n        animateOpacity(1.0, DEFAULT_TRANSITION)\n        return\n      case \"listening\":\n        setSpeed(DEFAULT_SPEED)\n        animateAmplitude(DEFAULT_AMPLITUDE, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY, DEFAULT_TRANSITION)\n        animateOpacity(\n          prefersReducedMotion ? 0.65 : [1.0, 0.3],\n          prefersReducedMotion\n            ? { duration: 0 }\n            : { duration: 0.75, repeat: Infinity, repeatType: \"mirror\" }\n        )\n        return\n      case \"thinking\":\n      case \"connecting\":\n      case \"initializing\":\n        setSpeed(DEFAULT_SPEED * 4)\n        animateAmplitude(DEFAULT_AMPLITUDE / 4, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY * 4, DEFAULT_TRANSITION)\n        animateOpacity(\n          prefersReducedMotion ? 0.65 : [1.0, 0.3],\n          prefersReducedMotion\n            ? { duration: 0 }\n            : { duration: 0.4, repeat: Infinity, repeatType: \"mirror\" }\n        )\n        return\n      case \"speaking\":\n      default:\n        setSpeed(DEFAULT_SPEED * 2)\n        animateAmplitude(DEFAULT_AMPLITUDE, DEFAULT_TRANSITION)\n        animateFrequency(DEFAULT_FREQUENCY, DEFAULT_TRANSITION)\n        animateOpacity(1.0, DEFAULT_TRANSITION)\n        return\n    }\n  }, [\n    state,\n    setSpeed,\n    animateAmplitude,\n    animateFrequency,\n    animateOpacity,\n    prefersReducedMotion,\n  ])\n\n  useEffect(() => {\n    if (state === \"speaking\") {\n      animateAmplitude(0.015 + 0.4 * volume, { duration: 0 })\n      animateFrequency(20 + 60 * volume, { duration: 0 })\n    }\n  }, [state, volume, animateAmplitude, animateFrequency])\n\n  return {\n    speed,\n    amplitude,\n    frequency,\n    opacity,\n  }\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/react-shader-toy.tsx",
          "target": "@components/voice-agents/livekit/react-shader-toy.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n/**\n * @license\n *\n * MIT License\n *\n * Copyright (c) 2018 Morgan Villedieu\n * Copyright (c) 2023 Rysana, Inc. (forked from the above)\n * Copyright (c) 2026 LiveKit, Inc. (forked from the above)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nimport React, { useEffect, useRef, type ComponentPropsWithoutRef } from \"react\"\n\nconst PRECISIONS = [\"lowp\", \"mediump\", \"highp\"]\nconst FS_MAIN_SHADER = `\\nvoid main(void){\n    vec4 color = vec4(0.0,0.0,0.0,1.0);\n    mainImage( color, gl_FragCoord.xy );\n    gl_FragColor = color;\n}`\nconst BASIC_FS = `void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n    vec2 uv = fragCoord/iResolution.xy;\n    vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));\n    fragColor = vec4(col,1.0);\n}`\nconst BASIC_VS = `attribute vec3 aVertexPosition;\nvoid main(void) {\n    gl_Position = vec4(aVertexPosition, 1.0);\n}`\nconst UNIFORM_TIME = \"iTime\"\nconst UNIFORM_TIMEDELTA = \"iTimeDelta\"\nconst UNIFORM_DATE = \"iDate\"\nconst UNIFORM_FRAME = \"iFrame\"\nconst UNIFORM_MOUSE = \"iMouse\"\nconst UNIFORM_RESOLUTION = \"iResolution\"\nconst UNIFORM_CHANNEL = \"iChannel\"\nconst UNIFORM_CHANNELRESOLUTION = \"iChannelResolution\"\nconst UNIFORM_DEVICEORIENTATION = \"iDeviceOrientation\"\n\ntype Vector4<T = number> = [T, T, T, T]\ntype UniformType = keyof Uniforms\n\nfunction isMatrixType(t: string, v: number[] | number): v is number[] {\n  return t.includes(\"Matrix\") && Array.isArray(v)\n}\nfunction isVectorListType(t: string, v: number[] | number): v is number[] {\n  return (\n    t.includes(\"v\") &&\n    Array.isArray(v) &&\n    v.length > Number.parseInt(t.charAt(0))\n  )\n}\nfunction isVectorType(t: string, v: number[] | number): v is Vector4 {\n  return (\n    !t.includes(\"v\") &&\n    Array.isArray(v) &&\n    v.length > Number.parseInt(t.charAt(0))\n  )\n}\nconst processUniform = <T extends UniformType>(\n  gl: WebGLRenderingContext,\n  location: WebGLUniformLocation,\n  t: T,\n  value: number | number[]\n) => {\n  if (isVectorType(t, value)) {\n    switch (t) {\n      case \"2f\":\n        return gl.uniform2f(location, value[0], value[1])\n      case \"3f\":\n        return gl.uniform3f(location, value[0], value[1], value[2])\n      case \"4f\":\n        return gl.uniform4f(location, value[0], value[1], value[2], value[3])\n      case \"2i\":\n        return gl.uniform2i(location, value[0], value[1])\n      case \"3i\":\n        return gl.uniform3i(location, value[0], value[1], value[2])\n      case \"4i\":\n        return gl.uniform4i(location, value[0], value[1], value[2], value[3])\n    }\n  }\n  if (typeof value === \"number\") {\n    switch (t) {\n      case \"1i\":\n        return gl.uniform1i(location, value)\n      default:\n        return gl.uniform1f(location, value)\n    }\n  }\n  switch (t) {\n    case \"1iv\":\n      return gl.uniform1iv(location, value)\n    case \"2iv\":\n      return gl.uniform2iv(location, value)\n    case \"3iv\":\n      return gl.uniform3iv(location, value)\n    case \"4iv\":\n      return gl.uniform4iv(location, value)\n    case \"1fv\":\n      return gl.uniform1fv(location, value)\n    case \"2fv\":\n      return gl.uniform2fv(location, value)\n    case \"3fv\":\n      return gl.uniform3fv(location, value)\n    case \"4fv\":\n      return gl.uniform4fv(location, value)\n    case \"Matrix2fv\":\n      return gl.uniformMatrix2fv(location, false, value)\n    case \"Matrix3fv\":\n      return gl.uniformMatrix3fv(location, false, value)\n    case \"Matrix4fv\":\n      return gl.uniformMatrix4fv(location, false, value)\n  }\n}\n\nconst uniformTypeToGLSLType = (t: string) => {\n  switch (t) {\n    case \"1f\":\n      return \"float\"\n    case \"2f\":\n      return \"vec2\"\n    case \"3f\":\n      return \"vec3\"\n    case \"4f\":\n      return \"vec4\"\n    case \"1i\":\n      return \"int\"\n    case \"2i\":\n      return \"ivec2\"\n    case \"3i\":\n      return \"ivec3\"\n    case \"4i\":\n      return \"ivec4\"\n    case \"1iv\":\n      return \"int\"\n    case \"2iv\":\n      return \"ivec2\"\n    case \"3iv\":\n      return \"ivec3\"\n    case \"4iv\":\n      return \"ivec4\"\n    case \"1fv\":\n      return \"float\"\n    case \"2fv\":\n      return \"vec2\"\n    case \"3fv\":\n      return \"vec3\"\n    case \"4fv\":\n      return \"vec4\"\n    case \"Matrix2fv\":\n      return \"mat2\"\n    case \"Matrix3fv\":\n      return \"mat3\"\n    case \"Matrix4fv\":\n      return \"mat4\"\n    default:\n      console.error(\n        log(\n          `The uniform type \"${t}\" is not valid, please make sure your uniform type is valid`\n        )\n      )\n  }\n}\n\nconst LinearFilter = 9729\nconst NearestFilter = 9728\nconst LinearMipMapLinearFilter = 9987\nconst ClampToEdgeWrapping = 33071\nconst RepeatWrapping = 10497\n\nclass Texture {\n  gl: WebGLRenderingContext\n  url?: string\n  wrapS?: number\n  wrapT?: number\n  minFilter?: number\n  magFilter?: number\n  source?: HTMLImageElement | HTMLVideoElement\n  pow2canvas?: HTMLCanvasElement\n  isLoaded = false\n  isVideo = false\n  flipY = -1\n  width = 0\n  height = 0\n  _webglTexture: WebGLTexture | null = null\n  constructor(gl: WebGLRenderingContext) {\n    this.gl = gl\n  }\n  updateTexture = (\n    texture: WebGLTexture,\n    video: HTMLVideoElement,\n    flipY: number\n  ) => {\n    const { gl } = this\n    const level = 0\n    const internalFormat = gl.RGBA\n    const srcFormat = gl.RGBA\n    const srcType = gl.UNSIGNED_BYTE\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      srcFormat,\n      srcType,\n      video\n    )\n  }\n  setupVideo = (url: string) => {\n    const video = document.createElement(\"video\")\n    let playing = false\n    let timeupdate = false\n    video.autoplay = true\n    video.muted = true\n    video.loop = true\n    video.crossOrigin = \"anonymous\"\n    const checkReady = () => {\n      if (playing && timeupdate) {\n        this.isLoaded = true\n      }\n    }\n    video.addEventListener(\n      \"playing\",\n      () => {\n        playing = true\n        this.width = video.videoWidth || 0\n        this.height = video.videoHeight || 0\n        checkReady()\n      },\n      true\n    )\n    video.addEventListener(\n      \"timeupdate\",\n      () => {\n        timeupdate = true\n        checkReady()\n      },\n      true\n    )\n    video.src = url\n    return video\n  }\n  makePowerOf2 = <T extends HTMLCanvasElement | HTMLImageElement | ImageBitmap>(\n    image: T\n  ): T => {\n    if (\n      image instanceof HTMLImageElement ||\n      image instanceof HTMLCanvasElement ||\n      image instanceof ImageBitmap\n    ) {\n      if (this.pow2canvas === undefined)\n        this.pow2canvas = document.createElement(\"canvas\")\n      this.pow2canvas.width = 2 ** Math.floor(Math.log(image.width) / Math.LN2)\n      this.pow2canvas.height =\n        2 ** Math.floor(Math.log(image.height) / Math.LN2)\n      const context = this.pow2canvas.getContext(\"2d\")\n      context?.drawImage(\n        image,\n        0,\n        0,\n        this.pow2canvas.width,\n        this.pow2canvas.height\n      )\n      console.warn(\n        log(\n          `Image is not power of two ${image.width} x ${image.height}. Resized to ${this.pow2canvas.width} x ${this.pow2canvas.height};`\n        )\n      )\n      return this.pow2canvas as T\n    }\n    return image\n  }\n  load = async (textureArgs: TextureParams) => {\n    const { gl } = this\n    const {\n      url,\n      wrapS,\n      wrapT,\n      minFilter,\n      magFilter,\n      flipY = -1,\n    }: TextureParams = textureArgs\n    if (!url) {\n      return Promise.reject(\n        new Error(\n          log(\n            \"Missing url, please make sure to pass the url of your texture { url: ... }\"\n          )\n        )\n      )\n    }\n    const isImage = /(\\.jpg|\\.jpeg|\\.png|\\.gif|\\.bmp)$/i.exec(url)\n    const isVideo = /(\\.mp4|\\.3gp|\\.webm|\\.ogv)$/i.exec(url)\n    if (isImage === null && isVideo === null) {\n      return Promise.reject(\n        new Error(\n          log(\n            `Please upload a video or an image with a valid format (url: ${url})`\n          )\n        )\n      )\n    }\n    Object.assign(this, { url, wrapS, wrapT, minFilter, magFilter, flipY })\n    const level = 0\n    const internalFormat = gl.RGBA\n    const width = 1\n    const height = 1\n    const border = 0\n    const srcFormat = gl.RGBA\n    const srcType = gl.UNSIGNED_BYTE\n    const pixel = new Uint8Array([255, 255, 255, 0])\n    const texture = gl.createTexture()\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      width,\n      height,\n      border,\n      srcFormat,\n      srcType,\n      pixel\n    )\n    if (isVideo) {\n      const video = this.setupVideo(url)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)\n      this._webglTexture = texture\n      this.source = video\n      this.isVideo = true\n      return video.play().then(() => this)\n    }\n    async function loadImage() {\n      return new Promise((resolve, reject) => {\n        const image = new Image()\n        image.crossOrigin = \"anonymous\"\n        image.onload = () => {\n          resolve(image)\n        }\n        image.onerror = () => {\n          reject(new Error(log(`failed loading url: ${url}`)))\n        }\n        image.src = url ?? \"\"\n      })\n    }\n    let image = (await loadImage()) as HTMLImageElement\n    let isPowerOf2 =\n      (image.width & (image.width - 1)) === 0 &&\n      (image.height & (image.height - 1)) === 0\n    if (\n      (textureArgs.wrapS !== ClampToEdgeWrapping ||\n        textureArgs.wrapT !== ClampToEdgeWrapping ||\n        (textureArgs.minFilter !== NearestFilter &&\n          textureArgs.minFilter !== LinearFilter)) &&\n      !isPowerOf2\n    ) {\n      image = this.makePowerOf2(image)\n      isPowerOf2 = true\n    }\n    gl.bindTexture(gl.TEXTURE_2D, texture)\n    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)\n    gl.texImage2D(\n      gl.TEXTURE_2D,\n      level,\n      internalFormat,\n      srcFormat,\n      srcType,\n      image\n    )\n    if (\n      isPowerOf2 &&\n      textureArgs.minFilter !== NearestFilter &&\n      textureArgs.minFilter !== LinearFilter\n    ) {\n      gl.generateMipmap(gl.TEXTURE_2D)\n    }\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_WRAP_S,\n      this.wrapS || RepeatWrapping\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_WRAP_T,\n      this.wrapT || RepeatWrapping\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_MIN_FILTER,\n      this.minFilter || LinearMipMapLinearFilter\n    )\n    gl.texParameteri(\n      gl.TEXTURE_2D,\n      gl.TEXTURE_MAG_FILTER,\n      this.magFilter || LinearFilter\n    )\n    this._webglTexture = texture\n    this.source = image\n    this.isVideo = false\n    this.isLoaded = true\n    this.width = image.width || 0\n    this.height = image.height || 0\n    return this\n  }\n}\n\nconst log = (text: string) => `react-shaders: ${text}`\n\nconst latestPointerClientCoords = (e: MouseEvent | TouchEvent) => {\n  if (\"changedTouches\" in e) {\n    const t = e.changedTouches[0]\n    return [t?.clientX ?? 0, t?.clientY ?? 0]\n  }\n  return [e.clientX, e.clientY]\n}\n\nconst lerpVal = (v0: number, v1: number, t: number) => v0 * (1 - t) + v1 * t\nconst insertStringAtIndex = (\n  currentString: string,\n  string: string,\n  index: number\n) =>\n  index > 0\n    ? currentString.substring(0, index) +\n      string +\n      currentString.substring(index, currentString.length)\n    : string + currentString\n\ntype Uniform = { type: string; value: number[] | number }\ntype Uniforms = Record<string, Uniform>\ntype TextureParams = {\n  url: string\n  wrapS?: number\n  wrapT?: number\n  minFilter?: number\n  magFilter?: number\n  flipY?: number\n}\n\nexport interface ReactShaderToyProps {\n  /** Fragment shader GLSL code. */\n  fs: string\n\n  /** Vertex shader GLSL code. */\n  vs?: string\n\n  /**\n   * Textures to be passed to the shader. Textures need to be squared or will be\n   * automatically resized.\n   *\n   * Options default to:\n   *\n   * ```js\n   * {\n   *   minFilter: LinearMipMapLinearFilter,\n   *   magFilter: LinearFilter,\n   *   wrapS: RepeatWrapping,\n   *   wrapT: RepeatWrapping,\n   * }\n   * ```\n   *\n   * See [textures in the docs](https://rysana.com/docs/react-shaders#textures)\n   * for details.\n   */\n  textures?: TextureParams[]\n\n  /**\n   * Custom uniforms to be passed to the shader.\n   *\n   * See [custom uniforms in the\n   * docs](https://rysana.com/docs/react-shaders#custom-uniforms) for details.\n   */\n  uniforms?: Uniforms\n\n  /**\n   * Color used when clearing the canvas.\n   *\n   * See [the WebGL\n   * docs](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/clearColor)\n   * for details.\n   */\n  clearColor?: Vector4\n\n  /**\n   * GLSL precision qualifier. Defaults to `'highp'`. Balance between\n   * performance and quality.\n   */\n  precision?: \"highp\" | \"lowp\" | \"mediump\"\n\n  /** Custom inline style for canvas. */\n  style?: React.CSSProperties\n\n  /** Customize WebGL context attributes. See [the WebGL docs](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getContextAttributes) for details. */\n  contextAttributes?: Record<string, unknown>\n\n  /** Lerp value for `iMouse` built-in uniform. Must be between 0 and 1. */\n  lerp?: number\n\n  /** Device pixel ratio. */\n  devicePixelRatio?: number\n\n  /**\n   * Callback for when the textures are done loading. Useful if you want to do\n   * something like e.g. hide the canvas until textures are done loading.\n   */\n  onDoneLoadingTextures?: () => void\n\n  /** Custom callback to handle errors. Defaults to `console.error`. */\n  onError?: (error: string) => void\n\n  /** Custom callback to handle warnings. Defaults to `console.warn`. */\n  onWarning?: (warning: string) => void\n\n  /**\n   * When true, the animation loop runs even when the canvas is not visible in the viewport.\n   * When false (default), animation runs only while visible (uses Intersection Observer),\n   * reducing CPU/GPU usage when the shader is off-screen.\n   */\n  animateWhenNotVisible?: boolean\n}\n\nexport function ReactShaderToy({\n  fs,\n  vs = BASIC_VS,\n  textures = [],\n  uniforms: propUniforms,\n  clearColor = [0, 0, 0, 1],\n  precision = \"highp\",\n  style,\n  contextAttributes = {},\n  lerp = 1,\n  devicePixelRatio = 1,\n  onDoneLoadingTextures,\n  onError = console.error,\n  onWarning = console.warn,\n  animateWhenNotVisible = false,\n  ...canvasProps\n}: ReactShaderToyProps & ComponentPropsWithoutRef<\"canvas\">) {\n  // Refs for WebGL state\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const glRef = useRef<WebGLRenderingContext | null>(null)\n  const squareVerticesBufferRef = useRef<WebGLBuffer | null>(null)\n  const shaderProgramRef = useRef<WebGLProgram | null>(null)\n  const vertexPositionAttributeRef = useRef<number | undefined>(undefined)\n  const animFrameIdRef = useRef<number | undefined>(undefined)\n  const initFrameIdRef = useRef<number | undefined>(undefined)\n  const isVisibleRef = useRef(true)\n  const prefersReducedMotionRef = useRef(false)\n  const animateWhenNotVisibleRef = useRef(animateWhenNotVisible)\n  const mousedownRef = useRef(false)\n  const canvasPositionRef = useRef<DOMRect | undefined>(undefined)\n  const timerRef = useRef(0)\n  const lastMouseArrRef = useRef<number[]>([0, 0])\n  const texturesArrRef = useRef<Texture[]>([])\n  const lastTimeRef = useRef(0)\n  const resizeObserverRef = useRef<ResizeObserver | undefined>(undefined)\n  const uniformsRef = useRef<\n    Record<\n      string,\n      {\n        type: string\n        isNeeded: boolean\n        value?: number[] | number\n        arraySize?: string\n      }\n    >\n  >({\n    [UNIFORM_TIME]: { type: \"float\", isNeeded: false, value: 0 },\n    [UNIFORM_TIMEDELTA]: { type: \"float\", isNeeded: false, value: 0 },\n    [UNIFORM_DATE]: { type: \"vec4\", isNeeded: false, value: [0, 0, 0, 0] },\n    [UNIFORM_MOUSE]: { type: \"vec4\", isNeeded: false, value: [0, 0, 0, 0] },\n    [UNIFORM_RESOLUTION]: { type: \"vec2\", isNeeded: false, value: [0, 0] },\n    [UNIFORM_FRAME]: { type: \"int\", isNeeded: false, value: 0 },\n    [UNIFORM_DEVICEORIENTATION]: {\n      type: \"vec4\",\n      isNeeded: false,\n      value: [0, 0, 0, 0],\n    },\n  })\n  const propsUniformsRef = useRef<Uniforms | undefined>(propUniforms)\n  const resolvedDevicePixelRatio = Math.min(Math.max(devicePixelRatio, 1), 2)\n\n  const setupChannelRes = (texture: TextureParams | Texture, id: number) => {\n    const width = \"width\" in texture ? (texture.width ?? 0) : 0\n    const height = \"height\" in texture ? (texture.height ?? 0) : 0\n    const channelResUniform = uniformsRef.current.iChannelResolution\n    if (!channelResUniform) return\n    const channelResValue = Array.isArray(channelResUniform.value)\n      ? channelResUniform.value\n      : (channelResUniform.value = [])\n    channelResValue[id * 3] = width * resolvedDevicePixelRatio\n    channelResValue[id * 3 + 1] = height * resolvedDevicePixelRatio\n    channelResValue[id * 3 + 2] = 0\n  }\n\n  const initWebGL = () => {\n    if (!canvasRef.current) return\n    glRef.current = (canvasRef.current.getContext(\"webgl\", contextAttributes) ||\n      canvasRef.current.getContext(\n        \"experimental-webgl\",\n        contextAttributes\n      )) as WebGLRenderingContext | null\n    glRef.current?.getExtension(\"OES_standard_derivatives\")\n    glRef.current?.getExtension(\"EXT_shader_texture_lod\")\n  }\n\n  const initBuffers = () => {\n    const gl = glRef.current\n    squareVerticesBufferRef.current = gl?.createBuffer() ?? null\n    gl?.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBufferRef.current)\n    const vertices = [\n      1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0,\n    ]\n    gl?.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)\n  }\n\n  const onDeviceOrientationChange = ({\n    alpha,\n    beta,\n    gamma,\n  }: DeviceOrientationEvent) => {\n    uniformsRef.current.iDeviceOrientation!.value = [\n      alpha ?? 0,\n      beta ?? 0,\n      gamma ?? 0,\n      window.orientation ?? 0,\n    ]\n  }\n\n  const mouseDown = (e: MouseEvent | TouchEvent) => {\n    const [clientX = 0, clientY = 0] = latestPointerClientCoords(e)\n    const mouseX =\n      clientX - (canvasPositionRef.current?.left ?? 0) - window.pageXOffset\n    const mouseY =\n      (canvasPositionRef.current?.height ?? 0) -\n      clientY -\n      (canvasPositionRef.current?.top ?? 0) -\n      window.pageYOffset\n    mousedownRef.current = true\n    const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n      ? uniformsRef.current.iMouse.value\n      : undefined\n    if (mouseValue) {\n      mouseValue[2] = mouseX\n      mouseValue[3] = mouseY\n    }\n    lastMouseArrRef.current[0] = mouseX\n    lastMouseArrRef.current[1] = mouseY\n  }\n\n  const mouseMove = (e: MouseEvent | TouchEvent) => {\n    canvasPositionRef.current = canvasRef.current?.getBoundingClientRect()\n    const [clientX = 0, clientY = 0] = latestPointerClientCoords(e)\n    const mouseX = clientX - (canvasPositionRef.current?.left ?? 0)\n    const mouseY =\n      (canvasPositionRef.current?.height ?? 0) -\n      clientY -\n      (canvasPositionRef.current?.top ?? 0)\n    if (lerp !== 1) {\n      lastMouseArrRef.current[0] = mouseX\n      lastMouseArrRef.current[1] = mouseY\n    } else {\n      const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n        ? uniformsRef.current.iMouse.value\n        : undefined\n      if (mouseValue) {\n        mouseValue[0] = mouseX\n        mouseValue[1] = mouseY\n      }\n    }\n  }\n\n  const mouseUp = () => {\n    const mouseValue = Array.isArray(uniformsRef.current.iMouse?.value)\n      ? uniformsRef.current.iMouse.value\n      : undefined\n    if (mouseValue) {\n      mouseValue[2] = 0\n      mouseValue[3] = 0\n    }\n  }\n\n  const onResize = () => {\n    const gl = glRef.current\n    if (!gl) return\n    canvasPositionRef.current = canvasRef.current?.getBoundingClientRect()\n    // Force pixel ratio to be one to avoid expensive calculus on retina display.\n    const realToCSSPixels = resolvedDevicePixelRatio\n    const displayWidth = Math.floor(\n      (canvasPositionRef.current?.width ?? 1) * realToCSSPixels\n    )\n    const displayHeight = Math.floor(\n      (canvasPositionRef.current?.height ?? 1) * realToCSSPixels\n    )\n    gl.canvas.width = displayWidth\n    gl.canvas.height = displayHeight\n    if (uniformsRef.current.iResolution?.isNeeded && shaderProgramRef.current) {\n      const rUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_RESOLUTION\n      )\n      gl.uniform2fv(rUniform, [gl.canvas.width, gl.canvas.height])\n    }\n  }\n\n  const createShader = (type: number, shaderCodeAsText: string) => {\n    const gl = glRef.current\n    if (!gl) return null\n    const shader = gl.createShader(type)\n    if (!shader) return null\n    gl.shaderSource(shader, shaderCodeAsText)\n    gl.compileShader(shader)\n    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n      onWarning?.(log(`Error compiling the shader:\\n${shaderCodeAsText}`))\n      const compilationLog = gl.getShaderInfoLog(shader)\n      gl.deleteShader(shader)\n      onError?.(log(`Shader compiler log: ${compilationLog}`))\n    }\n    return shader\n  }\n\n  const initShaders = (fragmentShader: string, vertexShader: string) => {\n    const gl = glRef.current\n    if (!gl) return\n    const fragmentShaderObj = createShader(gl.FRAGMENT_SHADER, fragmentShader)\n    const vertexShaderObj = createShader(gl.VERTEX_SHADER, vertexShader)\n    shaderProgramRef.current = gl.createProgram()\n    if (!shaderProgramRef.current || !vertexShaderObj || !fragmentShaderObj)\n      return\n    gl.attachShader(shaderProgramRef.current, vertexShaderObj)\n    gl.attachShader(shaderProgramRef.current, fragmentShaderObj)\n    gl.linkProgram(shaderProgramRef.current)\n    if (!gl.getProgramParameter(shaderProgramRef.current, gl.LINK_STATUS)) {\n      onError?.(\n        log(\n          `Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgramRef.current)}`\n        )\n      )\n      return\n    }\n    gl.useProgram(shaderProgramRef.current)\n    vertexPositionAttributeRef.current = gl.getAttribLocation(\n      shaderProgramRef.current,\n      \"aVertexPosition\"\n    )\n    gl.enableVertexAttribArray(vertexPositionAttributeRef.current)\n  }\n\n  const processCustomUniforms = () => {\n    if (propUniforms) {\n      for (const name of Object.keys(propUniforms)) {\n        const uniform = propUniforms[name]\n        if (!uniform) continue\n        const { value, type } = uniform\n        const glslType = uniformTypeToGLSLType(type)\n        if (!glslType) continue\n        const tempObject: { arraySize?: string } = {}\n        if (isMatrixType(type, value)) {\n          const arrayLength = type.length\n          const val = Number.parseInt(type.charAt(arrayLength - 3))\n          const numberOfMatrices = Math.floor(value.length / (val * val))\n          if (value.length > val * val)\n            tempObject.arraySize = `[${numberOfMatrices}]`\n        } else if (isVectorListType(type, value)) {\n          tempObject.arraySize = `[${Math.floor(value.length / Number.parseInt(type.charAt(0)))}]`\n        }\n        uniformsRef.current[name] = {\n          type: glslType,\n          isNeeded: false,\n          value,\n          ...tempObject,\n        }\n      }\n    }\n  }\n\n  const processTextures = () => {\n    const gl = glRef.current\n    if (!gl) return\n    if (textures && textures.length > 0) {\n      uniformsRef.current[`${UNIFORM_CHANNELRESOLUTION}`] = {\n        type: \"vec3\",\n        isNeeded: false,\n        arraySize: `[${textures.length}]`,\n        value: [],\n      }\n      const texturePromisesArr = textures.map(\n        (texture: TextureParams, id: number) => {\n          // Dynamically add textures uniforms.\n          uniformsRef.current[`${UNIFORM_CHANNEL}${id}`] = {\n            type: \"sampler2D\",\n            isNeeded: false,\n          }\n          setupChannelRes(texture, id)\n          texturesArrRef.current[id] = new Texture(gl)\n          return texturesArrRef.current[id]\n            ?.load(texture)\n            .then((t: Texture) => {\n              setupChannelRes(t, id)\n            })\n        }\n      )\n      Promise.all(texturePromisesArr)\n        .then(() => {\n          if (onDoneLoadingTextures) onDoneLoadingTextures()\n        })\n        .catch((e) => {\n          onError?.(e)\n          if (onDoneLoadingTextures) onDoneLoadingTextures()\n        })\n    } else if (onDoneLoadingTextures) onDoneLoadingTextures()\n  }\n\n  const preProcessFragment = (fragment: string) => {\n    const isValidPrecision = PRECISIONS.includes(precision ?? \"highp\")\n    const precisionString = `precision ${isValidPrecision ? precision : PRECISIONS[1]} float;\\n`\n    if (!isValidPrecision) {\n      onWarning?.(\n        log(\n          `wrong precision type ${precision}, please make sure to pass one of a valid precision lowp, mediump, highp, by default you shader precision will be set to highp.`\n        )\n      )\n    }\n    let fragmentShader = precisionString\n      .concat(`#define DPR ${resolvedDevicePixelRatio.toFixed(1)}\\n`)\n      .concat(fragment.replace(/texture\\(/g, \"texture2D(\"))\n    for (const uniform of Object.keys(uniformsRef.current)) {\n      if (fragment.includes(uniform)) {\n        const u = uniformsRef.current[uniform]\n        if (!u) continue\n        fragmentShader = insertStringAtIndex(\n          fragmentShader,\n          `uniform ${u.type} ${uniform}${u.arraySize || \"\"}; \\n`,\n          fragmentShader.lastIndexOf(precisionString) + precisionString.length\n        )\n        u.isNeeded = true\n      }\n    }\n    const isShadertoy = fragment.includes(\"mainImage\")\n    if (isShadertoy) fragmentShader = fragmentShader.concat(FS_MAIN_SHADER)\n    return fragmentShader\n  }\n\n  const setUniforms = (timestamp: number) => {\n    const gl = glRef.current\n    if (!gl || !shaderProgramRef.current) return\n    const delta = lastTimeRef.current\n      ? (timestamp - lastTimeRef.current) / 1000\n      : 0\n    lastTimeRef.current = timestamp\n    const propUniforms = propsUniformsRef.current\n    if (propUniforms) {\n      for (const name of Object.keys(propUniforms)) {\n        const currentUniform = propUniforms[name]\n        if (!currentUniform) continue\n        if (uniformsRef.current[name]?.isNeeded) {\n          if (!shaderProgramRef.current) return\n          const customUniformLocation = gl.getUniformLocation(\n            shaderProgramRef.current,\n            name\n          )\n          if (!customUniformLocation) return\n          processUniform(\n            gl,\n            customUniformLocation,\n            currentUniform.type as UniformType,\n            currentUniform.value\n          )\n        }\n      }\n    }\n    if (uniformsRef.current.iMouse?.isNeeded) {\n      const mouseUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_MOUSE\n      )\n      gl.uniform4fv(mouseUniform, uniformsRef.current.iMouse.value as number[])\n    }\n    if (uniformsRef.current.iChannelResolution?.isNeeded) {\n      const channelResUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_CHANNELRESOLUTION\n      )\n      gl.uniform3fv(\n        channelResUniform,\n        uniformsRef.current.iChannelResolution.value as number[]\n      )\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      const deviceOrientationUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_DEVICEORIENTATION\n      )\n      gl.uniform4fv(\n        deviceOrientationUniform,\n        uniformsRef.current.iDeviceOrientation.value as number[]\n      )\n    }\n    if (uniformsRef.current.iTime?.isNeeded) {\n      const timeUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_TIME\n      )\n      gl.uniform1f(timeUniform, (timerRef.current += delta))\n    }\n    if (uniformsRef.current.iTimeDelta?.isNeeded) {\n      const timeDeltaUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_TIMEDELTA\n      )\n      gl.uniform1f(timeDeltaUniform, delta)\n    }\n    if (uniformsRef.current.iDate?.isNeeded) {\n      const d = new Date()\n      const month = d.getMonth() + 1\n      const day = d.getDate()\n      const year = d.getFullYear()\n      const time =\n        d.getHours() * 60 * 60 +\n        d.getMinutes() * 60 +\n        d.getSeconds() +\n        d.getMilliseconds() * 0.001\n      const dateUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_DATE\n      )\n      gl.uniform4fv(dateUniform, [year, month, day, time])\n    }\n    if (uniformsRef.current.iFrame?.isNeeded) {\n      const timeDeltaUniform = gl.getUniformLocation(\n        shaderProgramRef.current,\n        UNIFORM_FRAME\n      )\n      const frame = uniformsRef.current.iFrame.value as number\n      gl.uniform1i(timeDeltaUniform, frame)\n      uniformsRef.current.iFrame.value = frame + 1\n    }\n    if (texturesArrRef.current.length > 0) {\n      for (let index = 0; index < texturesArrRef.current.length; index++) {\n        const texture = texturesArrRef.current[index]\n        if (!texture) return\n        const { isVideo, _webglTexture, source, flipY, isLoaded } = texture\n        if (!isLoaded || !_webglTexture || !source) return\n        if (uniformsRef.current[`iChannel${index}`]?.isNeeded) {\n          if (!shaderProgramRef.current) return\n          const iChannel = gl.getUniformLocation(\n            shaderProgramRef.current,\n            `iChannel${index}`\n          )\n          gl.activeTexture(gl.TEXTURE0 + index)\n          gl.bindTexture(gl.TEXTURE_2D, _webglTexture)\n          gl.uniform1i(iChannel, index)\n          if (isVideo) {\n            texture.updateTexture(\n              _webglTexture,\n              source as HTMLVideoElement,\n              flipY\n            )\n          }\n        }\n      }\n    }\n  }\n\n  const drawScene = (timestamp: number) => {\n    const gl = glRef.current\n    if (!gl) return\n    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight)\n    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)\n    gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBufferRef.current)\n    gl.vertexAttribPointer(\n      vertexPositionAttributeRef.current ?? 0,\n      3,\n      gl.FLOAT,\n      false,\n      0,\n      0\n    )\n    setUniforms(timestamp)\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\n    const mouseValue = uniformsRef.current.iMouse?.value\n    if (\n      uniformsRef.current.iMouse?.isNeeded &&\n      lerp !== 1 &&\n      Array.isArray(mouseValue)\n    ) {\n      const currentX = mouseValue[0] ?? 0\n      const currentY = mouseValue[1] ?? 0\n      mouseValue[0] = lerpVal(currentX, lastMouseArrRef.current[0] ?? 0, lerp)\n      mouseValue[1] = lerpVal(currentY, lastMouseArrRef.current[1] ?? 0, lerp)\n    }\n    if (\n      !prefersReducedMotionRef.current &&\n      (animateWhenNotVisibleRef.current || isVisibleRef.current)\n    ) {\n      animFrameIdRef.current = requestAnimationFrame(drawScene)\n    }\n  }\n\n  const addEventListeners = () => {\n    const options = { passive: true }\n    if (uniformsRef.current.iMouse?.isNeeded && canvasRef.current) {\n      canvasRef.current.addEventListener(\"mousemove\", mouseMove, options)\n      canvasRef.current.addEventListener(\"mouseout\", mouseUp, options)\n      canvasRef.current.addEventListener(\"mouseup\", mouseUp, options)\n      canvasRef.current.addEventListener(\"mousedown\", mouseDown, options)\n      canvasRef.current.addEventListener(\"touchmove\", mouseMove, options)\n      canvasRef.current.addEventListener(\"touchend\", mouseUp, options)\n      canvasRef.current.addEventListener(\"touchstart\", mouseDown, options)\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      window.addEventListener(\n        \"deviceorientation\",\n        onDeviceOrientationChange,\n        options\n      )\n    }\n    if (canvasRef.current) {\n      resizeObserverRef.current = new ResizeObserver(onResize)\n      resizeObserverRef.current.observe(canvasRef.current)\n      window.addEventListener(\"resize\", onResize, options)\n    }\n  }\n\n  const removeEventListeners = () => {\n    const options = { passive: true } as EventListenerOptions\n    if (uniformsRef.current.iMouse?.isNeeded && canvasRef.current) {\n      canvasRef.current.removeEventListener(\"mousemove\", mouseMove, options)\n      canvasRef.current.removeEventListener(\"mouseout\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"mouseup\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"mousedown\", mouseDown, options)\n      canvasRef.current.removeEventListener(\"touchmove\", mouseMove, options)\n      canvasRef.current.removeEventListener(\"touchend\", mouseUp, options)\n      canvasRef.current.removeEventListener(\"touchstart\", mouseDown, options)\n    }\n    if (uniformsRef.current.iDeviceOrientation?.isNeeded) {\n      window.removeEventListener(\n        \"deviceorientation\",\n        onDeviceOrientationChange,\n        options\n      )\n    }\n    if (resizeObserverRef.current) {\n      resizeObserverRef.current.disconnect()\n      window.removeEventListener(\"resize\", onResize, options)\n    }\n  }\n\n  useEffect(() => {\n    propsUniformsRef.current = propUniforms\n  }, [propUniforms])\n\n  useEffect(() => {\n    animateWhenNotVisibleRef.current = animateWhenNotVisible\n    if (animateWhenNotVisible) {\n      isVisibleRef.current = true\n    }\n  }, [animateWhenNotVisible])\n\n  useEffect(() => {\n    const media = window.matchMedia(\"(prefers-reduced-motion: reduce)\")\n    const update = () => {\n      prefersReducedMotionRef.current = media.matches\n      if (media.matches) {\n        cancelAnimationFrame(animFrameIdRef.current ?? 0)\n        requestAnimationFrame(drawScene)\n      } else if (animateWhenNotVisibleRef.current || isVisibleRef.current) {\n        requestAnimationFrame(drawScene)\n      }\n    }\n    update()\n    media.addEventListener(\"change\", update)\n    return () => media.removeEventListener(\"change\", update)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [])\n\n  // Intersection Observer: pause animation when off-screen when animateWhenNotVisible is false\n  useEffect(() => {\n    if (animateWhenNotVisible || !canvasRef.current) return\n    const canvas = canvasRef.current\n    const observer = new IntersectionObserver(\n      (entries) => {\n        for (const entry of entries) {\n          isVisibleRef.current = entry.isIntersecting\n          if (entry.isIntersecting) {\n            requestAnimationFrame(drawScene)\n          }\n        }\n      },\n      { threshold: 0 }\n    )\n    observer.observe(canvas)\n    return () => observer.disconnect()\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [animateWhenNotVisible])\n\n  // Main effect for initialization and cleanup\n  useEffect(() => {\n    const textures = texturesArrRef.current\n\n    function init() {\n      initWebGL()\n      const gl = glRef.current\n      if (gl && canvasRef.current) {\n        gl.clearColor(...clearColor)\n        gl.clearDepth(1.0)\n        gl.enable(gl.DEPTH_TEST)\n        gl.depthFunc(gl.LEQUAL)\n        gl.viewport(0, 0, canvasRef.current.width, canvasRef.current.height)\n        canvasRef.current.height = canvasRef.current.clientHeight\n        canvasRef.current.width = canvasRef.current.clientWidth\n        processCustomUniforms()\n        processTextures()\n        initShaders(preProcessFragment(fs || BASIC_FS), vs || BASIC_VS)\n        initBuffers()\n        requestAnimationFrame(drawScene)\n        addEventListeners()\n        onResize()\n      }\n    }\n\n    initFrameIdRef.current = requestAnimationFrame(init)\n\n    // Cleanup function\n    return () => {\n      const gl = glRef.current\n      if (gl) {\n        gl.getExtension(\"WEBGL_lose_context\")?.loseContext()\n        gl.useProgram(null)\n        gl.deleteProgram(shaderProgramRef.current ?? null)\n        if (textures.length > 0) {\n          for (const texture of textures as Texture[]) {\n            gl.deleteTexture(texture._webglTexture)\n          }\n        }\n        shaderProgramRef.current = null\n      }\n      removeEventListeners()\n      cancelAnimationFrame(initFrameIdRef.current ?? 0)\n      cancelAnimationFrame(animFrameIdRef.current ?? 0)\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []) // Empty dependency array to run only once on mount\n\n  return (\n    <canvas\n      ref={canvasRef}\n      style={{ height: \"100%\", width: \"100%\", ...style }}\n      {...canvasProps}\n    />\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-chat-transcript.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-transcript.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Bubble,\n  BubbleContent,\n} from \"@/components/voice-agents/livekit/_ui/bubble\"\nimport {\n  Marker,\n  MarkerContent,\n  MarkerIcon,\n} from \"@/components/voice-agents/livekit/_ui/marker\"\nimport {\n  Message,\n  MessageContent,\n} from \"@/components/voice-agents/livekit/_ui/message\"\nimport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n} from \"@/components/voice-agents/livekit/_ui/message-scroller\"\nimport { AgentChatIndicator } from \"@/components/voice-agents/livekit/agent-chat-indicator\"\nimport {\n  type AgentState,\n  type ReceivedMessage,\n} from \"@livekit/components-react\"\nimport { type ComponentProps } from \"react\"\nimport { Streamdown } from \"streamdown\"\n\n/**\n * Props for the AgentChatTranscript component.\n */\nexport interface AgentChatTranscriptProps\n  extends ComponentProps<\"div\">,\n    ComponentProps<typeof MessageScrollerProvider>,\n    ComponentProps<typeof MessageScrollerViewport>,\n    ComponentProps<typeof MessageScrollerContent> {\n  /**\n   * Whether to automatically scroll to the bottom of the transcript when new messages are added.\n   * @defaultValue true\n   */\n  autoScroll?: boolean\n  /**\n   * The scroll anchor to use when auto-scrolling.\n   * @defaultValue false\n   */\n  scrollAnchor?: boolean | \"user\" | \"other\" | \"any\"\n  /**\n   * The scroll button render function\n   */\n  scrollButtonRender?: ComponentProps<typeof MessageScrollerButton>[\"render\"]\n  /**\n   * The scroll button behavior\n   */\n  scrollButtonBehavior?: ComponentProps<\n    typeof MessageScrollerButton\n  >[\"behavior\"]\n  /**\n   * The scroll button direction\n   */\n  scrollButtonDirection?: ComponentProps<\n    typeof MessageScrollerButton\n  >[\"direction\"]\n  /**\n   * The current state of the agent. When 'thinking', displays a loading indicator.\n   */\n  agentState?: AgentState\n  /**\n   * Array of messages to display in the transcript.\n   * @defaultValue []\n   */\n  messages?: ReceivedMessage[]\n  /**\n   * Additional CSS class names to apply to the conversation container.\n   */\n  className?: string\n}\n\n/**\n * A chat transcript component that displays a conversation between the user and agent.\n * Shows messages with timestamps and origin indicators, plus a thinking indicator\n * when the agent is processing.\n *\n * @extends ComponentProps<'div'>, ComponentProps<typeof MessageScrollerProvider>, ComponentProps<typeof MessageScrollerViewport>, ComponentProps<typeof MessageScrollerContent>\n *\n *\n * @example\n * ```tsx\n * <AgentChatTranscript\n *   agentState={agentState}\n *   messages={chatMessages}\n * />\n * ```\n */\nexport function AgentChatTranscript({\n  scrollAnchor,\n  autoScroll = true,\n  scrollMargin,\n  scrollEdgeThreshold,\n  preserveScrollOnPrepend,\n  scrollPreviousItemPeek,\n  defaultScrollPosition = \"last-anchor\",\n  scrollButtonRender,\n  scrollButtonBehavior,\n  scrollButtonDirection,\n  spacerClassName,\n  agentState,\n  messages = [],\n  className,\n  ...props\n}: AgentChatTranscriptProps) {\n  return (\n    <MessageScrollerProvider\n      autoScroll={autoScroll}\n      scrollMargin={scrollMargin}\n      defaultScrollPosition={defaultScrollPosition}\n      scrollEdgeThreshold={scrollEdgeThreshold}\n      scrollPreviousItemPeek={scrollPreviousItemPeek}\n    >\n      <MessageScroller className={className} {...props}>\n        <MessageScrollerViewport\n          preserveScrollOnPrepend={preserveScrollOnPrepend}\n        >\n          <MessageScrollerContent\n            spacerClassName={spacerClassName}\n            aria-busy={agentState === \"thinking\"}\n          >\n            {messages.map((receivedMessage) => {\n              const { id, timestamp, from, message } = receivedMessage\n              const time = new Date(timestamp)\n              const isUser = from?.isLocal\n              const locale =\n                typeof navigator !== \"undefined\" ? navigator.language : \"en-US\"\n              const title = time.toLocaleTimeString(locale, {\n                timeStyle: \"full\",\n              })\n              let _scrollAnchor = false\n\n              if (\n                scrollAnchor === \"any\" ||\n                (scrollAnchor === \"user\" && isUser) ||\n                (scrollAnchor === \"other\" && !isUser)\n              ) {\n                _scrollAnchor = true\n              }\n\n              return (\n                <MessageScrollerItem\n                  key={id}\n                  messageId={id}\n                  scrollAnchor={_scrollAnchor}\n                >\n                  <Message align={isUser ? \"end\" : \"start\"} title={title}>\n                    <MessageContent>\n                      <Bubble\n                        align={isUser ? \"end\" : \"start\"}\n                        variant={isUser ? \"secondary\" : \"ghost\"}\n                      >\n                        <BubbleContent>\n                          <Streamdown>{message}</Streamdown>\n                        </BubbleContent>\n                      </Bubble>\n                    </MessageContent>\n                  </Message>\n                </MessageScrollerItem>\n              )\n            })}\n\n            {/* Agent is thinking indicator */}\n            {agentState === \"thinking\" && (\n              <MessageScrollerItem>\n                <Marker role=\"status\">\n                  <MarkerIcon>\n                    <AgentChatIndicator size=\"sm\" />\n                  </MarkerIcon>\n                  <MarkerContent className=\"shimmer\">Thinking...</MarkerContent>\n                </Marker>\n              </MessageScrollerItem>\n            )}\n          </MessageScrollerContent>\n        </MessageScrollerViewport>\n\n        {/* Scroll to bottom button */}\n        <MessageScrollerButton\n          variant=\"outline\"\n          className=\"rounded-full\"\n          render={scrollButtonRender}\n          behavior={scrollButtonBehavior}\n          direction={scrollButtonDirection}\n        />\n      </MessageScroller>\n    </MessageScrollerProvider>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/bubble.tsx",
          "target": "@components/voice-agents/livekit/_ui/bubble.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction BubbleGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"bubble-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nconst bubbleVariants = cva(\n  \"group/bubble relative flex w-fit max-w-[80%] min-w-0 flex-col gap-1 group-data-[align=end]/message:self-end data-[align=end]:self-end data-[variant=ghost]:max-w-full\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80\",\n        secondary:\n          \"*:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]\",\n        muted:\n          \"*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]\",\n        tinted:\n          \"*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]\",\n        outline:\n          \"*:data-[slot=bubble-content]:border-border *:data-[slot=bubble-content]:bg-background [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30\",\n        ghost:\n          \"border-none *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50\",\n        destructive:\n          \"*:data-[slot=bubble-content]:bg-destructive/10 *:data-[slot=bubble-content]:text-destructive dark:*:data-[slot=bubble-content]:bg-destructive/20 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Bubble({\n  variant = \"default\",\n  align = \"start\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof bubbleVariants> & {\n    align?: \"start\" | \"end\"\n  }) {\n  return (\n    <div\n      data-slot=\"bubble\"\n      data-variant={variant}\n      data-align={align}\n      className={cn(bubbleVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BubbleContent({\n  asChild = false,\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  asChild?: boolean\n}) {\n  const Comp = asChild ? Slot.Root : \"div\"\n\n  return (\n    <Comp\n      data-slot=\"bubble-content\"\n      className={cn(\n        \"[button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-ring/50 w-fit max-w-full min-w-0 overflow-hidden rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed wrap-break-word group-data-[align=end]/bubble:self-end [button]:text-left [button,a]:transition-colors [button,a]:outline-none [button,a]:focus-visible:ring-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst bubbleReactionsVariants = cva(\n  \"absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm ring-3 ring-card has-[button]:p-0\",\n  {\n    variants: {\n      side: {\n        top: \"top-0 -translate-y-3/4\",\n        bottom: \"bottom-0 translate-y-3/4\",\n      },\n      align: {\n        start: \"left-3\",\n        end: \"right-3\",\n      },\n    },\n    defaultVariants: {\n      side: \"bottom\",\n      align: \"end\",\n    },\n  }\n)\n\nfunction BubbleReactions({\n  side = \"bottom\",\n  align = \"end\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  align?: \"start\" | \"end\"\n  side?: \"top\" | \"bottom\"\n}) {\n  return (\n    <div\n      data-slot=\"bubble-reactions\"\n      data-align={align}\n      data-side={side}\n      className={cn(bubbleReactionsVariants({ side, align }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { BubbleGroup, Bubble, BubbleContent, BubbleReactions }\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/marker.tsx",
          "target": "@components/voice-agents/livekit/_ui/marker.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst markerVariants = cva(\n  \"group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground\",\n  {\n    variants: {\n      variant: {\n        default: \"\",\n        separator:\n          \"before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border\",\n        border: \"border-b border-border pb-2\",\n      },\n    },\n  }\n)\n\nfunction Marker({\n  className,\n  variant = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof markerVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"div\"\n\n  return (\n    <Comp\n      data-slot=\"marker\"\n      data-variant={variant}\n      className={cn(markerVariants({ variant, className }))}\n      {...props}\n    />\n  )\n}\n\nfunction MarkerIcon({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"marker-icon\"\n      aria-hidden=\"true\"\n      className={cn(\n        \"size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MarkerContent({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"marker-content\"\n      className={cn(\n        \"*:[a]:hover:text-foreground min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Marker, MarkerIcon, MarkerContent, markerVariants }\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/message.tsx",
          "target": "@components/voice-agents/livekit/_ui/message.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction MessageGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction Message({\n  className,\n  align = \"start\",\n  ...props\n}: React.ComponentProps<\"div\"> & { align?: \"start\" | \"end\" }) {\n  return (\n    <div\n      data-slot=\"message\"\n      data-align={align}\n      className={cn(\n        \"group/message relative flex w-full min-w-0 gap-2 text-sm data-[align=end]:flex-row-reverse\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageAvatar({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-avatar\"\n      className={cn(\n        \"bg-muted flex w-fit min-w-8 shrink-0 items-center justify-center self-end overflow-hidden rounded-full group-has-data-[slot=message-footer]/message:-translate-y-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-content\"\n      className={cn(\n        \"flex w-full min-w-0 flex-col gap-2.5 wrap-break-word group-data-[align=end]/message:*:data-slot:self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-header\"\n      className={cn(\n        \"text-muted-foreground flex max-w-full min-w-0 items-center px-3 text-xs font-medium group-has-data-[variant=ghost]/message:px-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-footer\"\n      className={cn(\n        \"text-muted-foreground flex max-w-full min-w-0 items-center px-3 text-xs font-medium group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  MessageGroup,\n  Message,\n  MessageAvatar,\n  MessageContent,\n  MessageFooter,\n  MessageHeader,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/_ui/message-scroller.tsx",
          "target": "@components/voice-agents/livekit/_ui/message-scroller.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ArrowDownIcon } from \"lucide-react\"\nimport * as React from \"react\"\nimport { Button } from \"./button\"\n\ntype ScrollerContextValue = {\n  autoScroll: boolean\n  atEnd: boolean\n  atEndRef: React.RefObject<boolean>\n  atStart: boolean\n  defaultScrollPosition: \"first\" | \"last\" | \"last-anchor\"\n  scrollEdgeThreshold: number\n  scrollMargin: number\n  scrollPreviousItemPeek: number\n  setAtEnd: (atEnd: boolean) => void\n  setAtStart: (atStart: boolean) => void\n  viewportRef: React.RefObject<HTMLDivElement | null>\n}\n\nconst ScrollerContext = React.createContext<ScrollerContextValue | null>(null)\n\nexport interface MessageScrollerProviderProps {\n  children?: React.ReactNode\n  autoScroll?: boolean\n  scrollMargin?: number\n  defaultScrollPosition?: \"first\" | \"last\" | \"last-anchor\"\n  scrollEdgeThreshold?: number\n  scrollPreviousItemPeek?: number\n}\n\nfunction MessageScrollerProvider({\n  children,\n  autoScroll = true,\n  defaultScrollPosition = \"last-anchor\",\n  scrollEdgeThreshold = 8,\n  scrollMargin = 0,\n  scrollPreviousItemPeek = 0,\n}: MessageScrollerProviderProps) {\n  const viewportRef = React.useRef<HTMLDivElement>(null)\n  const atEndRef = React.useRef(true)\n  const [atEnd, setAtEnd] = React.useState(true)\n  const [atStart, setAtStart] = React.useState(true)\n  const updateAtEnd = React.useCallback((nextAtEnd: boolean) => {\n    atEndRef.current = nextAtEnd\n    setAtEnd(nextAtEnd)\n  }, [])\n  return (\n    <ScrollerContext.Provider\n      value={{\n        autoScroll,\n        atEnd,\n        atEndRef,\n        atStart,\n        defaultScrollPosition,\n        scrollEdgeThreshold,\n        scrollMargin,\n        scrollPreviousItemPeek,\n        setAtEnd: updateAtEnd,\n        setAtStart,\n        viewportRef,\n      }}\n    >\n      {children}\n    </ScrollerContext.Provider>\n  )\n}\n\nfunction useScroller() {\n  const context = React.useContext(ScrollerContext)\n  if (!context) {\n    throw new Error(\n      \"MessageScroller components require MessageScrollerProvider\"\n    )\n  }\n  return context\n}\n\nfunction MessageScroller({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"message-scroller\"\n      className={cn(\n        \"group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction MessageScrollerViewport({\n  className,\n  preserveScrollOnPrepend = false,\n  onScroll,\n  style,\n  ...props\n}: React.ComponentProps<\"div\"> & { preserveScrollOnPrepend?: boolean }) {\n  const {\n    atEndRef,\n    autoScroll,\n    defaultScrollPosition,\n    scrollEdgeThreshold,\n    scrollMargin,\n    scrollPreviousItemPeek,\n    setAtEnd,\n    setAtStart,\n    viewportRef,\n  } = useScroller()\n\n  React.useLayoutEffect(() => {\n    const viewport = viewportRef.current\n    if (!viewport) return\n    const update = () => {\n      const atEnd =\n        viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <=\n        scrollEdgeThreshold\n      setAtEnd(atEnd)\n      setAtStart(viewport.scrollTop <= scrollEdgeThreshold)\n    }\n    if (defaultScrollPosition === \"last-anchor\") {\n      const anchors = viewport.querySelectorAll<HTMLElement>(\n        '[data-scroll-anchor=\"true\"]'\n      )\n      const anchor = anchors.item(anchors.length - 1)\n      if (anchor) anchor.scrollIntoView({ block: \"end\" })\n      else viewport.scrollTop = viewport.scrollHeight\n    } else if (defaultScrollPosition === \"last\") {\n      viewport.scrollTop = viewport.scrollHeight\n    }\n    let previousScrollHeight = viewport.scrollHeight\n    const observer = new MutationObserver((records) => {\n      const nextScrollHeight = viewport.scrollHeight\n      const prepended = records.some(\n        (record) =>\n          record.type === \"childList\" &&\n          record.addedNodes.length > 0 &&\n          (record.previousSibling === null ||\n            (record.previousSibling instanceof HTMLElement &&\n              record.previousSibling.dataset.slot ===\n                \"message-scroller-spacer\"))\n      )\n      if (preserveScrollOnPrepend && prepended) {\n        viewport.scrollTop += nextScrollHeight - previousScrollHeight\n      } else if (autoScroll && atEndRef.current) {\n        viewport.scrollTo({ top: nextScrollHeight })\n      }\n      previousScrollHeight = nextScrollHeight\n      update()\n    })\n    observer.observe(viewport, { childList: true, subtree: true })\n    update()\n    return () => observer.disconnect()\n  }, [\n    atEndRef,\n    autoScroll,\n    defaultScrollPosition,\n    preserveScrollOnPrepend,\n    scrollEdgeThreshold,\n    setAtEnd,\n    setAtStart,\n    viewportRef,\n  ])\n\n  return (\n    <div\n      ref={viewportRef}\n      data-slot=\"message-scroller-viewport\"\n      className={cn(\n        \"size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain\",\n        className\n      )}\n      style={{\n        scrollPaddingBlockStart: scrollPreviousItemPeek,\n        scrollPaddingBlockEnd: scrollMargin,\n        ...style,\n      }}\n      onScroll={(event) => {\n        const viewport = event.currentTarget\n        setAtEnd(\n          viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <=\n            scrollEdgeThreshold\n        )\n        setAtStart(viewport.scrollTop <= scrollEdgeThreshold)\n        onScroll?.(event)\n      }}\n      {...props}\n    />\n  )\n}\n\nfunction MessageScrollerContent({\n  className,\n  spacerClassName,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & { spacerClassName?: string }) {\n  return (\n    <div\n      data-slot=\"message-scroller-content\"\n      className={cn(\"flex min-h-full flex-col gap-8\", className)}\n      {...props}\n    >\n      {spacerClassName ? (\n        <div\n          aria-hidden=\"true\"\n          data-slot=\"message-scroller-spacer\"\n          className={cn(\"flex-1\", spacerClassName)}\n        />\n      ) : null}\n      {children}\n    </div>\n  )\n}\n\nfunction MessageScrollerItem({\n  className,\n  messageId,\n  scrollAnchor,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  messageId?: string\n  scrollAnchor?: boolean\n}) {\n  return (\n    <div\n      data-slot=\"message-scroller-item\"\n      data-message-id={messageId}\n      data-scroll-anchor={scrollAnchor || undefined}\n      className={cn(\"min-w-0 shrink-0\", className)}\n      {...props}\n    />\n  )\n}\n\nexport interface MessageScrollerButtonProps\n  extends Omit<React.ComponentProps<typeof Button>, \"children\"> {\n  behavior?: ScrollBehavior\n  direction?: \"start\" | \"end\"\n  render?: React.ReactElement\n  children?: React.ReactNode\n}\n\nfunction MessageScrollerButton({\n  behavior = \"smooth\",\n  direction = \"end\",\n  className,\n  children,\n  render,\n  onClick,\n  ...props\n}: MessageScrollerButtonProps) {\n  const { atEnd, atStart, viewportRef } = useScroller()\n  const inactive = direction === \"end\" ? atEnd : atStart\n  return (\n    <Button\n      asChild={Boolean(render)}\n      type=\"button\"\n      aria-hidden={inactive}\n      tabIndex={inactive ? -1 : 0}\n      className={cn(\n        \"bg-background absolute left-1/2 -translate-x-1/2 border transition-[opacity,transform] duration-200\",\n        direction === \"end\" ? \"bottom-4\" : \"top-4\",\n        inactive && \"pointer-events-none translate-y-2 opacity-0\",\n        className\n      )}\n      onClick={(event) => {\n        const viewport = viewportRef.current\n        viewport?.scrollTo({\n          top: direction === \"end\" ? viewport.scrollHeight : 0,\n          behavior,\n        })\n        onClick?.(event)\n      }}\n      {...props}\n    >\n      {render ?? (\n        <>\n          {children ?? (\n            <ArrowDownIcon\n              className={cn(direction === \"start\" && \"rotate-180\")}\n            />\n          )}\n          <span className=\"sr-only\">\n            {direction === \"end\" ? \"Scroll to end\" : \"Scroll to start\"}\n          </span>\n        </>\n      )}\n    </Button>\n  )\n}\n\nexport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/agent-chat-indicator.tsx",
          "target": "@components/voice-agents/livekit/agent-chat-indicator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { motion, useReducedMotion, type MotionProps } from \"motion/react\"\nimport { type ComponentProps, type Ref } from \"react\"\n\nconst motionAnimationProps = {\n  variants: {\n    hidden: {\n      opacity: 0,\n      scale: 0.1,\n      transition: {\n        duration: 0.1,\n        ease: \"linear\" as const,\n      },\n    },\n    visible: {\n      opacity: [0.5, 1],\n      scale: [0.9, 1],\n      transition: {\n        type: \"spring\" as const,\n        bounce: 0,\n        duration: 0.5,\n        repeat: Infinity,\n        repeatType: \"mirror\" as const,\n      },\n    },\n  },\n  initial: \"hidden\",\n  animate: \"visible\",\n  exit: \"hidden\",\n}\n\nconst agentChatIndicatorVariants = cva(\n  \"bg-muted-foreground inline-block size-2.5 rounded-full\",\n  {\n    variants: {\n      size: {\n        sm: \"size-3\",\n        md: \"size-4\",\n        lg: \"size-6\",\n      },\n    },\n    defaultVariants: {\n      size: \"md\",\n    },\n  }\n)\n\n/**\n * Props for the AgentChatIndicator component.\n */\nexport interface AgentChatIndicatorProps extends MotionProps {\n  /**\n   * The size of the indicator dot.\n   * @defaultValue 'md'\n   */\n  size?: \"sm\" | \"md\" | \"lg\"\n  /**\n   * Additional CSS class names to apply to the indicator.\n   */\n  className?: string\n  /**\n   * Allows getting a ref to the component instance.\\nOnce the component unmounts, React will set `ref.current` to `null`\\n(or call the ref with `null` if you passed a callback ref).\\n@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}\n   */\n  ref?: Ref<HTMLSpanElement>\n}\n\n/**\n * An animated indicator that shows the agent is processing or thinking.\n * Displays as a pulsing dot, typically used in chat interfaces.\n *\n * @extends ComponentProps<'span'>\n *\n * @example\n * ```tsx\n * {agentState === 'thinking' && <AgentChatIndicator size=\"md\" />}\n * ```\n */\nexport function AgentChatIndicator({\n  size = \"md\",\n  className,\n  ...props\n}: AgentChatIndicatorProps &\n  ComponentProps<\"span\"> &\n  VariantProps<typeof agentChatIndicatorVariants>) {\n  const prefersReducedMotion = useReducedMotion()\n\n  return (\n    <motion.span\n      {...(prefersReducedMotion\n        ? { initial: false, animate: { opacity: 1, scale: 1 } }\n        : motionAnimationProps)}\n      transition={{ duration: 0.1, ease: \"linear\" as const }}\n      className={cn(agentChatIndicatorVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/blocks/agent-session-view-01/components/tile-view.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-session-view-01/components/tile-view.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport {\n  useLocalParticipant,\n  useTracks,\n  useVoiceAssistant,\n  VideoTrack,\n  type TrackReference,\n} from \"@livekit/components-react\"\nimport { Track } from \"livekit-client\"\nimport { AnimatePresence, motion, type MotionProps } from \"motion/react\"\nimport React, { useMemo } from \"react\"\nimport { type AudioVisualizerConfig } from \"./agent-session-block\"\nimport { AudioVisualizer } from \"./audio-visualizer\"\n\nconst ANIMATION_TRANSITION: MotionProps[\"transition\"] = {\n  type: \"spring\",\n  stiffness: 675,\n  damping: 75,\n  mass: 1,\n}\n\nconst tileViewClassNames = {\n  // GRID\n  // 2 Columns x 3 Rows\n  grid: [\n    \"h-full w-full\",\n    \"grid gap-x-2 place-content-center\",\n    \"grid-cols-[1fr_1fr] grid-rows-[90px_1fr_90px]\",\n  ],\n  // Agent\n  // chatOpen: true,\n  // hasSecondTile: true\n  // layout: Column 1 / Row 1\n  // align: x-end y-center\n  agentChatOpenWithSecondTile: [\n    \"col-start-1 row-start-1\",\n    \"self-center justify-self-end\",\n  ],\n  // Agent\n  // chatOpen: true,\n  // hasSecondTile: false\n  // layout: Column 1 / Row 1 / Column-Span 2\n  // align: x-center y-center\n  agentChatOpenWithoutSecondTile: [\n    \"col-start-1 row-start-1\",\n    \"col-span-2\",\n    \"place-content-center\",\n  ],\n  // Agent\n  // chatOpen: false\n  // layout: Column 1 / Row 1 / Column-Span 2 / Row-Span 3\n  // align: x-center y-center\n  agentChatClosed: [\n    \"col-start-1 row-start-1\",\n    \"col-span-2 row-span-3\",\n    \"place-content-center\",\n  ],\n  // Second tile\n  // chatOpen: true,\n  // hasSecondTile: true\n  // layout: Column 2 / Row 1\n  // align: x-start y-center\n  secondTileChatOpen: [\n    \"col-start-2 row-start-1\",\n    \"self-center justify-self-start\",\n  ],\n  // Second tile\n  // chatOpen: false,\n  // hasSecondTile: false\n  // layout: Column 2 / Row 2\n  // align: x-end y-end\n  secondTileChatClosed: [\"col-start-2 row-start-3\", \"place-content-end\"],\n}\n\nexport function useLocalTrackRef(source: Track.Source) {\n  const { localParticipant } = useLocalParticipant()\n  const publication = localParticipant.getTrackPublication(source)\n  const trackRef = useMemo<TrackReference | undefined>(\n    () =>\n      publication\n        ? { source, participant: localParticipant, publication }\n        : undefined,\n    [source, publication, localParticipant]\n  )\n  return trackRef\n}\n\ninterface TileLayoutProps {\n  isChatOpen: boolean\n  audioVisualizer?: AudioVisualizerConfig\n}\n\nexport function TileLayout({ isChatOpen, audioVisualizer }: TileLayoutProps) {\n  const { videoTrack: agentVideoTrack } = useVoiceAssistant()\n  const [screenShareTrack] = useTracks([Track.Source.ScreenShare])\n  const cameraTrack: TrackReference | undefined = useLocalTrackRef(\n    Track.Source.Camera\n  )\n\n  const isCameraEnabled = cameraTrack && !cameraTrack.publication.isMuted\n  const isScreenShareEnabled =\n    screenShareTrack && !screenShareTrack.publication.isMuted\n  const hasSecondTile = isCameraEnabled || isScreenShareEnabled\n\n  const animationDelay = isChatOpen ? 0 : 0.15\n  const isAvatar = agentVideoTrack !== undefined\n  const videoWidth = agentVideoTrack?.publication.dimensions?.width ?? 0\n  const videoHeight = agentVideoTrack?.publication.dimensions?.height ?? 0\n\n  const { type: audioVisualizerType = \"bar\", ...audioVisualizerConfig } =\n    audioVisualizer ?? {}\n\n  return (\n    <div className=\"pointer-events-none absolute inset-x-0 top-8 bottom-24 z-50 @md/agent-session-block:top-12 @md/agent-session-block:bottom-40\">\n      <div className=\"relative mx-auto h-full max-w-2xl px-4 @md/agent-session-block:px-0\">\n        <div className={cn(tileViewClassNames.grid)}>\n          {/* Agent */}\n          <div\n            className={cn([\n              \"grid\",\n              !isChatOpen && tileViewClassNames.agentChatClosed,\n              isChatOpen &&\n                hasSecondTile &&\n                tileViewClassNames.agentChatOpenWithSecondTile,\n              isChatOpen &&\n                !hasSecondTile &&\n                tileViewClassNames.agentChatOpenWithoutSecondTile,\n            ])}\n          >\n            <AnimatePresence mode=\"popLayout\">\n              {!isAvatar && (\n                // Audio Agent\n                <motion.div\n                  key=\"agent\"\n                  layoutId=\"agent\"\n                  initial={{ opacity: 0 }}\n                  animate={{ opacity: 1 }}\n                  transition={{\n                    ...ANIMATION_TRANSITION,\n                    delay: animationDelay,\n                  }}\n                  className={cn(\"relative aspect-square h-[90px]\")}\n                >\n                  <AudioVisualizer\n                    key=\"audio-visualizer\"\n                    initial={{ scale: 1 }}\n                    animate={{ scale: isChatOpen ? 0.2 : 1 }}\n                    transition={{\n                      ...ANIMATION_TRANSITION,\n                      delay: animationDelay,\n                    }}\n                    type={audioVisualizerType}\n                    config={audioVisualizerConfig}\n                    className={cn(\n                      \"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\",\n                      \"bg-background rounded-[50px] border border-transparent transition-[border,drop-shadow]\",\n                      isChatOpen && \"border-input shadow-2xl/10 delay-200\"\n                    )}\n                    style={{ color: audioVisualizer?.color }}\n                  />\n                </motion.div>\n              )}\n\n              {isAvatar && (\n                // Avatar Agent\n                <motion.div\n                  key=\"avatar\"\n                  layoutId=\"avatar\"\n                  initial={{\n                    scale: 1,\n                    opacity: 1,\n                    maskImage:\n                      \"radial-gradient(circle, rgba(0, 0, 0, 1) 0, rgba(0, 0, 0, 1) 20px, transparent 20px)\",\n                    filter: \"blur(20px)\",\n                  }}\n                  animate={{\n                    maskImage:\n                      \"radial-gradient(circle, rgba(0, 0, 0, 1) 0, rgba(0, 0, 0, 1) 500px, transparent 500px)\",\n                    filter: \"blur(0px)\",\n                    borderRadius: isChatOpen ? 6 : 12,\n                  }}\n                  transition={{\n                    ...ANIMATION_TRANSITION,\n                    delay: animationDelay,\n                    maskImage: {\n                      duration: 1,\n                    },\n                    filter: {\n                      duration: 1,\n                    },\n                  }}\n                  className={cn(\n                    \"overflow-hidden bg-black drop-shadow-xl/80\",\n                    isChatOpen ? \"h-[90px]\" : \"h-auto w-full\"\n                  )}\n                >\n                  <VideoTrack\n                    width={videoWidth}\n                    height={videoHeight}\n                    trackRef={agentVideoTrack}\n                    className={cn(isChatOpen && \"size-[90px] object-cover\")}\n                  />\n                </motion.div>\n              )}\n            </AnimatePresence>\n          </div>\n\n          <div\n            className={cn([\n              \"grid\",\n              isChatOpen && tileViewClassNames.secondTileChatOpen,\n              !isChatOpen && tileViewClassNames.secondTileChatClosed,\n            ])}\n          >\n            {/* Camera & Screen Share */}\n            <AnimatePresence>\n              {((cameraTrack && isCameraEnabled) ||\n                (screenShareTrack && isScreenShareEnabled)) && (\n                <motion.div\n                  key=\"camera\"\n                  layout=\"position\"\n                  layoutId=\"camera\"\n                  initial={{\n                    opacity: 0,\n                    scale: 0,\n                  }}\n                  animate={{\n                    opacity: 1,\n                    scale: 1,\n                  }}\n                  exit={{\n                    opacity: 0,\n                    scale: 0,\n                  }}\n                  transition={{\n                    ...ANIMATION_TRANSITION,\n                    delay: animationDelay,\n                  }}\n                  className=\"aspect-square size-[90px] drop-shadow-lg/20\"\n                >\n                  <VideoTrack\n                    trackRef={cameraTrack || screenShareTrack}\n                    width={\n                      (cameraTrack || screenShareTrack)?.publication.dimensions\n                        ?.width ?? 0\n                    }\n                    height={\n                      (cameraTrack || screenShareTrack)?.publication.dimensions\n                        ?.height ?? 0\n                    }\n                    className=\"bg-muted aspect-square size-[90px] rounded-md object-cover\"\n                  />\n                </motion.div>\n              )}\n            </AnimatePresence>\n          </div>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/blocks/agent-session-view-01/components/audio-visualizer.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-session-view-01/components/audio-visualizer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  AgentAudioVisualizerBar,\n  type AgentAudioVisualizerBarProps,\n} from \"@/components/voice-agents/livekit/agent-audio-visualizer-bar\"\nimport {\n  AgentAudioVisualizerGrid,\n  type AgentAudioVisualizerGridProps,\n} from \"@/components/voice-agents/livekit/agent-audio-visualizer-grid\"\nimport {\n  AgentAudioVisualizerRadial,\n  type AgentAudioVisualizerRadialProps,\n} from \"@/components/voice-agents/livekit/agent-audio-visualizer-radial\"\nimport {\n  AgentAudioVisualizerWave,\n  type AgentAudioVisualizerWaveProps,\n} from \"@/components/voice-agents/livekit/agent-audio-visualizer-wave\"\nimport { cn } from \"@/lib/utils\"\nimport { useVoiceAssistant } from \"@livekit/components-react\"\nimport { motion, type MotionProps } from \"motion/react\"\nimport React from \"react\"\n\nconst MotionAgentAudioVisualizerBar = motion.create(AgentAudioVisualizerBar)\nconst MotionAgentAudioVisualizerGrid = motion.create(AgentAudioVisualizerGrid)\nconst MotionAgentAudioVisualizerRadial = motion.create(\n  AgentAudioVisualizerRadial\n)\nconst MotionAgentAudioVisualizerWave = motion.create(AgentAudioVisualizerWave)\n\nfunction getGridSize(\n  rowCount: number,\n  columnCount: number\n): AgentAudioVisualizerBarProps[\"size\"] {\n  const totalCount = rowCount * columnCount\n\n  if (totalCount < 100) {\n    return \"xl\"\n  } else if (totalCount < 200) {\n    return \"lg\"\n  } else if (totalCount < 300) {\n    return \"md\"\n  }\n\n  return \"sm\"\n}\n\nfunction getBarSize(barCount: number): AgentAudioVisualizerBarProps[\"size\"] {\n  if (barCount <= 5) {\n    return \"xl\"\n  } else if (barCount <= 10) {\n    return \"lg\"\n  } else if (barCount <= 15) {\n    return \"md\"\n  } else if (barCount <= 30) {\n    return \"sm\"\n  }\n\n  return \"icon\"\n}\n\nfunction getBarClassName(size: AgentAudioVisualizerBarProps[\"size\"]) {\n  if (size == \"xl\") {\n    return \"size-[450px] *:min-h-[64px] *:w-[64px] gap-4\"\n  } else if (size == \"lg\") {\n    return \"size-[450px] *:min-h-[48px] *:w-[48px]\"\n  } else if (size == \"md\") {\n    return \"size-[350px] @md/agent-session-block:size-[450px]  *:min-h-[32px] *:w-[32px]\"\n  } else if (size == \"sm\") {\n    return \"size-[300px] @md/agent-session-block:size-[450px] *:min-h-[16px] *:w-[16px]\"\n  }\n\n  return \"size-[300px] @md/agent-session-block:size-[450px] *:min-h-[4px] *:w-[4px]\"\n}\n\ninterface AudioVisualizerProps extends MotionProps {\n  type: \"bar\" | \"wave\" | \"grid\" | \"radial\"\n  config?:\n    | AgentAudioVisualizerBarProps\n    | AgentAudioVisualizerWaveProps\n    | AgentAudioVisualizerGridProps\n    | AgentAudioVisualizerRadialProps\n  className?: string\n}\n\nexport function AudioVisualizer({\n  type,\n  config,\n  className,\n  ...props\n}: AudioVisualizerProps) {\n  const { state, audioTrack } = useVoiceAssistant()\n\n  // `state`/`audioTrack` always reflect the live agent session; any same-named field on\n  // `config` is ignored by spreading it before these are set explicitly below.\n  switch (type) {\n    case \"wave\": {\n      return (\n        <motion.div className={className} {...props}>\n          <MotionAgentAudioVisualizerWave\n            {...config}\n            state={state}\n            audioTrack={audioTrack}\n            className=\"size-[300px] @md/agent-session-block:size-[450px]\"\n          />\n        </motion.div>\n      )\n    }\n    case \"grid\": {\n      const {\n        size,\n        radius,\n        rowCount = 15,\n        columnCount = 15,\n      } = config as AgentAudioVisualizerGridProps\n\n      return (\n        <MotionAgentAudioVisualizerGrid\n          {...config}\n          size={size ?? getGridSize(rowCount, columnCount)}\n          state={state}\n          audioTrack={audioTrack}\n          rowCount={rowCount}\n          columnCount={columnCount}\n          radius={radius ?? Math.round(Math.min(rowCount, columnCount) / 4)}\n          className={cn(\n            \"size-[350px] gap-0 p-20 *:place-self-center @md/agent-session-block:size-[450px]\",\n            className\n          )}\n          {...props}\n        />\n      )\n    }\n    case \"radial\": {\n      const { radius = 100, barCount = 25 } =\n        config as AgentAudioVisualizerRadialProps\n      return (\n        <motion.div className={className} {...props}>\n          <MotionAgentAudioVisualizerRadial\n            {...config}\n            size=\"xl\"\n            state={state}\n            radius={radius}\n            barCount={barCount}\n            audioTrack={audioTrack}\n            className=\"size-[450px]\"\n          />\n        </motion.div>\n      )\n    }\n    default: {\n      const { size, barCount = 5 } =\n        (config as AgentAudioVisualizerBarProps) ?? {}\n      const _size = size ?? getBarSize(barCount)\n      const sizedClassName = getBarClassName(_size)\n\n      return (\n        <MotionAgentAudioVisualizerBar\n          {...config}\n          size={_size}\n          state={state}\n          barCount={barCount}\n          audioTrack={audioTrack}\n          className={cn(sizedClassName, className)}\n          {...props}\n        >\n          <span className=\"min-h-2.5 w-2.5 rounded-full bg-current/10 transition-colors duration-250 ease-linear data-[lk-highlighted=true]:bg-current\" />\n        </MotionAgentAudioVisualizerBar>\n      )\n    }\n  }\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/blocks/agent-popup-01/components/popup-view.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-popup-01/components/popup-view.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { type AgentControlBarControls } from \"@/components/voice-agents/livekit/agent-control-bar\"\nimport { AgentSessionView_01 } from \"@/components/voice-agents/livekit/blocks/agent-session-view-01/components/agent-session-block\"\nimport type { AudioVisualizerConfig } from \"@/components/voice-agents/livekit/blocks/agent-session-view-01/components/agent-session-block\"\nimport { StartAudioButton } from \"@/components/voice-agents/livekit/start-audio-button\"\nimport { cn } from \"@/lib/utils\"\nimport { AnimatePresence, motion } from \"motion/react\"\nimport { useEffect, useState } from \"react\"\nimport type { AgentPopupError } from \"./agent-popup-block\"\n\ninterface ErrorOverlayProps {\n  logo?: string\n  agentName?: string\n  error?: AgentPopupError\n}\n\nfunction ErrorOverlay({ logo, agentName, error }: ErrorOverlayProps) {\n  const [logoFailed, setLogoFailed] = useState(false)\n  useEffect(() => {\n    setLogoFailed(false)\n  }, [logo])\n  const showLogo = Boolean(logo) && !logoFailed\n\n  return error ? (\n    <motion.div\n      initial={{ opacity: 0 }}\n      animate={{ opacity: 1 }}\n      data-testid=\"error-overlay\"\n      // @ts-expect-error React's types lag the platform on `inert`.\n      inert={error === null ? \"\" : undefined}\n      className={cn(\n        \"bg-background absolute inset-0 z-50 flex h-full w-full flex-col items-center justify-center gap-5 px-6 text-center transition-opacity\"\n      )}\n    >\n      {showLogo ? (\n        // eslint-disable-next-line @next/next/no-img-element\n        <img\n          src={logo}\n          alt={`${agentName ?? \"Agent\"} logo`}\n          className=\"size-6 object-contain\"\n          referrerPolicy=\"no-referrer\"\n          onError={() => setLogoFailed(true)}\n        />\n      ) : null}\n      <span className=\"text-foreground leading-tight font-medium text-pretty\">\n        {error?.title}\n      </span>\n      <span className=\"text-muted-foreground text-sm text-balance\">\n        {error?.description}\n      </span>\n    </motion.div>\n  ) : null\n}\n\nexport interface PopupViewProps {\n  agentName?: string\n  logo?: string\n  error?: AgentPopupError\n  controls: AgentControlBarControls\n  themeMode?: \"dark\" | \"light\"\n  preConnectMessage?: string\n  isPreConnectBufferEnabled?: boolean\n  audioVisualizer?: AudioVisualizerConfig\n  onDisconnect?: () => void\n}\n\nexport function PopupView({\n  agentName,\n  logo,\n  error,\n  controls,\n  themeMode,\n  isPreConnectBufferEnabled,\n  preConnectMessage,\n  audioVisualizer,\n  onDisconnect,\n}: PopupViewProps) {\n  return (\n    <motion.div\n      initial={{ opacity: 0, translateY: 8 }}\n      animate={{ opacity: 1, translateY: 0 }}\n      exit={{ opacity: 0, translateY: 8 }}\n      transition={{ type: \"spring\", bounce: 0, duration: 0.4 }}\n      className=\"fixed right-4 bottom-20 left-4 z-50 h-[480px] md:left-auto md:w-[360px]\"\n    >\n      <div className=\"relative flex h-full w-full flex-col overflow-hidden rounded-[40px] border drop-shadow-md\">\n        <AnimatePresence>\n          <ErrorOverlay logo={logo} agentName={agentName} error={error} />\n        </AnimatePresence>\n        <StartAudioButton\n          label=\"Enable Audio\"\n          className=\"mx-4 mt-2 rounded-full\"\n        />\n        <AgentSessionView_01\n          controls={controls}\n          themeMode={themeMode}\n          isPreConnectBufferEnabled={isPreConnectBufferEnabled}\n          preConnectMessage={preConnectMessage}\n          audioVisualizer={audioVisualizer}\n          onDisconnect={onDisconnect}\n        />\n      </div>\n    </motion.div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/start-audio-button.tsx",
          "target": "@components/voice-agents/livekit/start-audio-button.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/voice-agents/livekit/_ui/button\"\nimport { useEnsureRoom, useStartAudio } from \"@livekit/components-react\"\nimport { type Room } from \"livekit-client\"\nimport { type ComponentProps } from \"react\"\n\n/**\n * Props for the StartAudioButton component.\n */\nexport interface StartAudioButtonProps extends ComponentProps<\"button\"> {\n  /**\n   * The size of the button.\n   * @defaultValue 'default'\n   */\n  size?: \"default\" | \"sm\" | \"lg\" | \"icon\" | \"icon-sm\" | \"icon-lg\"\n  /**\n   * The variant of the button.\n   * @defaultValue 'default'\n   */\n  variant?:\n    | \"default\"\n    | \"destructive\"\n    | \"outline\"\n    | \"secondary\"\n    | \"ghost\"\n    | \"link\"\n  /**\n   * The LiveKit room instance. If not provided, uses the room from context.\n   */\n  room?: Room\n  /**\n   * The label text to display on the button.\n   */\n  label: string\n}\n\n/**\n * A button that allows users to start audio playback.\n * Required for browsers that block autoplay of audio.\n * Only renders when audio playback is blocked.\n *\n * @extends ComponentProps<'button'>\n *\n * @example\n * ```tsx\n * <StartAudioButton label=\"Click to allow audio playback\" />\n * ```\n */\nexport function StartAudioButton({\n  size = \"default\",\n  variant = \"default\",\n  label,\n  room,\n  className,\n  ...props\n}: StartAudioButtonProps) {\n  const roomEnsured = useEnsureRoom(room)\n  const { mergedProps } = useStartAudio({ room: roomEnsured, props })\n\n  return (\n    <Button\n      size={size}\n      variant={variant}\n      {...props}\n      {...mergedProps}\n      // don't merge useStartAudio className\n      className={className}\n    >\n      {label}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/blocks/agent-popup-01/components/trigger.tsx",
          "target": "@components/voice-agents/livekit/blocks/agent-popup-01/components/trigger.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/voice-agents/livekit/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { AudioLinesIcon, PhoneOffIcon, XIcon } from \"lucide-react\"\nimport { useEffect, useState, type ComponentProps } from \"react\"\nimport type { AgentPopupError } from \"./agent-popup-block\"\n\nexport interface TriggerProps extends ComponentProps<\"button\"> {\n  /** Logo image shown in place of the default audio icon. */\n  logo?: string\n  /** Brand color used for the idle ring/disc and, via contrast, the fallback icon color. */\n  color?: string\n  /** Used to build the default `aria-label` (e.g. \"Rex agent\") and image `alt` text. */\n  agentName?: string\n  /** Whether the popup is currently open. Drives the connecting/active/error visual states. */\n  isPressed?: boolean\n  /** Whether the agent session is connected. Only relevant while `isPressed` is true. */\n  isConnected?: boolean\n  /** Session error, if any. Only relevant while `isPressed` is true. */\n  error?: AgentPopupError\n  /** Called when the trigger is clicked. */\n  onToggle: () => void\n}\n\nexport function Trigger({\n  logo,\n  color,\n  error,\n  agentName,\n  isPressed = false,\n  isConnected = false,\n  onToggle,\n  className,\n  ...props\n}: TriggerProps) {\n  const altText = agentName ? `${agentName} agent` : \"Open assistant\"\n  const isError = isPressed && error !== undefined\n  const isActive = isPressed && error === undefined && isConnected\n  const isConnecting = isPressed && !isError && !isActive\n  const isDestructive = isError || isActive\n  const [logoFailed, setLogoFailed] = useState(false)\n\n  useEffect(() => {\n    setLogoFailed(false)\n  }, [logo])\n  const showLogo = Boolean(logo) && !logoFailed\n\n  return (\n    <Button\n      type=\"button\"\n      size=\"lg\"\n      variant=\"ghost\"\n      onClick={onToggle}\n      aria-label={isPressed ? \"Close assistant\" : altText}\n      aria-expanded={isPressed}\n      className={cn(\n        \"relative m-0 block size-12 rounded-full p-0.5 drop-shadow-sm transition-transform duration-200 hover:scale-105 focus-visible:scale-105\",\n        className\n      )}\n      {...props}\n    >\n      <div\n        className={cn(\n          \"absolute inset-0 rounded-full bg-current transition-colors\",\n          isConnecting && \"animate-spin\",\n          isConnecting &&\n            \"bg-current/30 bg-conic from-transparent from-30% via-current via-50% to-transparent to-70%\",\n          isDestructive && \"bg-transparent\"\n        )}\n        style={{ color }}\n      />\n      <div\n        className={cn(\n          \"absolute inset-0 z-10 grid place-items-center rounded-full transition-colors\",\n          isConnecting && \"bg-background text-background inset-0.5\",\n          isDestructive && \"bg-destructive text-white\"\n        )}\n      >\n        {isConnecting ? null : isError ? (\n          // The spinning ring is the connecting signal; skip a centred glyph\n          // so it reads as a clean spinner rather than a flashing X.\n          <XIcon className=\"size-5\" aria-hidden=\"true\" />\n        ) : isActive ? (\n          // Crossed-out phone on the solid destructive disc signals\n          // \"click to end the call\".\n          <PhoneOffIcon className=\"size-5\" aria-hidden=\"true\" />\n        ) : showLogo ? (\n          // eslint-disable-next-line @next/next/no-img-element\n          <img\n            src={logo}\n            alt={altText}\n            className=\"size-6 rounded-sm object-contain\"\n            referrerPolicy=\"no-referrer\"\n            onError={() => setLogoFailed(true)}\n          />\n        ) : (\n          // Pick black vs white based on the user-set brand color so the\n          // icon stays readable across a bright yellow, deep navy, etc.\n          <AudioLinesIcon\n            className=\"text-background size-5\"\n            aria-hidden=\"true\"\n            style={\n              color\n                ? {\n                    color: `contrast-color(${color})`,\n                  }\n                : undefined\n            }\n          />\n        )}\n      </div>\n    </Button>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/LICENSE",
          "target": "@components/voice-agents/livekit/LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/voice-agents/livekit/SOURCE.json",
          "target": "@components/voice-agents/livekit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"LiveKit Agents UI\",\n  \"repository\": \"https://github.com/livekit/components-js\",\n  \"revision\": \"20aa613fcab699385fe7385d0bf31a9262210421\",\n  \"license\": \"Apache-2.0 with an MIT file-level exception\",\n  \"sourceRoot\": \"packages/shadcn\",\n  \"components\": [\n    {\n      \"name\": \"agent-disconnect-button\",\n      \"path\": \"agent-disconnect-button.tsx\",\n      \"title\": \"Agent Disconnect Button\"\n    },\n    {\n      \"name\": \"agent-track-toggle\",\n      \"path\": \"agent-track-toggle.tsx\",\n      \"title\": \"Agent Track Toggle\"\n    },\n    {\n      \"name\": \"agent-track-control\",\n      \"path\": \"agent-track-control.tsx\",\n      \"title\": \"Agent Track Control\"\n    },\n    {\n      \"name\": \"agent-control-bar\",\n      \"path\": \"agent-control-bar.tsx\",\n      \"title\": \"Agent Control Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-bar\",\n      \"path\": \"agent-audio-visualizer-bar.tsx\",\n      \"title\": \"Agent Audio Visualizer Bar\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-radial\",\n      \"path\": \"agent-audio-visualizer-radial.tsx\",\n      \"title\": \"Agent Audio Visualizer Radial\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-grid\",\n      \"path\": \"agent-audio-visualizer-grid.tsx\",\n      \"title\": \"Agent Audio Visualizer Grid\"\n    },\n    {\n      \"name\": \"agent-session-provider\",\n      \"path\": \"agent-session-provider.tsx\",\n      \"title\": \"Agent Session Provider\"\n    },\n    {\n      \"name\": \"start-audio-button\",\n      \"path\": \"start-audio-button.tsx\",\n      \"title\": \"Start Audio Button\"\n    },\n    {\n      \"name\": \"agent-chat-indicator\",\n      \"path\": \"agent-chat-indicator.tsx\",\n      \"title\": \"Agent Chat Indicator\"\n    },\n    {\n      \"name\": \"agent-chat-transcript\",\n      \"path\": \"agent-chat-transcript.tsx\",\n      \"title\": \"Agent Chat Transcript\"\n    },\n    {\n      \"name\": \"react-shader-toy\",\n      \"path\": \"react-shader-toy.tsx\",\n      \"title\": \"React Shader Toy\"\n    },\n    {\n      \"name\": \"agent-audio-visualizer-wave\",\n      \"path\": \"agent-audio-visualizer-wave.tsx\",\n      \"title\": \"Agent Audio Visualizer Wave\"\n    },\n    {\n      \"name\": \"agent-session-view-01\",\n      \"path\": \"blocks/agent-session-view-01/components/agent-session-block.tsx\",\n      \"title\": \"Agent Session View\"\n    },\n    {\n      \"name\": \"agent-popup-01\",\n      \"path\": \"blocks/agent-popup-01/components/agent-popup-block.tsx\",\n      \"title\": \"Agent Popup\"\n    }\n  ],\n  \"changes\": [\n    \"Rewritten local imports into components/voice-agents/livekit.\",\n    \"Bundled the registry UI dependency closure locally; MessageScroller uses an equivalent native scroll implementation because @shadcn/react is not a project dependency.\",\n    \"ReactShaderToy caps device pixel ratio at 2, pauses while off-screen, and renders a static frame when reduced motion is requested.\",\n    \"Bar, radial, grid, wave, and chat-indicator animation loops stop or resolve to a static state when reduced motion is requested.\",\n    \"Gallery previews use explicit offline state and volume overrides and never create a fake LiveKit room or start audio capture.\",\n    \"Marked hook-based public entry points as client components for direct Next.js App Router imports.\",\n    \"Replaced the popup trigger robot glyph with a contextual Lucide audio-lines icon.\"\n  ],\n  \"fileLevelLicenses\": {\n    \"react-shader-toy.tsx\": \"MIT\"\n  },\n  \"excluded\": [\n    {\n      \"name\": \"agent-audio-visualizer-aura\",\n      \"reason\": \"Upstream file is licensed under PolyForm Non-Resale 1.0.0, so it is not included in this distributable kit.\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/livekit/NOTICE",
          "target": "@components/voice-agents/livekit/NOTICE",
          "type": "registry:file",
          "content": "Copyright 2023 LiveKit, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis product includes code from react-shaders (https://github.com/rysana-ai/react-shaders)\n\n   Copyright (c) 2018 Morgan Villedieu\n   Copyright (c) 2023 Rysana, Inc. (forked from the above)\n\nLicensed under the MIT License\n"
        }
      ],
      "categories": [
        "LiveKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-audio-player",
      "type": "registry:block",
      "title": "Elevenlabs Audio Player",
      "description": "Audio Player",
      "dependencies": [
        "@radix-ui/react-dropdown-menu@^2.1.14",
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/audio-player.tsx",
          "target": "@components/voice-agents/elevenlabs/audio-player.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { cn } from \"@/lib/utils\"\nimport { Check, PauseIcon, PlayIcon, Settings } from \"lucide-react\"\nimport { Slider as SliderPrimitive } from \"radix-ui\"\nimport {\n  ComponentProps,\n  createContext,\n  HTMLProps,\n  ReactNode,\n  RefObject,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\nenum ReadyState {\n  HAVE_NOTHING = 0,\n  HAVE_METADATA = 1,\n  HAVE_CURRENT_DATA = 2,\n  HAVE_FUTURE_DATA = 3,\n  HAVE_ENOUGH_DATA = 4,\n}\n\nenum NetworkState {\n  NETWORK_EMPTY = 0,\n  NETWORK_IDLE = 1,\n  NETWORK_LOADING = 2,\n  NETWORK_NO_SOURCE = 3,\n}\n\nfunction formatTime(seconds: number) {\n  const hrs = Math.floor(seconds / 3600)\n  const mins = Math.floor((seconds % 3600) / 60)\n  const secs = Math.floor(seconds % 60)\n\n  const formattedMins = mins < 10 ? `0${mins}` : mins\n  const formattedSecs = secs < 10 ? `0${secs}` : secs\n\n  return hrs > 0\n    ? `${hrs}:${formattedMins}:${formattedSecs}`\n    : `${mins}:${formattedSecs}`\n}\n\ninterface AudioPlayerItem<TData = unknown> {\n  id: string | number\n  src: string\n  data?: TData\n}\n\ninterface AudioPlayerApi<TData = unknown> {\n  ref: RefObject<HTMLAudioElement | null>\n  activeItem: AudioPlayerItem<TData> | null\n  duration: number | undefined\n  error: MediaError | null\n  isPlaying: boolean\n  isBuffering: boolean\n  playbackRate: number\n  isItemActive: (id: string | number | null) => boolean\n  setActiveItem: (item: AudioPlayerItem<TData> | null) => Promise<void>\n  play: (item?: AudioPlayerItem<TData> | null) => Promise<void>\n  pause: () => void\n  seek: (time: number) => void\n  setPlaybackRate: (rate: number) => void\n}\n\nconst AudioPlayerContext = createContext<AudioPlayerApi<unknown> | null>(null)\n\nexport function useAudioPlayer<TData = unknown>(): AudioPlayerApi<TData> {\n  const api = useContext(AudioPlayerContext) as AudioPlayerApi<TData> | null\n  if (!api) {\n    throw new Error(\n      \"useAudioPlayer cannot be called outside of AudioPlayerProvider\"\n    )\n  }\n  return api\n}\n\nconst AudioPlayerTimeContext = createContext<number | null>(null)\n\nexport const useAudioPlayerTime = () => {\n  const time = useContext(AudioPlayerTimeContext)\n  if (time === null) {\n    throw new Error(\n      \"useAudioPlayerTime cannot be called outside of AudioPlayerProvider\"\n    )\n  }\n  return time\n}\n\nexport function AudioPlayerProvider<TData = unknown>({\n  children,\n}: {\n  children: ReactNode\n}) {\n  const audioRef = useRef<HTMLAudioElement>(null)\n  const itemRef = useRef<AudioPlayerItem<TData> | null>(null)\n  const playPromiseRef = useRef<Promise<void> | null>(null)\n  const [readyState, setReadyState] = useState<number>(0)\n  const [networkState, setNetworkState] = useState<number>(0)\n  const [time, setTime] = useState<number>(0)\n  const [duration, setDuration] = useState<number | undefined>(undefined)\n  const [error, setError] = useState<MediaError | null>(null)\n  const [activeItem, _setActiveItem] = useState<AudioPlayerItem<TData> | null>(\n    null\n  )\n  const [paused, setPaused] = useState(true)\n  const [playbackRate, setPlaybackRateState] = useState<number>(1)\n\n  const setActiveItem = useCallback(\n    async (item: AudioPlayerItem<TData> | null) => {\n      if (!audioRef.current) return\n\n      if (item?.id === itemRef.current?.id) {\n        return\n      }\n      itemRef.current = item\n      const currentRate = audioRef.current.playbackRate\n      audioRef.current.pause()\n      audioRef.current.currentTime = 0\n      if (item === null) {\n        audioRef.current.removeAttribute(\"src\")\n      } else {\n        audioRef.current.src = item.src\n      }\n      audioRef.current.load()\n      audioRef.current.playbackRate = currentRate\n    },\n    []\n  )\n\n  const play = useCallback(\n    async (item?: AudioPlayerItem<TData> | null) => {\n      if (!audioRef.current) return\n\n      if (playPromiseRef.current) {\n        try {\n          await playPromiseRef.current\n        } catch (error) {\n          console.error(\"Play promise error:\", error)\n        }\n      }\n\n      if (item === undefined) {\n        const playPromise = audioRef.current.play()\n        playPromiseRef.current = playPromise\n        return playPromise\n      }\n      if (item?.id === activeItem?.id) {\n        const playPromise = audioRef.current.play()\n        playPromiseRef.current = playPromise\n        return playPromise\n      }\n\n      itemRef.current = item\n      const currentRate = audioRef.current.playbackRate\n      if (!audioRef.current.paused) {\n        audioRef.current.pause()\n      }\n      audioRef.current.currentTime = 0\n      if (item === null) {\n        audioRef.current.removeAttribute(\"src\")\n      } else {\n        audioRef.current.src = item.src\n      }\n      audioRef.current.load()\n      audioRef.current.playbackRate = currentRate\n      const playPromise = audioRef.current.play()\n      playPromiseRef.current = playPromise\n      return playPromise\n    },\n    [activeItem]\n  )\n\n  const pause = useCallback(async () => {\n    if (!audioRef.current) return\n\n    if (playPromiseRef.current) {\n      try {\n        await playPromiseRef.current\n      } catch (e) {\n        console.error(e)\n      }\n    }\n\n    audioRef.current.pause()\n    playPromiseRef.current = null\n  }, [])\n\n  const seek = useCallback((time: number) => {\n    if (!audioRef.current) return\n    audioRef.current.currentTime = time\n  }, [])\n\n  const setPlaybackRate = useCallback((rate: number) => {\n    if (!audioRef.current) return\n    audioRef.current.playbackRate = rate\n    setPlaybackRateState(rate)\n  }, [])\n\n  const isItemActive = useCallback(\n    (id: string | number | null) => {\n      return activeItem?.id === id\n    },\n    [activeItem]\n  )\n\n  useAnimationFrame(() => {\n    if (audioRef.current) {\n      _setActiveItem(itemRef.current)\n      setReadyState(audioRef.current.readyState)\n      setNetworkState(audioRef.current.networkState)\n      setTime(audioRef.current.currentTime)\n      setDuration(audioRef.current.duration)\n      setPaused(audioRef.current.paused)\n      setError(audioRef.current.error)\n      setPlaybackRateState(audioRef.current.playbackRate)\n    }\n  })\n\n  const isPlaying = !paused\n  const isBuffering =\n    readyState < ReadyState.HAVE_FUTURE_DATA &&\n    networkState === NetworkState.NETWORK_LOADING\n\n  const api = useMemo<AudioPlayerApi<TData>>(\n    () => ({\n      ref: audioRef,\n      duration,\n      error,\n      isPlaying,\n      isBuffering,\n      activeItem,\n      playbackRate,\n      isItemActive,\n      setActiveItem,\n      play,\n      pause,\n      seek,\n      setPlaybackRate,\n    }),\n    [\n      audioRef,\n      duration,\n      error,\n      isPlaying,\n      isBuffering,\n      activeItem,\n      playbackRate,\n      isItemActive,\n      setActiveItem,\n      play,\n      pause,\n      seek,\n      setPlaybackRate,\n    ]\n  )\n\n  return (\n    <AudioPlayerContext.Provider value={api as AudioPlayerApi<unknown>}>\n      <AudioPlayerTimeContext.Provider value={time}>\n        <audio ref={audioRef} className=\"hidden\" crossOrigin=\"anonymous\" />\n        {children}\n      </AudioPlayerTimeContext.Provider>\n    </AudioPlayerContext.Provider>\n  )\n}\n\nexport const AudioPlayerProgress = ({\n  ...otherProps\n}: Omit<\n  ComponentProps<typeof SliderPrimitive.Root>,\n  \"min\" | \"max\" | \"value\"\n>) => {\n  const player = useAudioPlayer()\n  const time = useAudioPlayerTime()\n  const wasPlayingRef = useRef(false)\n\n  return (\n    <SliderPrimitive.Root\n      {...otherProps}\n      value={[time]}\n      onValueChange={(vals) => {\n        player.seek(vals[0])\n        otherProps.onValueChange?.(vals)\n      }}\n      min={0}\n      max={player.duration ?? 0}\n      step={otherProps.step || 0.25}\n      onPointerDown={(e) => {\n        wasPlayingRef.current = player.isPlaying\n        player.pause()\n        otherProps.onPointerDown?.(e)\n      }}\n      onPointerUp={(e) => {\n        if (wasPlayingRef.current) {\n          player.play()\n        }\n        otherProps.onPointerUp?.(e)\n      }}\n      className={cn(\n        \"group/player relative flex h-4 touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col\",\n        otherProps.className\n      )}\n      onKeyDown={(e) => {\n        if (e.key === \" \") {\n          e.preventDefault()\n          if (!player.isPlaying) {\n            player.play()\n          } else {\n            player.pause()\n          }\n        }\n        otherProps.onKeyDown?.(e)\n      }}\n      disabled={\n        player.duration === undefined ||\n        !Number.isFinite(player.duration) ||\n        Number.isNaN(player.duration)\n      }\n    >\n      <SliderPrimitive.Track className=\"bg-muted relative h-[4px] w-full grow overflow-hidden rounded-full\">\n        <SliderPrimitive.Range className=\"bg-primary absolute h-full\" />\n      </SliderPrimitive.Track>\n      <SliderPrimitive.Thumb\n        className=\"relative flex h-0 w-0 items-center justify-center opacity-0 group-hover/player:opacity-100 focus-visible:opacity-100 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50\"\n        data-slot=\"slider-thumb\"\n      >\n        <div className=\"bg-foreground absolute size-3 rounded-full\" />\n      </SliderPrimitive.Thumb>\n    </SliderPrimitive.Root>\n  )\n}\n\nexport const AudioPlayerTime = ({\n  className,\n  ...otherProps\n}: HTMLProps<HTMLSpanElement>) => {\n  const time = useAudioPlayerTime()\n  return (\n    <span\n      {...otherProps}\n      className={cn(\"text-muted-foreground text-sm tabular-nums\", className)}\n    >\n      {formatTime(time)}\n    </span>\n  )\n}\n\nexport const AudioPlayerDuration = ({\n  className,\n  ...otherProps\n}: HTMLProps<HTMLSpanElement>) => {\n  const player = useAudioPlayer()\n  return (\n    <span\n      {...otherProps}\n      className={cn(\"text-muted-foreground text-sm tabular-nums\", className)}\n    >\n      {player.duration !== null &&\n      player.duration !== undefined &&\n      !Number.isNaN(player.duration)\n        ? formatTime(player.duration)\n        : \"--:--\"}\n    </span>\n  )\n}\n\ninterface SpinnerProps {\n  className?: string\n}\n\nfunction Spinner({ className }: SpinnerProps) {\n  return (\n    <div\n      className={cn(\n        \"border-muted border-t-foreground size-3.5 animate-spin rounded-full border-2\",\n        className\n      )}\n      role=\"status\"\n      aria-label=\"Loading\"\n    >\n      <span className=\"sr-only\">Loading...</span>\n    </div>\n  )\n}\n\ninterface PlayButtonProps extends React.ComponentProps<typeof Button> {\n  playing: boolean\n  onPlayingChange: (playing: boolean) => void\n  loading?: boolean\n}\n\nconst PlayButton = ({\n  playing,\n  onPlayingChange,\n  className,\n  onClick,\n  loading,\n  ...otherProps\n}: PlayButtonProps) => {\n  return (\n    <Button\n      {...otherProps}\n      onClick={(e) => {\n        onPlayingChange(!playing)\n        onClick?.(e)\n      }}\n      className={cn(\"relative\", className)}\n      aria-label={playing ? \"Pause\" : \"Play\"}\n      type=\"button\"\n    >\n      {playing ? (\n        <PauseIcon\n          className={cn(\"size-4\", loading && \"opacity-0\")}\n          aria-hidden=\"true\"\n        />\n      ) : (\n        <PlayIcon\n          className={cn(\"size-4\", loading && \"opacity-0\")}\n          aria-hidden=\"true\"\n        />\n      )}\n      {loading && (\n        <div className=\"absolute inset-0 flex items-center justify-center rounded-[inherit] backdrop-blur-xs\">\n          <Spinner />\n        </div>\n      )}\n    </Button>\n  )\n}\n\nexport interface AudioPlayerButtonProps<TData = unknown>\n  extends React.ComponentProps<typeof Button> {\n  item?: AudioPlayerItem<TData>\n}\n\nexport function AudioPlayerButton<TData = unknown>({\n  item,\n  ...otherProps\n}: AudioPlayerButtonProps<TData>) {\n  const player = useAudioPlayer<TData>()\n\n  if (!item) {\n    return (\n      <PlayButton\n        {...otherProps}\n        playing={player.isPlaying}\n        onPlayingChange={(shouldPlay) => {\n          if (shouldPlay) {\n            player.play()\n          } else {\n            player.pause()\n          }\n        }}\n        loading={player.isBuffering && player.isPlaying}\n      />\n    )\n  }\n\n  return (\n    <PlayButton\n      {...otherProps}\n      playing={player.isItemActive(item.id) && player.isPlaying}\n      onPlayingChange={(shouldPlay) => {\n        if (shouldPlay) {\n          player.play(item)\n        } else {\n          player.pause()\n        }\n      }}\n      loading={\n        player.isItemActive(item.id) && player.isBuffering && player.isPlaying\n      }\n    />\n  )\n}\n\ntype Callback = (delta: number) => void\n\nfunction useAnimationFrame(callback: Callback) {\n  const requestRef = useRef<number | null>(null)\n  const previousTimeRef = useRef<number | null>(null)\n  const callbackRef = useRef<Callback>(callback)\n\n  useEffect(() => {\n    callbackRef.current = callback\n  }, [callback])\n\n  useEffect(() => {\n    const animate = (time: number) => {\n      if (previousTimeRef.current !== null) {\n        const delta = time - previousTimeRef.current\n        callbackRef.current(delta)\n      }\n      previousTimeRef.current = time\n      requestRef.current = requestAnimationFrame(animate)\n    }\n\n    requestRef.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (requestRef.current) cancelAnimationFrame(requestRef.current)\n      previousTimeRef.current = null\n    }\n  }, [])\n}\n\nconst PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] as const\n\nexport interface AudioPlayerSpeedProps\n  extends React.ComponentProps<typeof Button> {\n  speeds?: readonly number[]\n}\n\nexport function AudioPlayerSpeed({\n  speeds = PLAYBACK_SPEEDS,\n  className,\n  variant = \"ghost\",\n  size = \"icon\",\n  ...props\n}: AudioPlayerSpeedProps) {\n  const player = useAudioPlayer()\n  const currentSpeed = player.playbackRate\n\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          variant={variant}\n          size={size}\n          className={cn(className)}\n          aria-label=\"Playback speed\"\n          {...props}\n        >\n          <Settings className=\"size-4\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent align=\"end\" className=\"min-w-[120px]\">\n        {speeds.map((speed) => (\n          <DropdownMenuItem\n            key={speed}\n            onClick={() => player.setPlaybackRate(speed)}\n            className=\"flex items-center justify-between\"\n          >\n            <span className={speed === 1 ? \"\" : \"font-mono\"}>\n              {speed === 1 ? \"Normal\" : `${speed}x`}\n            </span>\n            {currentSpeed === speed && <Check className=\"size-4\" />}\n          </DropdownMenuItem>\n        ))}\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n\nexport interface AudioPlayerSpeedButtonGroupProps\n  extends Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> {\n  speeds?: readonly number[]\n}\n\nexport function AudioPlayerSpeedButtonGroup({\n  speeds = [0.5, 1, 1.5, 2],\n  className,\n  ...props\n}: AudioPlayerSpeedButtonGroupProps) {\n  const player = useAudioPlayer()\n  const currentSpeed = player.playbackRate\n\n  return (\n    <div\n      className={cn(\"flex items-center gap-1\", className)}\n      role=\"group\"\n      aria-label=\"Playback speed controls\"\n      {...props}\n    >\n      {speeds.map((speed) => (\n        <Button\n          key={speed}\n          variant={currentSpeed === speed ? \"default\" : \"outline\"}\n          size=\"sm\"\n          onClick={() => player.setPlaybackRate(speed)}\n          className=\"min-w-[50px] font-mono text-xs\"\n        >\n          {speed}x\n        </Button>\n      ))}\n    </div>\n  )\n}\n\nexport const exampleTracks = [\n  {\n    id: \"0\",\n    name: \"II - 00\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/00.mp3\",\n  },\n  {\n    id: \"1\",\n    name: \"II - 01\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/01.mp3\",\n  },\n  {\n    id: \"2\",\n    name: \"II - 02\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/02.mp3\",\n  },\n  {\n    id: \"3\",\n    name: \"II - 03\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/03.mp3\",\n  },\n  {\n    id: \"4\",\n    name: \"II - 04\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/04.mp3\",\n  },\n  {\n    id: \"5\",\n    name: \"II - 05\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/05.mp3\",\n  },\n  {\n    id: \"6\",\n    name: \"II - 06\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/06.mp3\",\n  },\n  {\n    id: \"7\",\n    name: \"II - 07\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/07.mp3\",\n  },\n  {\n    id: \"8\",\n    name: \"II - 08\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/08.mp3\",\n  },\n  {\n    id: \"9\",\n    name: \"II - 09\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/09.mp3\",\n  },\n]\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/dropdown-menu.tsx",
          "target": "@components/ui/dropdown-menu.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction DropdownMenu({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  return (\n    <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n  )\n}\n\nfunction DropdownMenuTrigger({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-md\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return (\n    <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return (\n    <DropdownMenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CircleIcon className=\"size-2 fill-current\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-semibold data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPrimitive.SubContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-bar-visualizer",
      "type": "registry:block",
      "title": "Elevenlabs Bar Visualizer",
      "description": "Bar Visualizer",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/bar-visualizer.tsx",
          "target": "@components/voice-agents/elevenlabs/bar-visualizer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport {\n  forwardRef,\n  memo,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n  type HTMLAttributes,\n} from \"react\"\n\nexport interface AudioAnalyserOptions {\n  fftSize?: number\n  smoothingTimeConstant?: number\n  minDecibels?: number\n  maxDecibels?: number\n}\n\nfunction createAudioAnalyser(\n  mediaStream: MediaStream,\n  options: AudioAnalyserOptions = {}\n) {\n  const audioContext = new (window.AudioContext ||\n    (window as unknown as { webkitAudioContext: typeof AudioContext })\n      .webkitAudioContext)()\n  const source = audioContext.createMediaStreamSource(mediaStream)\n  const analyser = audioContext.createAnalyser()\n\n  if (options.fftSize) analyser.fftSize = options.fftSize\n  if (options.smoothingTimeConstant !== undefined) {\n    analyser.smoothingTimeConstant = options.smoothingTimeConstant\n  }\n  if (options.minDecibels !== undefined)\n    analyser.minDecibels = options.minDecibels\n  if (options.maxDecibels !== undefined)\n    analyser.maxDecibels = options.maxDecibels\n\n  source.connect(analyser)\n\n  const cleanup = () => {\n    source.disconnect()\n    audioContext.close()\n  }\n\n  return { analyser, audioContext, cleanup }\n}\n\n/**\n * Hook for tracking the volume of an audio stream using the Web Audio API.\n * @param mediaStream - The MediaStream to analyze\n * @param options - Audio analyser options\n * @returns The current volume level (0-1)\n */\nexport function useAudioVolume(\n  mediaStream?: MediaStream | null,\n  options: AudioAnalyserOptions = { fftSize: 32, smoothingTimeConstant: 0 }\n) {\n  const [volume, setVolume] = useState(0)\n  const volumeRef = useRef(0)\n  const frameId = useRef<number | undefined>(undefined)\n  const { fftSize, smoothingTimeConstant, minDecibels, maxDecibels } = options\n\n  // Memoize options to prevent unnecessary re-renders\n  const memoizedOptions = useMemo(\n    () => ({ fftSize, smoothingTimeConstant, minDecibels, maxDecibels }),\n    [fftSize, smoothingTimeConstant, minDecibels, maxDecibels]\n  )\n\n  useEffect(() => {\n    if (!mediaStream) {\n      setVolume(0)\n      volumeRef.current = 0\n      return\n    }\n\n    const { analyser, cleanup } = createAudioAnalyser(\n      mediaStream,\n      memoizedOptions\n    )\n\n    const bufferLength = analyser.frequencyBinCount\n    const dataArray = new Uint8Array(bufferLength)\n    let lastUpdate = 0\n    const updateInterval = 1000 / 30 // 30 FPS\n\n    const updateVolume = (timestamp: number) => {\n      if (timestamp - lastUpdate >= updateInterval) {\n        analyser.getByteFrequencyData(dataArray)\n        let sum = 0\n        for (let i = 0; i < dataArray.length; i++) {\n          const a = dataArray[i]\n          sum += a * a\n        }\n        const newVolume = Math.sqrt(sum / dataArray.length) / 255\n\n        // Only update state if volume changed significantly\n        if (Math.abs(newVolume - volumeRef.current) > 0.01) {\n          volumeRef.current = newVolume\n          setVolume(newVolume)\n        }\n        lastUpdate = timestamp\n      }\n      frameId.current = requestAnimationFrame(updateVolume)\n    }\n\n    frameId.current = requestAnimationFrame(updateVolume)\n\n    return () => {\n      cleanup()\n      if (frameId.current) {\n        cancelAnimationFrame(frameId.current)\n      }\n    }\n  }, [mediaStream, memoizedOptions])\n\n  return volume\n}\n\nexport interface MultiBandVolumeOptions {\n  bands?: number\n  loPass?: number // Low frequency cutoff\n  hiPass?: number // High frequency cutoff\n  updateInterval?: number // Update interval in ms\n  analyserOptions?: AudioAnalyserOptions\n}\n\nconst multibandDefaults: MultiBandVolumeOptions = {\n  bands: 5,\n  loPass: 100,\n  hiPass: 600,\n  updateInterval: 32,\n  analyserOptions: { fftSize: 2048 },\n}\n\n// Memoized normalization function to avoid recreating on each render\nconst normalizeDb = (value: number) => {\n  if (value === -Infinity) return 0\n  const minDb = -100\n  const maxDb = -10\n  const db = 1 - (Math.max(minDb, Math.min(maxDb, value)) * -1) / 100\n  return Math.sqrt(db)\n}\n\n/**\n * Hook for tracking volume across multiple frequency bands\n * @param mediaStream - The MediaStream to analyze\n * @param options - Multiband options\n * @returns Array of volume levels for each frequency band\n */\nexport function useMultibandVolume(\n  mediaStream?: MediaStream | null,\n  options: MultiBandVolumeOptions = {}\n) {\n  const { bands, loPass, hiPass, updateInterval, analyserOptions } = options\n  const hasAnalyserOptions = analyserOptions !== undefined\n  const { fftSize, smoothingTimeConstant, minDecibels, maxDecibels } =\n    analyserOptions ?? {}\n  const opts = useMemo(\n    () => ({\n      ...multibandDefaults,\n      bands,\n      loPass,\n      hiPass,\n      updateInterval,\n      analyserOptions: hasAnalyserOptions\n        ? { fftSize, smoothingTimeConstant, minDecibels, maxDecibels }\n        : undefined,\n    }),\n    [\n      bands,\n      loPass,\n      hiPass,\n      updateInterval,\n      hasAnalyserOptions,\n      fftSize,\n      smoothingTimeConstant,\n      minDecibels,\n      maxDecibels,\n    ]\n  )\n\n  const [frequencyBands, setFrequencyBands] = useState<number[]>(() =>\n    new Array(opts.bands).fill(0)\n  )\n  const bandsRef = useRef<number[]>(new Array(opts.bands).fill(0))\n  const frameId = useRef<number | undefined>(undefined)\n\n  useEffect(() => {\n    if (!mediaStream) {\n      const emptyBands = new Array(opts.bands).fill(0)\n      setFrequencyBands(emptyBands)\n      bandsRef.current = emptyBands\n      return\n    }\n\n    const { analyser, cleanup } = createAudioAnalyser(\n      mediaStream,\n      opts.analyserOptions\n    )\n\n    const bufferLength = analyser.frequencyBinCount\n    const dataArray = new Float32Array(bufferLength)\n    const sliceStart = opts.loPass!\n    const sliceEnd = opts.hiPass!\n    const sliceLength = sliceEnd - sliceStart\n    const chunkSize = Math.ceil(sliceLength / opts.bands!)\n\n    let lastUpdate = 0\n    const updateInterval = opts.updateInterval!\n\n    const updateVolume = (timestamp: number) => {\n      if (timestamp - lastUpdate >= updateInterval) {\n        analyser.getFloatFrequencyData(dataArray)\n\n        // Process directly without creating intermediate arrays\n        const chunks = new Array(opts.bands!)\n\n        for (let i = 0; i < opts.bands!; i++) {\n          let sum = 0\n          let count = 0\n          const startIdx = sliceStart + i * chunkSize\n          const endIdx = Math.min(sliceStart + (i + 1) * chunkSize, sliceEnd)\n\n          for (let j = startIdx; j < endIdx; j++) {\n            sum += normalizeDb(dataArray[j])\n            count++\n          }\n\n          chunks[i] = count > 0 ? sum / count : 0\n        }\n\n        // Only update state if bands changed significantly\n        let hasChanged = false\n        for (let i = 0; i < chunks.length; i++) {\n          if (Math.abs(chunks[i] - bandsRef.current[i]) > 0.01) {\n            hasChanged = true\n            break\n          }\n        }\n\n        if (hasChanged) {\n          bandsRef.current = chunks\n          setFrequencyBands(chunks)\n        }\n\n        lastUpdate = timestamp\n      }\n\n      frameId.current = requestAnimationFrame(updateVolume)\n    }\n\n    frameId.current = requestAnimationFrame(updateVolume)\n\n    return () => {\n      cleanup()\n      if (frameId.current) {\n        cancelAnimationFrame(frameId.current)\n      }\n    }\n  }, [mediaStream, opts])\n\n  return frequencyBands\n}\n\ntype AnimationState =\n  | \"connecting\"\n  | \"initializing\"\n  | \"listening\"\n  | \"speaking\"\n  | \"thinking\"\n  | undefined\n\nexport const useBarAnimator = (\n  state: AnimationState,\n  columns: number,\n  interval: number\n): number[] => {\n  const indexRef = useRef(0)\n  const [currentFrame, setCurrentFrame] = useState<number[]>([])\n  const animationFrameId = useRef<number | null>(null)\n\n  // Memoize sequence generation\n  const sequence = useMemo(() => {\n    if (state === \"thinking\" || state === \"listening\") {\n      return generateListeningSequenceBar(columns)\n    } else if (state === \"connecting\" || state === \"initializing\") {\n      return generateConnectingSequenceBar(columns)\n    } else if (state === undefined || state === \"speaking\") {\n      return [new Array(columns).fill(0).map((_, idx) => idx)]\n    } else {\n      return [[]]\n    }\n  }, [state, columns])\n\n  useEffect(() => {\n    indexRef.current = 0\n    setCurrentFrame(sequence[0] || [])\n  }, [sequence])\n\n  useEffect(() => {\n    let startTime = performance.now()\n\n    const animate = (time: DOMHighResTimeStamp) => {\n      const timeElapsed = time - startTime\n\n      if (timeElapsed >= interval) {\n        indexRef.current = (indexRef.current + 1) % sequence.length\n        setCurrentFrame(sequence[indexRef.current] || [])\n        startTime = time\n      }\n\n      animationFrameId.current = requestAnimationFrame(animate)\n    }\n\n    animationFrameId.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationFrameId.current !== null) {\n        cancelAnimationFrame(animationFrameId.current)\n      }\n    }\n  }, [interval, sequence])\n\n  return currentFrame\n}\n\n// Memoize sequence generators\nconst generateConnectingSequenceBar = (columns: number): number[][] => {\n  const seq = []\n  for (let x = 0; x < columns; x++) {\n    seq.push([x, columns - 1 - x])\n  }\n  return seq\n}\n\nconst generateListeningSequenceBar = (columns: number): number[][] => {\n  const center = Math.floor(columns / 2)\n  const noIndex = -1\n  return [[center], [noIndex]]\n}\n\nexport type AgentState =\n  | \"connecting\"\n  | \"initializing\"\n  | \"listening\"\n  | \"speaking\"\n  | \"thinking\"\n\nexport interface BarVisualizerProps extends HTMLAttributes<HTMLDivElement> {\n  /** Voice assistant state */\n  state?: AgentState\n  /** Number of bars to display */\n  barCount?: number\n  /** Audio source */\n  mediaStream?: MediaStream | null\n  /** Min/max height as percentage */\n  minHeight?: number\n  maxHeight?: number\n  /** Enable demo mode with fake audio data */\n  demo?: boolean\n  /** Align bars from center instead of bottom */\n  centerAlign?: boolean\n}\n\nconst BarVisualizerComponent = forwardRef<HTMLDivElement, BarVisualizerProps>(\n  (\n    {\n      state,\n      barCount = 15,\n      mediaStream,\n      minHeight = 20,\n      maxHeight = 100,\n      demo = false,\n      centerAlign = false,\n      className,\n      style,\n      ...props\n    },\n    ref\n  ) => {\n    // Audio processing\n    const realVolumeBands = useMultibandVolume(mediaStream, {\n      bands: barCount,\n      loPass: 100,\n      hiPass: 200,\n    })\n\n    // Generate fake volume data for demo mode using refs to avoid state updates\n    const fakeVolumeBandsRef = useRef<number[]>(new Array(barCount).fill(0.2))\n    const [fakeVolumeBands, setFakeVolumeBands] = useState<number[]>(() =>\n      new Array(barCount).fill(0.2)\n    )\n    const fakeAnimationRef = useRef<number | undefined>(undefined)\n\n    // Animate fake volume bands for speaking and listening states\n    useEffect(() => {\n      if (!demo) return\n      if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) {\n        const bands = new Array(barCount).fill(0.2)\n        fakeVolumeBandsRef.current = bands\n        setFakeVolumeBands(bands)\n        return\n      }\n\n      if (state !== \"speaking\" && state !== \"listening\") {\n        const bands = new Array(barCount).fill(0.2)\n        fakeVolumeBandsRef.current = bands\n        setFakeVolumeBands(bands)\n        return\n      }\n\n      let lastUpdate = 0\n      const updateInterval = 50\n      const startTime = Date.now() / 1000\n\n      const updateFakeVolume = (timestamp: number) => {\n        if (timestamp - lastUpdate >= updateInterval) {\n          const time = Date.now() / 1000 - startTime\n          const newBands = new Array(barCount)\n\n          for (let i = 0; i < barCount; i++) {\n            const waveOffset = i * 0.5\n            const baseVolume = Math.sin(time * 2 + waveOffset) * 0.3 + 0.5\n            const randomNoise = Math.random() * 0.2\n            newBands[i] = Math.max(0.1, Math.min(1, baseVolume + randomNoise))\n          }\n\n          // Only update if values changed significantly\n          let hasChanged = false\n          for (let i = 0; i < barCount; i++) {\n            if (Math.abs(newBands[i] - fakeVolumeBandsRef.current[i]) > 0.05) {\n              hasChanged = true\n              break\n            }\n          }\n\n          if (hasChanged) {\n            fakeVolumeBandsRef.current = newBands\n            setFakeVolumeBands(newBands)\n          }\n\n          lastUpdate = timestamp\n        }\n\n        fakeAnimationRef.current = requestAnimationFrame(updateFakeVolume)\n      }\n\n      fakeAnimationRef.current = requestAnimationFrame(updateFakeVolume)\n\n      return () => {\n        if (fakeAnimationRef.current) {\n          cancelAnimationFrame(fakeAnimationRef.current)\n        }\n      }\n    }, [demo, state, barCount])\n\n    // Use fake or real volume data based on demo mode\n    const volumeBands = useMemo(\n      () => (demo ? fakeVolumeBands : realVolumeBands),\n      [demo, fakeVolumeBands, realVolumeBands]\n    )\n\n    // Animation sequencing\n    const highlightedIndices = useBarAnimator(\n      state,\n      barCount,\n      state === \"connecting\"\n        ? 2000 / barCount\n        : state === \"thinking\"\n          ? 150\n          : state === \"listening\"\n            ? 500\n            : 1000\n    )\n\n    return (\n      <div\n        ref={ref}\n        data-state={state}\n        className={cn(\n          \"relative flex justify-center gap-1.5\",\n          centerAlign ? \"items-center\" : \"items-end\",\n          \"bg-muted h-32 w-full overflow-hidden rounded-lg p-4\",\n          className\n        )}\n        style={{\n          ...style,\n        }}\n        {...props}\n      >\n        {volumeBands.map((volume, index) => {\n          const heightPct = Math.min(\n            maxHeight,\n            Math.max(minHeight, volume * 100 + 5)\n          )\n          const isHighlighted = highlightedIndices?.includes(index) ?? false\n\n          return (\n            <Bar\n              key={index}\n              heightPct={heightPct}\n              isHighlighted={isHighlighted}\n              state={state}\n            />\n          )\n        })}\n      </div>\n    )\n  }\n)\n\n// Memoized Bar component to prevent unnecessary re-renders\nconst Bar = memo<{\n  heightPct: number\n  isHighlighted: boolean\n  state?: AgentState\n}>(({ heightPct, isHighlighted, state }) => (\n  <div\n    data-highlighted={isHighlighted}\n    className={cn(\n      \"max-w-[12px] min-w-[8px] flex-1 transition-all duration-150\",\n      \"rounded-full\",\n      \"bg-border data-[highlighted=true]:bg-primary\",\n      state === \"speaking\" && \"bg-primary\",\n      state === \"thinking\" && isHighlighted && \"animate-pulse\"\n    )}\n    style={{\n      height: `${heightPct}%`,\n      animationDuration: state === \"thinking\" ? \"300ms\" : undefined,\n    }}\n  />\n))\n\nBar.displayName = \"Bar\"\n\n// Wrap the main component with memo for prop comparison optimization\nconst BarVisualizer = memo(BarVisualizerComponent, (prevProps, nextProps) => {\n  return (\n    prevProps.state === nextProps.state &&\n    prevProps.barCount === nextProps.barCount &&\n    prevProps.mediaStream === nextProps.mediaStream &&\n    prevProps.minHeight === nextProps.minHeight &&\n    prevProps.maxHeight === nextProps.maxHeight &&\n    prevProps.demo === nextProps.demo &&\n    prevProps.centerAlign === nextProps.centerAlign &&\n    prevProps.className === nextProps.className &&\n    JSON.stringify(prevProps.style) === JSON.stringify(nextProps.style)\n  )\n})\n\nBarVisualizerComponent.displayName = \"BarVisualizerComponent\"\nBarVisualizer.displayName = \"BarVisualizer\"\n\nexport { BarVisualizer }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-conversation-bar",
      "type": "registry:block",
      "title": "Elevenlabs Conversation Bar",
      "description": "Conversation Bar",
      "dependencies": [
        "@elevenlabs/react@1.6.0",
        "@radix-ui/react-separator@^1.1.6",
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/conversation-bar.tsx",
          "target": "@components/voice-agents/elevenlabs/conversation-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Card } from \"@/components/ai-elements/_ui/card\"\nimport { Button } from \"@/components/ui/button\"\nimport { Separator } from \"@/components/ui/separator\"\nimport { Textarea } from \"@/components/ui/textarea\"\nimport { LiveWaveform } from \"@/components/voice-agents/elevenlabs/live-waveform\"\nimport { acquireMediaStream } from \"@/components/voice-agents/elevenlabs/media\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useConversationControls,\n  useConversationInput,\n  useConversationStatus,\n} from \"@elevenlabs/react\"\nimport {\n  ArrowUpIcon,\n  ChevronDown,\n  Keyboard,\n  Mic,\n  MicOff,\n  PhoneIcon,\n  XIcon,\n} from \"lucide-react\"\nimport * as React from \"react\"\n\nexport interface ConversationBarProps {\n  /**\n   * ElevenLabs Agent ID to connect to\n   */\n  agentId: string\n\n  /**\n   * Custom className for the container\n   */\n  className?: string\n\n  /**\n   * Custom className for the waveform\n   */\n  waveformClassName?: string\n\n  /**\n   * Callback when user sends a message\n   */\n  onSendMessage?: (message: string) => void\n  /** Disable every control and prevent media/session acquisition. */\n  disabled?: boolean\n}\n\nexport const ConversationBar = React.forwardRef<\n  HTMLDivElement,\n  ConversationBarProps\n>(({ agentId, className, waveformClassName, onSendMessage, disabled }, ref) => {\n  const { status } = useConversationStatus()\n  const { startSession, endSession, sendUserMessage, sendContextualUpdate } =\n    useConversationControls()\n  const { isMuted, setMuted } = useConversationInput()\n  const [keyboardOpen, setKeyboardOpen] = React.useState(false)\n  const [textInput, setTextInput] = React.useState(\"\")\n  const mediaStreamRef = React.useRef<MediaStream | null>(null)\n  const startRequestRef = React.useRef(0)\n\n  const isConnected = status === \"connected\"\n\n  const getMicStream = React.useCallback(async (requestId: number) => {\n    if (mediaStreamRef.current) return mediaStreamRef.current\n\n    const stream = await acquireMediaStream(\n      { audio: true },\n      () => requestId !== startRequestRef.current\n    )\n    if (!stream) return null\n    mediaStreamRef.current = stream\n\n    return stream\n  }, [])\n\n  const startConversation = React.useCallback(async () => {\n    const requestId = startRequestRef.current + 1\n    startRequestRef.current = requestId\n    try {\n      const stream = await getMicStream(requestId)\n      if (!stream || requestId !== startRequestRef.current) return\n\n      startSession({\n        agentId,\n        connectionType: \"webrtc\",\n      })\n    } catch (error) {\n      console.error(\"Error starting conversation:\", error)\n    }\n  }, [getMicStream, agentId, startSession])\n\n  const handleEndSession = React.useCallback(() => {\n    startRequestRef.current += 1\n    endSession()\n\n    if (mediaStreamRef.current) {\n      mediaStreamRef.current.getTracks().forEach((t) => t.stop())\n      mediaStreamRef.current = null\n    }\n  }, [endSession])\n\n  const toggleMute = React.useCallback(() => {\n    setMuted(!isMuted)\n  }, [isMuted, setMuted])\n\n  const handleStartOrEnd = React.useCallback(() => {\n    if (disabled) return\n    if (status === \"connected\" || status === \"connecting\") {\n      handleEndSession()\n    } else if (status === \"disconnected\" || status === \"error\") {\n      startConversation()\n    }\n  }, [disabled, status, handleEndSession, startConversation])\n\n  const handleSendText = React.useCallback(() => {\n    if (!textInput.trim()) return\n\n    const messageToSend = textInput\n    sendUserMessage(messageToSend)\n    setTextInput(\"\")\n    onSendMessage?.(messageToSend)\n  }, [sendUserMessage, textInput, onSendMessage])\n\n  const handleTextChange = React.useCallback(\n    (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n      const value = e.target.value\n      setTextInput(value)\n\n      if (value.trim() && isConnected) {\n        sendContextualUpdate(value)\n      }\n    },\n    [sendContextualUpdate, isConnected]\n  )\n\n  const handleKeyDown = React.useCallback(\n    (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n      if (e.key === \"Enter\" && !e.shiftKey) {\n        e.preventDefault()\n        handleSendText()\n      }\n    },\n    [handleSendText]\n  )\n\n  React.useEffect(() => {\n    if (!disabled) return\n    startRequestRef.current += 1\n    mediaStreamRef.current?.getTracks().forEach((track) => track.stop())\n    mediaStreamRef.current = null\n  }, [disabled])\n\n  React.useEffect(() => {\n    return () => {\n      startRequestRef.current += 1\n      if (mediaStreamRef.current) {\n        mediaStreamRef.current.getTracks().forEach((t) => t.stop())\n      }\n    }\n  }, [])\n\n  return (\n    <div\n      ref={ref}\n      className={cn(\"flex w-full items-end justify-center p-4\", className)}\n    >\n      <Card className=\"m-0 w-full gap-0 border p-0 shadow-lg\">\n        <div className=\"flex flex-col-reverse\">\n          <div>\n            {keyboardOpen && <Separator />}\n            <div className=\"flex items-center justify-between gap-2 p-2\">\n              <div className=\"h-8 w-[120px] md:h-10\">\n                <div\n                  className={cn(\n                    \"flex h-full items-center gap-2 rounded-md py-1\",\n                    \"bg-foreground/5 text-foreground/70\"\n                  )}\n                >\n                  <div className=\"h-full flex-1\">\n                    <div\n                      className={cn(\n                        \"relative flex h-full w-full shrink-0 items-center justify-center overflow-hidden rounded-sm\",\n                        waveformClassName\n                      )}\n                    >\n                      <LiveWaveform\n                        key={\n                          status === \"disconnected\" || status === \"error\"\n                            ? \"idle\"\n                            : \"active\"\n                        }\n                        active={isConnected && !isMuted && !disabled}\n                        processing={status === \"connecting\"}\n                        barWidth={3}\n                        barGap={1}\n                        barRadius={4}\n                        fadeEdges={true}\n                        fadeWidth={24}\n                        sensitivity={1.8}\n                        smoothingTimeConstant={0.85}\n                        height={20}\n                        mode=\"static\"\n                        className={cn(\n                          \"h-full w-full transition-opacity duration-300\",\n                          (status === \"disconnected\" || status === \"error\") &&\n                            \"opacity-0\"\n                        )}\n                      />\n                      {(status === \"disconnected\" || status === \"error\") && (\n                        <div className=\"absolute inset-0 flex items-center justify-center\">\n                          <span className=\"text-foreground/50 text-[10px] font-medium\">\n                            Customer Support\n                          </span>\n                        </div>\n                      )}\n                    </div>\n                  </div>\n                </div>\n              </div>\n              <div className=\"flex items-center\">\n                <Button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  onClick={toggleMute}\n                  aria-label={isMuted ? \"Unmute microphone\" : \"Mute microphone\"}\n                  aria-pressed={isMuted}\n                  className={cn(isMuted ? \"bg-foreground/5\" : \"\")}\n                  disabled={disabled || !isConnected}\n                >\n                  {isMuted ? <MicOff /> : <Mic />}\n                </Button>\n                <Button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  onClick={() => setKeyboardOpen((v) => !v)}\n                  aria-label={\n                    keyboardOpen ? \"Hide text input\" : \"Show text input\"\n                  }\n                  aria-pressed={keyboardOpen}\n                  className=\"relative\"\n                  disabled={disabled || !isConnected}\n                >\n                  <Keyboard\n                    className={\n                      \"h-5 w-5 transform-gpu transition-all duration-200 ease-[cubic-bezier(0.22,1,0.36,1)] \" +\n                      (keyboardOpen\n                        ? \"scale-75 opacity-0\"\n                        : \"scale-100 opacity-100\")\n                    }\n                  />\n                  <ChevronDown\n                    className={\n                      \"absolute inset-0 m-auto h-5 w-5 transform-gpu transition-all delay-50 duration-200 ease-[cubic-bezier(0.34,1.56,0.64,1)] \" +\n                      (keyboardOpen\n                        ? \"scale-100 opacity-100\"\n                        : \"scale-75 opacity-0\")\n                    }\n                  />\n                </Button>\n                <Separator orientation=\"vertical\" className=\"mx-1 -my-2.5\" />\n                <Button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  onClick={handleStartOrEnd}\n                  disabled={disabled}\n                  aria-label={\n                    isConnected || status === \"connecting\"\n                      ? \"End conversation\"\n                      : \"Start conversation\"\n                  }\n                >\n                  {isConnected || status === \"connecting\" ? (\n                    <XIcon className=\"h-5 w-5\" />\n                  ) : (\n                    <PhoneIcon className=\"h-5 w-5\" />\n                  )}\n                </Button>\n              </div>\n            </div>\n          </div>\n\n          <div\n            className={cn(\n              \"overflow-hidden transition-all duration-300 ease-out\",\n              keyboardOpen ? \"max-h-[120px]\" : \"max-h-0\"\n            )}\n          >\n            <div className=\"relative px-2 pt-2 pb-2\">\n              <Textarea\n                value={textInput}\n                onChange={handleTextChange}\n                onKeyDown={handleKeyDown}\n                placeholder=\"Enter your message...\"\n                className=\"min-h-[100px] resize-none border-0 pr-12 shadow-none focus-visible:ring-0\"\n                disabled={disabled || !isConnected}\n              />\n              <Button\n                size=\"icon\"\n                variant=\"ghost\"\n                onClick={handleSendText}\n                aria-label=\"Send message\"\n                disabled={disabled || !textInput.trim() || !isConnected}\n                className=\"absolute right-3 bottom-3 h-8 w-8\"\n              >\n                <ArrowUpIcon className=\"h-4 w-4\" />\n              </Button>\n            </div>\n          </div>\n        </div>\n      </Card>\n    </div>\n  )\n})\n\nConversationBar.displayName = \"ConversationBar\"\n"
        },
        {
          "path": "components/ai-elements/_ui/card.tsx",
          "target": "@components/ai-elements/_ui/card.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card\"\n      className={cn(\n        \"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-header\"\n      className={cn(\n        \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-title\"\n      className={cn(\"leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-action\"\n      className={cn(\n        \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-content\"\n      className={cn(\"px-6\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-footer\"\n      className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Card,\n  CardHeader,\n  CardFooter,\n  CardTitle,\n  CardAction,\n  CardDescription,\n  CardContent,\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ui/separator.tsx",
          "target": "@components/ui/separator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\"\nimport * as React from \"react\"\n\nfunction Separator({\n  className,\n  orientation = \"horizontal\",\n  decorative = true,\n  ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n  return (\n    <SeparatorPrimitive.Root\n      data-slot=\"separator-root\"\n      decorative={decorative}\n      orientation={orientation}\n      className={cn(\n        \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Separator }\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/live-waveform.tsx",
          "target": "@components/voice-agents/elevenlabs/live-waveform.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { acquireMediaStream } from \"@/components/voice-agents/elevenlabs/media\"\nimport { cn } from \"@/lib/utils\"\nimport { useEffect, useRef, type HTMLAttributes } from \"react\"\n\nexport type LiveWaveformProps = HTMLAttributes<HTMLDivElement> & {\n  active?: boolean\n  processing?: boolean\n  deviceId?: string\n  barWidth?: number\n  barHeight?: number\n  barGap?: number\n  barRadius?: number\n  barColor?: string\n  fadeEdges?: boolean\n  fadeWidth?: number\n  height?: string | number\n  sensitivity?: number\n  smoothingTimeConstant?: number\n  fftSize?: number\n  historySize?: number\n  updateRate?: number\n  mode?: \"scrolling\" | \"static\"\n  onError?: (error: Error) => void\n  onStreamReady?: (stream: MediaStream) => void\n  onStreamEnd?: () => void\n}\n\nexport const LiveWaveform = ({\n  active = false,\n  processing = false,\n  deviceId,\n  barWidth = 3,\n  barGap = 1,\n  barRadius = 1.5,\n  barColor,\n  fadeEdges = true,\n  fadeWidth = 24,\n  barHeight: baseBarHeight = 4,\n  height = 64,\n  sensitivity = 1,\n  smoothingTimeConstant = 0.8,\n  fftSize = 256,\n  historySize = 60,\n  updateRate = 30,\n  mode = \"static\",\n  onError,\n  onStreamReady,\n  onStreamEnd,\n  className,\n  ...props\n}: LiveWaveformProps) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const historyRef = useRef<number[]>([])\n  const analyserRef = useRef<AnalyserNode | null>(null)\n  const audioContextRef = useRef<AudioContext | null>(null)\n  const streamRef = useRef<MediaStream | null>(null)\n  const animationRef = useRef<number>(0)\n  const lastUpdateRef = useRef<number>(0)\n  const processingAnimationRef = useRef<number | null>(null)\n  const lastActiveDataRef = useRef<number[]>([])\n  const transitionProgressRef = useRef(0)\n  const staticBarsRef = useRef<number[]>([])\n  const needsRedrawRef = useRef(true)\n  const gradientCacheRef = useRef<CanvasGradient | null>(null)\n  const lastWidthRef = useRef(0)\n  const redrawRef = useRef<() => void>(() => {})\n\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n  // Handle canvas resizing\n  useEffect(() => {\n    const canvas = canvasRef.current\n    const container = containerRef.current\n    if (!canvas || !container) return\n\n    const resizeObserver = new ResizeObserver(() => {\n      const rect = container.getBoundingClientRect()\n      const dpr = window.devicePixelRatio || 1\n\n      canvas.width = rect.width * dpr\n      canvas.height = rect.height * dpr\n      canvas.style.width = `${rect.width}px`\n      canvas.style.height = `${rect.height}px`\n\n      const ctx = canvas.getContext(\"2d\")\n      if (ctx) {\n        ctx.scale(dpr, dpr)\n      }\n\n      gradientCacheRef.current = null\n      lastWidthRef.current = rect.width\n      needsRedrawRef.current = true\n      redrawRef.current()\n    })\n\n    resizeObserver.observe(container)\n    return () => resizeObserver.disconnect()\n  }, [])\n\n  useEffect(() => {\n    const reduceMotion = window.matchMedia(\n      \"(prefers-reduced-motion: reduce)\"\n    ).matches\n    if (processing && !active) {\n      let time = 0\n      transitionProgressRef.current = 0\n\n      const animateProcessing = () => {\n        time += 0.03\n        transitionProgressRef.current = Math.min(\n          1,\n          transitionProgressRef.current + 0.02\n        )\n\n        const processingData = []\n        const barCount = Math.floor(\n          (containerRef.current?.getBoundingClientRect().width || 200) /\n            (barWidth + barGap)\n        )\n\n        if (mode === \"static\") {\n          const halfCount = Math.floor(barCount / 2)\n\n          for (let i = 0; i < barCount; i++) {\n            const normalizedPosition = (i - halfCount) / halfCount\n            const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n            const wave1 = Math.sin(time * 1.5 + normalizedPosition * 3) * 0.25\n            const wave2 = Math.sin(time * 0.8 - normalizedPosition * 2) * 0.2\n            const wave3 = Math.cos(time * 2 + normalizedPosition) * 0.15\n            const combinedWave = wave1 + wave2 + wave3\n            const processingValue = (0.2 + combinedWave) * centerWeight\n\n            let finalValue = processingValue\n            if (\n              lastActiveDataRef.current.length > 0 &&\n              transitionProgressRef.current < 1\n            ) {\n              const lastDataIndex = Math.min(\n                i,\n                lastActiveDataRef.current.length - 1\n              )\n              const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n              finalValue =\n                lastValue * (1 - transitionProgressRef.current) +\n                processingValue * transitionProgressRef.current\n            }\n\n            processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n          }\n        } else {\n          for (let i = 0; i < barCount; i++) {\n            const normalizedPosition = (i - barCount / 2) / (barCount / 2)\n            const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n            const wave1 = Math.sin(time * 1.5 + i * 0.15) * 0.25\n            const wave2 = Math.sin(time * 0.8 - i * 0.1) * 0.2\n            const wave3 = Math.cos(time * 2 + i * 0.05) * 0.15\n            const combinedWave = wave1 + wave2 + wave3\n            const processingValue = (0.2 + combinedWave) * centerWeight\n\n            let finalValue = processingValue\n            if (\n              lastActiveDataRef.current.length > 0 &&\n              transitionProgressRef.current < 1\n            ) {\n              const lastDataIndex = Math.floor(\n                (i / barCount) * lastActiveDataRef.current.length\n              )\n              const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n              finalValue =\n                lastValue * (1 - transitionProgressRef.current) +\n                processingValue * transitionProgressRef.current\n            }\n\n            processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n          }\n        }\n\n        if (mode === \"static\") {\n          staticBarsRef.current = processingData\n        } else {\n          historyRef.current = processingData\n        }\n\n        needsRedrawRef.current = true\n        redrawRef.current()\n        if (!reduceMotion) {\n          processingAnimationRef.current =\n            requestAnimationFrame(animateProcessing)\n        }\n      }\n\n      animateProcessing()\n\n      return () => {\n        if (processingAnimationRef.current) {\n          cancelAnimationFrame(processingAnimationRef.current)\n        }\n      }\n    } else if (!active && !processing) {\n      const hasData =\n        mode === \"static\"\n          ? staticBarsRef.current.length > 0\n          : historyRef.current.length > 0\n\n      if (hasData) {\n        if (reduceMotion) {\n          staticBarsRef.current = []\n          historyRef.current = []\n          needsRedrawRef.current = true\n          redrawRef.current()\n          return\n        }\n        let fadeProgress = 0\n        let fadeFrame = 0\n        const fadeToIdle = () => {\n          fadeProgress += 0.03\n          if (fadeProgress < 1) {\n            if (mode === \"static\") {\n              staticBarsRef.current = staticBarsRef.current.map(\n                (value) => value * (1 - fadeProgress)\n              )\n            } else {\n              historyRef.current = historyRef.current.map(\n                (value) => value * (1 - fadeProgress)\n              )\n            }\n            needsRedrawRef.current = true\n            redrawRef.current()\n            fadeFrame = requestAnimationFrame(fadeToIdle)\n          } else {\n            if (mode === \"static\") {\n              staticBarsRef.current = []\n            } else {\n              historyRef.current = []\n            }\n          }\n        }\n        fadeToIdle()\n        return () => cancelAnimationFrame(fadeFrame)\n      }\n    }\n  }, [processing, active, barWidth, barGap, mode])\n\n  // Handle microphone setup and teardown\n  useEffect(() => {\n    let cancelled = false\n    if (!active) {\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n        streamRef.current = null\n        onStreamEnd?.()\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n        audioContextRef.current = null\n      }\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n        animationRef.current = 0\n      }\n      return\n    }\n\n    const setupMicrophone = async () => {\n      try {\n        const stream = await acquireMediaStream(\n          {\n            audio: deviceId\n              ? {\n                  deviceId: { exact: deviceId },\n                  echoCancellation: true,\n                  noiseSuppression: true,\n                  autoGainControl: true,\n                }\n              : {\n                  echoCancellation: true,\n                  noiseSuppression: true,\n                  autoGainControl: true,\n                },\n          },\n          () => cancelled\n        )\n        if (!stream) return\n        streamRef.current = stream\n        onStreamReady?.(stream)\n\n        const AudioContextConstructor =\n          window.AudioContext ||\n          (window as unknown as { webkitAudioContext: typeof AudioContext })\n            .webkitAudioContext\n        const audioContext = new AudioContextConstructor()\n        const analyser = audioContext.createAnalyser()\n        analyser.fftSize = fftSize\n        analyser.smoothingTimeConstant = smoothingTimeConstant\n\n        const source = audioContext.createMediaStreamSource(stream)\n        source.connect(analyser)\n\n        audioContextRef.current = audioContext\n        analyserRef.current = analyser\n\n        // Clear history when starting\n        historyRef.current = []\n      } catch (error) {\n        if (!cancelled) onError?.(error as Error)\n      }\n    }\n\n    setupMicrophone()\n\n    return () => {\n      cancelled = true\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n        streamRef.current = null\n        onStreamEnd?.()\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n        audioContextRef.current = null\n      }\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n        animationRef.current = 0\n      }\n    }\n  }, [\n    active,\n    deviceId,\n    fftSize,\n    smoothingTimeConstant,\n    onError,\n    onStreamReady,\n    onStreamEnd,\n  ])\n\n  // Animation loop\n  useEffect(() => {\n    const currentCanvas = canvasRef.current\n    if (!currentCanvas) return\n    const canvas: HTMLCanvasElement = currentCanvas\n\n    const currentContext = canvas.getContext(\"2d\")\n    if (!currentContext) return\n    const ctx: CanvasRenderingContext2D = currentContext\n\n    let rafId = 0\n\n    const scheduleRedraw = () => {\n      if (!rafId) rafId = requestAnimationFrame(animate)\n    }\n\n    function animate(currentTime: number) {\n      rafId = 0\n      // Render waveform\n      const rect = canvas.getBoundingClientRect()\n\n      // Update audio data if active\n      if (active && currentTime - lastUpdateRef.current > updateRate) {\n        lastUpdateRef.current = currentTime\n\n        if (analyserRef.current) {\n          const dataArray = new Uint8Array(\n            analyserRef.current.frequencyBinCount\n          )\n          analyserRef.current.getByteFrequencyData(dataArray)\n\n          if (mode === \"static\") {\n            // For static mode, update bars in place\n            const startFreq = Math.floor(dataArray.length * 0.05)\n            const endFreq = Math.floor(dataArray.length * 0.4)\n            const relevantData = dataArray.slice(startFreq, endFreq)\n\n            const barCount = Math.floor(rect.width / (barWidth + barGap))\n            const halfCount = Math.floor(barCount / 2)\n            const newBars: number[] = []\n\n            // Mirror the data for symmetric display\n            for (let i = halfCount - 1; i >= 0; i--) {\n              const dataIndex = Math.floor(\n                (i / halfCount) * relevantData.length\n              )\n              const value = Math.min(\n                1,\n                (relevantData[dataIndex] / 255) * sensitivity\n              )\n              newBars.push(Math.max(0.05, value))\n            }\n\n            for (let i = 0; i < halfCount; i++) {\n              const dataIndex = Math.floor(\n                (i / halfCount) * relevantData.length\n              )\n              const value = Math.min(\n                1,\n                (relevantData[dataIndex] / 255) * sensitivity\n              )\n              newBars.push(Math.max(0.05, value))\n            }\n\n            staticBarsRef.current = newBars\n            lastActiveDataRef.current = newBars\n          } else {\n            // Scrolling mode - original behavior\n            let sum = 0\n            const startFreq = Math.floor(dataArray.length * 0.05)\n            const endFreq = Math.floor(dataArray.length * 0.4)\n            const relevantData = dataArray.slice(startFreq, endFreq)\n\n            for (let i = 0; i < relevantData.length; i++) {\n              sum += relevantData[i]\n            }\n            const average = (sum / relevantData.length / 255) * sensitivity\n\n            // Add to history\n            historyRef.current.push(Math.min(1, Math.max(0.05, average)))\n            lastActiveDataRef.current = [...historyRef.current]\n\n            // Maintain history size\n            if (historyRef.current.length > historySize) {\n              historyRef.current.shift()\n            }\n          }\n          needsRedrawRef.current = true\n        }\n      }\n\n      // Only redraw if needed\n      if (!needsRedrawRef.current && !active && !processing) return\n\n      needsRedrawRef.current = active\n      ctx.clearRect(0, 0, rect.width, rect.height)\n\n      const computedBarColor =\n        barColor ||\n        (() => {\n          const style = getComputedStyle(canvas)\n          // Try to get the computed color value directly\n          const color = style.color\n          return color || \"#000\"\n        })()\n\n      const step = barWidth + barGap\n      const barCount = Math.floor(rect.width / step)\n      const centerY = rect.height / 2\n\n      // Draw bars based on mode\n      if (mode === \"static\") {\n        // Static mode - bars in fixed positions\n        const dataToRender = processing\n          ? staticBarsRef.current\n          : active\n            ? staticBarsRef.current\n            : staticBarsRef.current.length > 0\n              ? staticBarsRef.current\n              : []\n\n        for (let i = 0; i < barCount && i < dataToRender.length; i++) {\n          const value = dataToRender[i] || 0.1\n          const x = i * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.4 + value * 0.6\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n      } else {\n        // Scrolling mode - original behavior\n        for (let i = 0; i < barCount && i < historyRef.current.length; i++) {\n          const dataIndex = historyRef.current.length - 1 - i\n          const value = historyRef.current[dataIndex] || 0.1\n          const x = rect.width - (i + 1) * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.4 + value * 0.6\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n      }\n\n      // Apply edge fading\n      if (fadeEdges && fadeWidth > 0 && rect.width > 0) {\n        // Cache gradient if width hasn't changed\n        if (!gradientCacheRef.current || lastWidthRef.current !== rect.width) {\n          const gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n          const fadePercent = Math.min(0.3, fadeWidth / rect.width)\n\n          // destination-out: removes destination where source alpha is high\n          // We want: fade edges out, keep center solid\n          // Left edge: start opaque (1) = remove, fade to transparent (0) = keep\n          gradient.addColorStop(0, \"rgba(255,255,255,1)\")\n          gradient.addColorStop(fadePercent, \"rgba(255,255,255,0)\")\n          // Center stays transparent = keep everything\n          gradient.addColorStop(1 - fadePercent, \"rgba(255,255,255,0)\")\n          // Right edge: fade from transparent (0) = keep to opaque (1) = remove\n          gradient.addColorStop(1, \"rgba(255,255,255,1)\")\n\n          gradientCacheRef.current = gradient\n          lastWidthRef.current = rect.width\n        }\n\n        ctx.globalCompositeOperation = \"destination-out\"\n        ctx.fillStyle = gradientCacheRef.current\n        ctx.fillRect(0, 0, rect.width, rect.height)\n        ctx.globalCompositeOperation = \"source-over\"\n      }\n\n      ctx.globalAlpha = 1\n\n      if (active || processing) scheduleRedraw()\n    }\n\n    redrawRef.current = scheduleRedraw\n    scheduleRedraw()\n\n    return () => {\n      redrawRef.current = () => {}\n      if (rafId) {\n        cancelAnimationFrame(rafId)\n      }\n    }\n  }, [\n    active,\n    processing,\n    sensitivity,\n    updateRate,\n    historySize,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    barRadius,\n    barColor,\n    fadeEdges,\n    fadeWidth,\n    mode,\n  ])\n\n  return (\n    <div\n      className={cn(\"relative h-full w-full\", className)}\n      ref={containerRef}\n      style={{ height: heightStyle }}\n      aria-label={\n        active\n          ? \"Live audio waveform\"\n          : processing\n            ? \"Processing audio\"\n            : \"Audio waveform idle\"\n      }\n      role=\"img\"\n      {...props}\n    >\n      {!active && !processing && (\n        <div className=\"border-muted-foreground/20 absolute top-1/2 right-0 left-0 -translate-y-1/2 border-t-2 border-dotted\" />\n      )}\n      <canvas\n        className=\"block h-full w-full\"\n        ref={canvasRef}\n        aria-hidden=\"true\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/media.ts",
          "target": "@components/voice-agents/elevenlabs/media.ts",
          "type": "registry:component",
          "content": "export async function acquireMediaStream(\n  constraints: MediaStreamConstraints,\n  cancelled: () => boolean\n) {\n  const stream = await navigator.mediaDevices.getUserMedia(constraints)\n  if (!cancelled()) return stream\n  stream.getTracks().forEach((track) => track.stop())\n  return null\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-conversation",
      "type": "registry:block",
      "title": "Elevenlabs Conversation",
      "description": "Conversation",
      "dependencies": [
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "use-stick-to-bottom@^1.1.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/conversation.tsx",
          "target": "@components/voice-agents/elevenlabs/conversation.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { ArrowDownIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport { useCallback } from \"react\"\nimport { StickToBottom, useStickToBottomContext } from \"use-stick-to-bottom\"\n\nexport type ConversationProps = ComponentProps<typeof StickToBottom>\n\nexport const Conversation = ({ className, ...props }: ConversationProps) => (\n  <StickToBottom\n    className={cn(\"relative flex-1 overflow-y-auto\", className)}\n    initial=\"smooth\"\n    resize=\"smooth\"\n    role=\"log\"\n    {...props}\n  />\n)\n\nexport type ConversationContentProps = ComponentProps<\n  typeof StickToBottom.Content\n>\n\nexport const ConversationContent = ({\n  className,\n  ...props\n}: ConversationContentProps) => (\n  <StickToBottom.Content className={cn(\"p-4\", className)} {...props} />\n)\n\nexport type ConversationEmptyStateProps = Omit<\n  ComponentProps<\"div\">,\n  \"title\"\n> & {\n  title?: React.ReactNode\n  description?: React.ReactNode\n  icon?: React.ReactNode\n}\n\nexport const ConversationEmptyState = ({\n  className,\n  title = \"No messages yet\",\n  description = \"Start a conversation to see messages here\",\n  icon,\n  children,\n  ...props\n}: ConversationEmptyStateProps) => (\n  <div\n    className={cn(\n      \"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\",\n      className\n    )}\n    {...props}\n  >\n    {children ?? (\n      <>\n        {icon && <div className=\"text-muted-foreground\">{icon}</div>}\n        <div className=\"space-y-1\">\n          <h3 className=\"text-sm font-medium\">{title}</h3>\n          {description && (\n            <p className=\"text-muted-foreground text-sm\">{description}</p>\n          )}\n        </div>\n      </>\n    )}\n  </div>\n)\n\nexport type ConversationScrollButtonProps = ComponentProps<typeof Button>\n\nexport const ConversationScrollButton = ({\n  className,\n  ...props\n}: ConversationScrollButtonProps) => {\n  const { isAtBottom, scrollToBottom } = useStickToBottomContext()\n\n  const handleScrollToBottom = useCallback(() => {\n    scrollToBottom()\n  }, [scrollToBottom])\n\n  return (\n    !isAtBottom && (\n      <Button\n        className={cn(\n          \"bg-background dark:bg-background absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full shadow-md\",\n          className\n        )}\n        onClick={handleScrollToBottom}\n        size=\"icon\"\n        type=\"button\"\n        variant=\"outline\"\n        {...props}\n      >\n        <ArrowDownIcon className=\"size-4\" />\n      </Button>\n    )\n  )\n}\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-live-waveform",
      "type": "registry:block",
      "title": "Elevenlabs Live Waveform",
      "description": "Live Waveform",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/live-waveform.tsx",
          "target": "@components/voice-agents/elevenlabs/live-waveform.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { acquireMediaStream } from \"@/components/voice-agents/elevenlabs/media\"\nimport { cn } from \"@/lib/utils\"\nimport { useEffect, useRef, type HTMLAttributes } from \"react\"\n\nexport type LiveWaveformProps = HTMLAttributes<HTMLDivElement> & {\n  active?: boolean\n  processing?: boolean\n  deviceId?: string\n  barWidth?: number\n  barHeight?: number\n  barGap?: number\n  barRadius?: number\n  barColor?: string\n  fadeEdges?: boolean\n  fadeWidth?: number\n  height?: string | number\n  sensitivity?: number\n  smoothingTimeConstant?: number\n  fftSize?: number\n  historySize?: number\n  updateRate?: number\n  mode?: \"scrolling\" | \"static\"\n  onError?: (error: Error) => void\n  onStreamReady?: (stream: MediaStream) => void\n  onStreamEnd?: () => void\n}\n\nexport const LiveWaveform = ({\n  active = false,\n  processing = false,\n  deviceId,\n  barWidth = 3,\n  barGap = 1,\n  barRadius = 1.5,\n  barColor,\n  fadeEdges = true,\n  fadeWidth = 24,\n  barHeight: baseBarHeight = 4,\n  height = 64,\n  sensitivity = 1,\n  smoothingTimeConstant = 0.8,\n  fftSize = 256,\n  historySize = 60,\n  updateRate = 30,\n  mode = \"static\",\n  onError,\n  onStreamReady,\n  onStreamEnd,\n  className,\n  ...props\n}: LiveWaveformProps) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const historyRef = useRef<number[]>([])\n  const analyserRef = useRef<AnalyserNode | null>(null)\n  const audioContextRef = useRef<AudioContext | null>(null)\n  const streamRef = useRef<MediaStream | null>(null)\n  const animationRef = useRef<number>(0)\n  const lastUpdateRef = useRef<number>(0)\n  const processingAnimationRef = useRef<number | null>(null)\n  const lastActiveDataRef = useRef<number[]>([])\n  const transitionProgressRef = useRef(0)\n  const staticBarsRef = useRef<number[]>([])\n  const needsRedrawRef = useRef(true)\n  const gradientCacheRef = useRef<CanvasGradient | null>(null)\n  const lastWidthRef = useRef(0)\n  const redrawRef = useRef<() => void>(() => {})\n\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n  // Handle canvas resizing\n  useEffect(() => {\n    const canvas = canvasRef.current\n    const container = containerRef.current\n    if (!canvas || !container) return\n\n    const resizeObserver = new ResizeObserver(() => {\n      const rect = container.getBoundingClientRect()\n      const dpr = window.devicePixelRatio || 1\n\n      canvas.width = rect.width * dpr\n      canvas.height = rect.height * dpr\n      canvas.style.width = `${rect.width}px`\n      canvas.style.height = `${rect.height}px`\n\n      const ctx = canvas.getContext(\"2d\")\n      if (ctx) {\n        ctx.scale(dpr, dpr)\n      }\n\n      gradientCacheRef.current = null\n      lastWidthRef.current = rect.width\n      needsRedrawRef.current = true\n      redrawRef.current()\n    })\n\n    resizeObserver.observe(container)\n    return () => resizeObserver.disconnect()\n  }, [])\n\n  useEffect(() => {\n    const reduceMotion = window.matchMedia(\n      \"(prefers-reduced-motion: reduce)\"\n    ).matches\n    if (processing && !active) {\n      let time = 0\n      transitionProgressRef.current = 0\n\n      const animateProcessing = () => {\n        time += 0.03\n        transitionProgressRef.current = Math.min(\n          1,\n          transitionProgressRef.current + 0.02\n        )\n\n        const processingData = []\n        const barCount = Math.floor(\n          (containerRef.current?.getBoundingClientRect().width || 200) /\n            (barWidth + barGap)\n        )\n\n        if (mode === \"static\") {\n          const halfCount = Math.floor(barCount / 2)\n\n          for (let i = 0; i < barCount; i++) {\n            const normalizedPosition = (i - halfCount) / halfCount\n            const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n            const wave1 = Math.sin(time * 1.5 + normalizedPosition * 3) * 0.25\n            const wave2 = Math.sin(time * 0.8 - normalizedPosition * 2) * 0.2\n            const wave3 = Math.cos(time * 2 + normalizedPosition) * 0.15\n            const combinedWave = wave1 + wave2 + wave3\n            const processingValue = (0.2 + combinedWave) * centerWeight\n\n            let finalValue = processingValue\n            if (\n              lastActiveDataRef.current.length > 0 &&\n              transitionProgressRef.current < 1\n            ) {\n              const lastDataIndex = Math.min(\n                i,\n                lastActiveDataRef.current.length - 1\n              )\n              const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n              finalValue =\n                lastValue * (1 - transitionProgressRef.current) +\n                processingValue * transitionProgressRef.current\n            }\n\n            processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n          }\n        } else {\n          for (let i = 0; i < barCount; i++) {\n            const normalizedPosition = (i - barCount / 2) / (barCount / 2)\n            const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n            const wave1 = Math.sin(time * 1.5 + i * 0.15) * 0.25\n            const wave2 = Math.sin(time * 0.8 - i * 0.1) * 0.2\n            const wave3 = Math.cos(time * 2 + i * 0.05) * 0.15\n            const combinedWave = wave1 + wave2 + wave3\n            const processingValue = (0.2 + combinedWave) * centerWeight\n\n            let finalValue = processingValue\n            if (\n              lastActiveDataRef.current.length > 0 &&\n              transitionProgressRef.current < 1\n            ) {\n              const lastDataIndex = Math.floor(\n                (i / barCount) * lastActiveDataRef.current.length\n              )\n              const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n              finalValue =\n                lastValue * (1 - transitionProgressRef.current) +\n                processingValue * transitionProgressRef.current\n            }\n\n            processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n          }\n        }\n\n        if (mode === \"static\") {\n          staticBarsRef.current = processingData\n        } else {\n          historyRef.current = processingData\n        }\n\n        needsRedrawRef.current = true\n        redrawRef.current()\n        if (!reduceMotion) {\n          processingAnimationRef.current =\n            requestAnimationFrame(animateProcessing)\n        }\n      }\n\n      animateProcessing()\n\n      return () => {\n        if (processingAnimationRef.current) {\n          cancelAnimationFrame(processingAnimationRef.current)\n        }\n      }\n    } else if (!active && !processing) {\n      const hasData =\n        mode === \"static\"\n          ? staticBarsRef.current.length > 0\n          : historyRef.current.length > 0\n\n      if (hasData) {\n        if (reduceMotion) {\n          staticBarsRef.current = []\n          historyRef.current = []\n          needsRedrawRef.current = true\n          redrawRef.current()\n          return\n        }\n        let fadeProgress = 0\n        let fadeFrame = 0\n        const fadeToIdle = () => {\n          fadeProgress += 0.03\n          if (fadeProgress < 1) {\n            if (mode === \"static\") {\n              staticBarsRef.current = staticBarsRef.current.map(\n                (value) => value * (1 - fadeProgress)\n              )\n            } else {\n              historyRef.current = historyRef.current.map(\n                (value) => value * (1 - fadeProgress)\n              )\n            }\n            needsRedrawRef.current = true\n            redrawRef.current()\n            fadeFrame = requestAnimationFrame(fadeToIdle)\n          } else {\n            if (mode === \"static\") {\n              staticBarsRef.current = []\n            } else {\n              historyRef.current = []\n            }\n          }\n        }\n        fadeToIdle()\n        return () => cancelAnimationFrame(fadeFrame)\n      }\n    }\n  }, [processing, active, barWidth, barGap, mode])\n\n  // Handle microphone setup and teardown\n  useEffect(() => {\n    let cancelled = false\n    if (!active) {\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n        streamRef.current = null\n        onStreamEnd?.()\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n        audioContextRef.current = null\n      }\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n        animationRef.current = 0\n      }\n      return\n    }\n\n    const setupMicrophone = async () => {\n      try {\n        const stream = await acquireMediaStream(\n          {\n            audio: deviceId\n              ? {\n                  deviceId: { exact: deviceId },\n                  echoCancellation: true,\n                  noiseSuppression: true,\n                  autoGainControl: true,\n                }\n              : {\n                  echoCancellation: true,\n                  noiseSuppression: true,\n                  autoGainControl: true,\n                },\n          },\n          () => cancelled\n        )\n        if (!stream) return\n        streamRef.current = stream\n        onStreamReady?.(stream)\n\n        const AudioContextConstructor =\n          window.AudioContext ||\n          (window as unknown as { webkitAudioContext: typeof AudioContext })\n            .webkitAudioContext\n        const audioContext = new AudioContextConstructor()\n        const analyser = audioContext.createAnalyser()\n        analyser.fftSize = fftSize\n        analyser.smoothingTimeConstant = smoothingTimeConstant\n\n        const source = audioContext.createMediaStreamSource(stream)\n        source.connect(analyser)\n\n        audioContextRef.current = audioContext\n        analyserRef.current = analyser\n\n        // Clear history when starting\n        historyRef.current = []\n      } catch (error) {\n        if (!cancelled) onError?.(error as Error)\n      }\n    }\n\n    setupMicrophone()\n\n    return () => {\n      cancelled = true\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n        streamRef.current = null\n        onStreamEnd?.()\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n        audioContextRef.current = null\n      }\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n        animationRef.current = 0\n      }\n    }\n  }, [\n    active,\n    deviceId,\n    fftSize,\n    smoothingTimeConstant,\n    onError,\n    onStreamReady,\n    onStreamEnd,\n  ])\n\n  // Animation loop\n  useEffect(() => {\n    const currentCanvas = canvasRef.current\n    if (!currentCanvas) return\n    const canvas: HTMLCanvasElement = currentCanvas\n\n    const currentContext = canvas.getContext(\"2d\")\n    if (!currentContext) return\n    const ctx: CanvasRenderingContext2D = currentContext\n\n    let rafId = 0\n\n    const scheduleRedraw = () => {\n      if (!rafId) rafId = requestAnimationFrame(animate)\n    }\n\n    function animate(currentTime: number) {\n      rafId = 0\n      // Render waveform\n      const rect = canvas.getBoundingClientRect()\n\n      // Update audio data if active\n      if (active && currentTime - lastUpdateRef.current > updateRate) {\n        lastUpdateRef.current = currentTime\n\n        if (analyserRef.current) {\n          const dataArray = new Uint8Array(\n            analyserRef.current.frequencyBinCount\n          )\n          analyserRef.current.getByteFrequencyData(dataArray)\n\n          if (mode === \"static\") {\n            // For static mode, update bars in place\n            const startFreq = Math.floor(dataArray.length * 0.05)\n            const endFreq = Math.floor(dataArray.length * 0.4)\n            const relevantData = dataArray.slice(startFreq, endFreq)\n\n            const barCount = Math.floor(rect.width / (barWidth + barGap))\n            const halfCount = Math.floor(barCount / 2)\n            const newBars: number[] = []\n\n            // Mirror the data for symmetric display\n            for (let i = halfCount - 1; i >= 0; i--) {\n              const dataIndex = Math.floor(\n                (i / halfCount) * relevantData.length\n              )\n              const value = Math.min(\n                1,\n                (relevantData[dataIndex] / 255) * sensitivity\n              )\n              newBars.push(Math.max(0.05, value))\n            }\n\n            for (let i = 0; i < halfCount; i++) {\n              const dataIndex = Math.floor(\n                (i / halfCount) * relevantData.length\n              )\n              const value = Math.min(\n                1,\n                (relevantData[dataIndex] / 255) * sensitivity\n              )\n              newBars.push(Math.max(0.05, value))\n            }\n\n            staticBarsRef.current = newBars\n            lastActiveDataRef.current = newBars\n          } else {\n            // Scrolling mode - original behavior\n            let sum = 0\n            const startFreq = Math.floor(dataArray.length * 0.05)\n            const endFreq = Math.floor(dataArray.length * 0.4)\n            const relevantData = dataArray.slice(startFreq, endFreq)\n\n            for (let i = 0; i < relevantData.length; i++) {\n              sum += relevantData[i]\n            }\n            const average = (sum / relevantData.length / 255) * sensitivity\n\n            // Add to history\n            historyRef.current.push(Math.min(1, Math.max(0.05, average)))\n            lastActiveDataRef.current = [...historyRef.current]\n\n            // Maintain history size\n            if (historyRef.current.length > historySize) {\n              historyRef.current.shift()\n            }\n          }\n          needsRedrawRef.current = true\n        }\n      }\n\n      // Only redraw if needed\n      if (!needsRedrawRef.current && !active && !processing) return\n\n      needsRedrawRef.current = active\n      ctx.clearRect(0, 0, rect.width, rect.height)\n\n      const computedBarColor =\n        barColor ||\n        (() => {\n          const style = getComputedStyle(canvas)\n          // Try to get the computed color value directly\n          const color = style.color\n          return color || \"#000\"\n        })()\n\n      const step = barWidth + barGap\n      const barCount = Math.floor(rect.width / step)\n      const centerY = rect.height / 2\n\n      // Draw bars based on mode\n      if (mode === \"static\") {\n        // Static mode - bars in fixed positions\n        const dataToRender = processing\n          ? staticBarsRef.current\n          : active\n            ? staticBarsRef.current\n            : staticBarsRef.current.length > 0\n              ? staticBarsRef.current\n              : []\n\n        for (let i = 0; i < barCount && i < dataToRender.length; i++) {\n          const value = dataToRender[i] || 0.1\n          const x = i * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.4 + value * 0.6\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n      } else {\n        // Scrolling mode - original behavior\n        for (let i = 0; i < barCount && i < historyRef.current.length; i++) {\n          const dataIndex = historyRef.current.length - 1 - i\n          const value = historyRef.current[dataIndex] || 0.1\n          const x = rect.width - (i + 1) * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.4 + value * 0.6\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n      }\n\n      // Apply edge fading\n      if (fadeEdges && fadeWidth > 0 && rect.width > 0) {\n        // Cache gradient if width hasn't changed\n        if (!gradientCacheRef.current || lastWidthRef.current !== rect.width) {\n          const gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n          const fadePercent = Math.min(0.3, fadeWidth / rect.width)\n\n          // destination-out: removes destination where source alpha is high\n          // We want: fade edges out, keep center solid\n          // Left edge: start opaque (1) = remove, fade to transparent (0) = keep\n          gradient.addColorStop(0, \"rgba(255,255,255,1)\")\n          gradient.addColorStop(fadePercent, \"rgba(255,255,255,0)\")\n          // Center stays transparent = keep everything\n          gradient.addColorStop(1 - fadePercent, \"rgba(255,255,255,0)\")\n          // Right edge: fade from transparent (0) = keep to opaque (1) = remove\n          gradient.addColorStop(1, \"rgba(255,255,255,1)\")\n\n          gradientCacheRef.current = gradient\n          lastWidthRef.current = rect.width\n        }\n\n        ctx.globalCompositeOperation = \"destination-out\"\n        ctx.fillStyle = gradientCacheRef.current\n        ctx.fillRect(0, 0, rect.width, rect.height)\n        ctx.globalCompositeOperation = \"source-over\"\n      }\n\n      ctx.globalAlpha = 1\n\n      if (active || processing) scheduleRedraw()\n    }\n\n    redrawRef.current = scheduleRedraw\n    scheduleRedraw()\n\n    return () => {\n      redrawRef.current = () => {}\n      if (rafId) {\n        cancelAnimationFrame(rafId)\n      }\n    }\n  }, [\n    active,\n    processing,\n    sensitivity,\n    updateRate,\n    historySize,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    barRadius,\n    barColor,\n    fadeEdges,\n    fadeWidth,\n    mode,\n  ])\n\n  return (\n    <div\n      className={cn(\"relative h-full w-full\", className)}\n      ref={containerRef}\n      style={{ height: heightStyle }}\n      aria-label={\n        active\n          ? \"Live audio waveform\"\n          : processing\n            ? \"Processing audio\"\n            : \"Audio waveform idle\"\n      }\n      role=\"img\"\n      {...props}\n    >\n      {!active && !processing && (\n        <div className=\"border-muted-foreground/20 absolute top-1/2 right-0 left-0 -translate-y-1/2 border-t-2 border-dotted\" />\n      )}\n      <canvas\n        className=\"block h-full w-full\"\n        ref={canvasRef}\n        aria-hidden=\"true\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/media.ts",
          "target": "@components/voice-agents/elevenlabs/media.ts",
          "type": "registry:component",
          "content": "export async function acquireMediaStream(\n  constraints: MediaStreamConstraints,\n  cancelled: () => boolean\n) {\n  const stream = await navigator.mediaDevices.getUserMedia(constraints)\n  if (!cancelled()) return stream\n  stream.getTracks().forEach((track) => track.stop())\n  return null\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-matrix",
      "type": "registry:block",
      "title": "Elevenlabs Matrix",
      "description": "Matrix",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/matrix.tsx",
          "target": "@components/voice-agents/elevenlabs/matrix.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\n\nexport type Frame = number[][]\ntype MatrixMode = \"default\" | \"vu\"\n\ninterface CellPosition {\n  x: number\n  y: number\n}\n\ninterface MatrixProps extends React.HTMLAttributes<HTMLDivElement> {\n  rows: number\n  cols: number\n  pattern?: Frame\n  frames?: Frame[]\n  fps?: number\n  autoplay?: boolean\n  loop?: boolean\n  size?: number\n  gap?: number\n  palette?: {\n    on: string\n    off: string\n  }\n  brightness?: number\n  ariaLabel?: string\n  onFrame?: (index: number) => void\n  mode?: MatrixMode\n  levels?: number[]\n}\n\nfunction clamp(value: number): number {\n  return Math.max(0, Math.min(1, value))\n}\n\nfunction ensureFrameSize(frame: Frame, rows: number, cols: number): Frame {\n  const result: Frame = []\n  for (let r = 0; r < rows; r++) {\n    const row = frame[r] || []\n    result.push([])\n    for (let c = 0; c < cols; c++) {\n      result[r][c] = row[c] ?? 0\n    }\n  }\n  return result\n}\n\nfunction useAnimation(\n  frames: Frame[] | undefined,\n  options: {\n    fps: number\n    autoplay: boolean\n    loop: boolean\n    onFrame?: (index: number) => void\n  }\n): { frameIndex: number; isPlaying: boolean } {\n  const { fps, autoplay, loop, onFrame } = options\n  const [frameIndex, setFrameIndex] = useState(0)\n  const [isPlaying, setIsPlaying] = useState(autoplay)\n  const frameIdRef = useRef<number | undefined>(undefined)\n  const lastTimeRef = useRef<number>(0)\n  const accumulatorRef = useRef<number>(0)\n\n  useEffect(() => {\n    if (\n      !frames ||\n      frames.length === 0 ||\n      !isPlaying ||\n      window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n    ) {\n      return\n    }\n\n    const frameInterval = 1000 / fps\n\n    const animate = (currentTime: number) => {\n      if (lastTimeRef.current === 0) {\n        lastTimeRef.current = currentTime\n      }\n\n      const deltaTime = currentTime - lastTimeRef.current\n      lastTimeRef.current = currentTime\n      accumulatorRef.current += deltaTime\n\n      if (accumulatorRef.current >= frameInterval) {\n        accumulatorRef.current -= frameInterval\n\n        setFrameIndex((prev) => {\n          const next = prev + 1\n          if (next >= frames.length) {\n            if (loop) {\n              onFrame?.(0)\n              return 0\n            } else {\n              setIsPlaying(false)\n              return prev\n            }\n          }\n          onFrame?.(next)\n          return next\n        })\n      }\n\n      frameIdRef.current = requestAnimationFrame(animate)\n    }\n\n    frameIdRef.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (frameIdRef.current) {\n        cancelAnimationFrame(frameIdRef.current)\n      }\n    }\n  }, [frames, isPlaying, fps, loop, onFrame])\n\n  useEffect(() => {\n    setFrameIndex(0)\n    setIsPlaying(autoplay)\n    lastTimeRef.current = 0\n    accumulatorRef.current = 0\n  }, [frames, autoplay])\n\n  return { frameIndex, isPlaying }\n}\n\nfunction emptyFrame(rows: number, cols: number): Frame {\n  return Array.from({ length: rows }, () => Array(cols).fill(0))\n}\n\nfunction setPixel(frame: Frame, row: number, col: number, value: number): void {\n  if (row >= 0 && row < frame.length && col >= 0 && col < frame[0].length) {\n    frame[row][col] = value\n  }\n}\n\nexport const digits: Frame[] = [\n  [\n    [0, 1, 1, 1, 0],\n    [1, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [0, 1, 1, 1, 0],\n  ],\n  [\n    [0, 0, 1, 0, 0],\n    [0, 1, 1, 0, 0],\n    [0, 0, 1, 0, 0],\n    [0, 0, 1, 0, 0],\n    [0, 0, 1, 0, 0],\n    [0, 0, 1, 0, 0],\n    [0, 1, 1, 1, 0],\n  ],\n  [\n    [0, 1, 1, 1, 0],\n    [1, 0, 0, 0, 1],\n    [0, 0, 0, 0, 1],\n    [0, 0, 0, 1, 0],\n    [0, 0, 1, 0, 0],\n    [0, 1, 0, 0, 0],\n    [1, 1, 1, 1, 1],\n  ],\n  [\n    [0, 1, 1, 1, 0],\n    [1, 0, 0, 0, 1],\n    [0, 0, 0, 0, 1],\n    [0, 0, 1, 1, 0],\n    [0, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [0, 1, 1, 1, 0],\n  ],\n  [\n    [0, 0, 0, 1, 0],\n    [0, 0, 1, 1, 0],\n    [0, 1, 0, 1, 0],\n    [1, 0, 0, 1, 0],\n    [1, 1, 1, 1, 1],\n    [0, 0, 0, 1, 0],\n    [0, 0, 0, 1, 0],\n  ],\n  [\n    [1, 1, 1, 1, 1],\n    [1, 0, 0, 0, 0],\n    [1, 1, 1, 1, 0],\n    [0, 0, 0, 0, 1],\n    [0, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [0, 1, 1, 1, 0],\n  ],\n  [\n    [0, 1, 1, 1, 0],\n    [1, 0, 0, 0, 0],\n    [1, 0, 0, 0, 0],\n    [1, 1, 1, 1, 0],\n    [1, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [0, 1, 1, 1, 0],\n  ],\n  [\n    [1, 1, 1, 1, 1],\n    [0, 0, 0, 0, 1],\n    [0, 0, 0, 1, 0],\n    [0, 0, 1, 0, 0],\n    [0, 1, 0, 0, 0],\n    [0, 1, 0, 0, 0],\n    [0, 1, 0, 0, 0],\n  ],\n  [\n    [0, 1, 1, 1, 0],\n    [1, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [0, 1, 1, 1, 0],\n    [1, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [0, 1, 1, 1, 0],\n  ],\n  [\n    [0, 1, 1, 1, 0],\n    [1, 0, 0, 0, 1],\n    [1, 0, 0, 0, 1],\n    [0, 1, 1, 1, 1],\n    [0, 0, 0, 0, 1],\n    [0, 0, 0, 0, 1],\n    [0, 1, 1, 1, 0],\n  ],\n]\n\nexport const chevronLeft: Frame = [\n  [0, 0, 0, 1, 0],\n  [0, 0, 1, 0, 0],\n  [0, 1, 0, 0, 0],\n  [0, 0, 1, 0, 0],\n  [0, 0, 0, 1, 0],\n]\n\nexport const chevronRight: Frame = [\n  [0, 1, 0, 0, 0],\n  [0, 0, 1, 0, 0],\n  [0, 0, 0, 1, 0],\n  [0, 0, 1, 0, 0],\n  [0, 1, 0, 0, 0],\n]\n\nexport const loader: Frame[] = (() => {\n  const frames: Frame[] = []\n  const size = 7\n  const center = 3\n  const radius = 2.5\n\n  for (let frame = 0; frame < 12; frame++) {\n    const f = emptyFrame(size, size)\n    for (let i = 0; i < 8; i++) {\n      const angle = (frame / 12) * Math.PI * 2 + (i / 8) * Math.PI * 2\n      const x = Math.round(center + Math.cos(angle) * radius)\n      const y = Math.round(center + Math.sin(angle) * radius)\n      const brightness = 1 - i / 10\n      setPixel(f, y, x, Math.max(0.2, brightness))\n    }\n    frames.push(f)\n  }\n\n  return frames\n})()\n\nexport const pulse: Frame[] = (() => {\n  const frames: Frame[] = []\n  const size = 7\n  const center = 3\n\n  for (let frame = 0; frame < 16; frame++) {\n    const f = emptyFrame(size, size)\n    const phase = (frame / 16) * Math.PI * 2\n    const intensity = (Math.sin(phase) + 1) / 2\n\n    setPixel(f, center, center, 1)\n\n    const radius = Math.floor((1 - intensity) * 3) + 1\n    for (let dy = -radius; dy <= radius; dy++) {\n      for (let dx = -radius; dx <= radius; dx++) {\n        const dist = Math.sqrt(dx * dx + dy * dy)\n        if (Math.abs(dist - radius) < 0.7) {\n          setPixel(f, center + dy, center + dx, intensity * 0.6)\n        }\n      }\n    }\n\n    frames.push(f)\n  }\n\n  return frames\n})()\n\nexport function vu(columns: number, levels: number[]): Frame {\n  const rows = 7\n  const frame = emptyFrame(rows, columns)\n\n  for (let col = 0; col < Math.min(columns, levels.length); col++) {\n    const level = Math.max(0, Math.min(1, levels[col]))\n    const height = Math.floor(level * rows)\n\n    for (let row = 0; row < rows; row++) {\n      const rowFromBottom = rows - 1 - row\n      if (rowFromBottom < height) {\n        let brightness = 1\n        if (row < rows * 0.3) {\n          brightness = 1\n        } else if (row < rows * 0.6) {\n          brightness = 0.8\n        } else {\n          brightness = 0.6\n        }\n        frame[row][col] = brightness\n      }\n    }\n  }\n\n  return frame\n}\n\nexport const wave: Frame[] = (() => {\n  const frames: Frame[] = []\n  const rows = 7\n  const cols = 7\n\n  for (let frame = 0; frame < 24; frame++) {\n    const f = emptyFrame(rows, cols)\n    const phase = (frame / 24) * Math.PI * 2\n\n    for (let col = 0; col < cols; col++) {\n      const colPhase = (col / cols) * Math.PI * 2\n      const height = Math.sin(phase + colPhase) * 2.5 + 3.5\n      const row = Math.floor(height)\n\n      if (row >= 0 && row < rows) {\n        setPixel(f, row, col, 1)\n        const frac = height - row\n        if (row > 0) setPixel(f, row - 1, col, 1 - frac)\n        if (row < rows - 1) setPixel(f, row + 1, col, frac)\n      }\n    }\n\n    frames.push(f)\n  }\n\n  return frames\n})()\n\nexport const snake: Frame[] = (() => {\n  const frames: Frame[] = []\n  const rows = 7\n  const cols = 7\n  const path: Array<[number, number]> = []\n\n  let x = 0\n  let y = 0\n  let dx = 1\n  let dy = 0\n\n  const visited = new Set<string>()\n  while (path.length < rows * cols) {\n    path.push([y, x])\n    visited.add(`${y},${x}`)\n\n    const nextX = x + dx\n    const nextY = y + dy\n\n    if (\n      nextX >= 0 &&\n      nextX < cols &&\n      nextY >= 0 &&\n      nextY < rows &&\n      !visited.has(`${nextY},${nextX}`)\n    ) {\n      x = nextX\n      y = nextY\n    } else {\n      const newDx = -dy\n      const newDy = dx\n      dx = newDx\n      dy = newDy\n\n      const nextX = x + dx\n      const nextY = y + dy\n\n      if (\n        nextX >= 0 &&\n        nextX < cols &&\n        nextY >= 0 &&\n        nextY < rows &&\n        !visited.has(`${nextY},${nextX}`)\n      ) {\n        x = nextX\n        y = nextY\n      } else {\n        break\n      }\n    }\n  }\n\n  const snakeLength = 5\n  for (let frame = 0; frame < path.length; frame++) {\n    const f = emptyFrame(rows, cols)\n\n    for (let i = 0; i < snakeLength; i++) {\n      const idx = frame - i\n      if (idx >= 0 && idx < path.length) {\n        const [y, x] = path[idx]\n        const brightness = 1 - i / snakeLength\n        setPixel(f, y, x, brightness)\n      }\n    }\n\n    frames.push(f)\n  }\n\n  return frames\n})()\n\nexport const Matrix = React.forwardRef<HTMLDivElement, MatrixProps>(\n  (\n    {\n      rows,\n      cols,\n      pattern,\n      frames,\n      fps = 12,\n      autoplay = true,\n      loop = true,\n      size = 10,\n      gap = 2,\n      palette = {\n        on: \"currentColor\",\n        off: \"var(--muted-foreground)\",\n      },\n      brightness = 1,\n      ariaLabel,\n      onFrame,\n      mode = \"default\",\n      levels,\n      className,\n      ...props\n    },\n    ref\n  ) => {\n    const { frameIndex } = useAnimation(frames, {\n      fps,\n      autoplay: autoplay && !pattern,\n      loop,\n      onFrame,\n    })\n\n    const currentFrame = useMemo(() => {\n      if (mode === \"vu\" && levels && levels.length > 0) {\n        return ensureFrameSize(vu(cols, levels), rows, cols)\n      }\n\n      if (pattern) {\n        return ensureFrameSize(pattern, rows, cols)\n      }\n\n      if (frames && frames.length > 0) {\n        return ensureFrameSize(frames[frameIndex] || frames[0], rows, cols)\n      }\n\n      return ensureFrameSize([], rows, cols)\n    }, [pattern, frames, frameIndex, rows, cols, mode, levels])\n\n    const cellPositions = useMemo(() => {\n      const positions: CellPosition[][] = []\n\n      for (let row = 0; row < rows; row++) {\n        positions[row] = []\n        for (let col = 0; col < cols; col++) {\n          positions[row][col] = {\n            x: col * (size + gap),\n            y: row * (size + gap),\n          }\n        }\n      }\n\n      return positions\n    }, [rows, cols, size, gap])\n\n    const svgDimensions = useMemo(() => {\n      return {\n        width: cols * (size + gap) - gap,\n        height: rows * (size + gap) - gap,\n      }\n    }, [rows, cols, size, gap])\n\n    const isAnimating = !pattern && frames && frames.length > 0\n\n    return (\n      <div\n        ref={ref}\n        role=\"img\"\n        aria-label={ariaLabel ?? \"matrix display\"}\n        aria-live={isAnimating ? \"polite\" : undefined}\n        className={cn(\"relative inline-block\", className)}\n        style={\n          {\n            \"--matrix-on\": palette.on,\n            \"--matrix-off\": palette.off,\n            \"--matrix-gap\": `${gap}px`,\n            \"--matrix-size\": `${size}px`,\n          } as React.CSSProperties\n        }\n        {...props}\n      >\n        <svg\n          width={svgDimensions.width}\n          height={svgDimensions.height}\n          viewBox={`0 0 ${svgDimensions.width} ${svgDimensions.height}`}\n          xmlns=\"http://www.w3.org/2000/svg\"\n          className=\"block\"\n          style={{ overflow: \"visible\" }}\n        >\n          <defs>\n            <radialGradient id=\"matrix-pixel-on\" cx=\"50%\" cy=\"50%\" r=\"50%\">\n              <stop offset=\"0%\" stopColor=\"var(--matrix-on)\" stopOpacity=\"1\" />\n              <stop\n                offset=\"70%\"\n                stopColor=\"var(--matrix-on)\"\n                stopOpacity=\"0.85\"\n              />\n              <stop\n                offset=\"100%\"\n                stopColor=\"var(--matrix-on)\"\n                stopOpacity=\"0.6\"\n              />\n            </radialGradient>\n\n            <radialGradient id=\"matrix-pixel-off\" cx=\"50%\" cy=\"50%\" r=\"50%\">\n              <stop\n                offset=\"0%\"\n                stopColor=\"var(--muted-foreground)\"\n                stopOpacity=\"1\"\n              />\n              <stop\n                offset=\"100%\"\n                stopColor=\"var(--muted-foreground)\"\n                stopOpacity=\"0.7\"\n              />\n            </radialGradient>\n\n            <filter\n              id=\"matrix-glow\"\n              x=\"-50%\"\n              y=\"-50%\"\n              width=\"200%\"\n              height=\"200%\"\n            >\n              <feGaussianBlur stdDeviation=\"2\" result=\"blur\" />\n              <feComposite in=\"SourceGraphic\" in2=\"blur\" operator=\"over\" />\n            </filter>\n          </defs>\n\n          <style>\n            {`\n              .matrix-pixel {\n                transition: opacity 300ms ease-out, transform 150ms ease-out;\n                transform-origin: center;\n                transform-box: fill-box;\n              }\n              .matrix-pixel-active {\n                filter: url(#matrix-glow);\n              }\n            `}\n          </style>\n\n          {currentFrame.map((row, rowIndex) =>\n            row.map((value, colIndex) => {\n              const pos = cellPositions[rowIndex]?.[colIndex]\n              if (!pos) return null\n\n              const opacity = clamp(brightness * value)\n              const isActive = opacity > 0.5\n              const isOn = opacity > 0.05\n              const fill = isOn\n                ? \"url(#matrix-pixel-on)\"\n                : \"url(#matrix-pixel-off)\"\n\n              const scale = isActive ? 1.1 : 1\n              const radius = (size / 2) * 0.9\n\n              return (\n                <circle\n                  key={`${rowIndex}-${colIndex}`}\n                  className={cn(\n                    \"matrix-pixel\",\n                    isActive && \"matrix-pixel-active\",\n                    !isOn && \"opacity-20 dark:opacity-[0.1]\"\n                  )}\n                  cx={pos.x + size / 2}\n                  cy={pos.y + size / 2}\n                  r={radius}\n                  fill={fill}\n                  opacity={isOn ? opacity : 0.1}\n                  style={{\n                    transform: `scale(${scale})`,\n                  }}\n                />\n              )\n            })\n          )}\n        </svg>\n      </div>\n    )\n  }\n)\n\nMatrix.displayName = \"Matrix\"\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-message",
      "type": "registry:block",
      "title": "Elevenlabs Message",
      "description": "Message",
      "dependencies": [
        "@radix-ui/react-avatar@^1.1.3",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/message.tsx",
          "target": "@components/voice-agents/elevenlabs/message.tsx",
          "type": "registry:component",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n  from: \"user\" | \"assistant\"\n}\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n  <div\n    className={cn(\n      \"group flex w-full items-end justify-end gap-2 py-4\",\n      from === \"user\" ? \"is-user\" : \"is-assistant flex-row-reverse justify-end\",\n      className\n    )}\n    {...props}\n  />\n)\n\nconst messageContentVariants = cva(\n  \"is-user:dark flex flex-col gap-2 overflow-hidden rounded-lg text-sm\",\n  {\n    variants: {\n      variant: {\n        contained: [\n          \"max-w-[80%] px-4 py-3\",\n          \"group-[.is-user]:bg-primary group-[.is-user]:text-primary-foreground\",\n          \"group-[.is-assistant]:bg-secondary group-[.is-assistant]:text-foreground\",\n        ],\n        flat: [\n          \"group-[.is-user]:max-w-[80%] group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground\",\n          \"group-[.is-assistant]:text-foreground\",\n        ],\n      },\n    },\n    defaultVariants: {\n      variant: \"contained\",\n    },\n  }\n)\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement> &\n  VariantProps<typeof messageContentVariants>\n\nexport const MessageContent = ({\n  children,\n  className,\n  variant,\n  ...props\n}: MessageContentProps) => (\n  <div\n    className={cn(messageContentVariants({ variant, className }))}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type MessageAvatarProps = ComponentProps<typeof Avatar> & {\n  src: string\n  name?: string\n}\n\nexport const MessageAvatar = ({\n  src,\n  name,\n  className,\n  ...props\n}: MessageAvatarProps) => (\n  <Avatar className={cn(\"ring-border size-8 ring-1\", className)} {...props}>\n    <AvatarImage alt=\"\" className=\"mt-0 mb-0\" src={src} />\n    <AvatarFallback>{name?.slice(0, 2) || \"ME\"}</AvatarFallback>\n  </Avatar>\n)\n"
        },
        {
          "path": "components/ui/avatar.tsx",
          "target": "@components/ui/avatar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Avatar({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n  return (\n    <AvatarPrimitive.Root\n      data-slot=\"avatar\"\n      className={cn(\n        \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarImage({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n  return (\n    <AvatarPrimitive.Image\n      data-slot=\"avatar-image\"\n      className={cn(\"aspect-square size-full\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarFallback({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n  return (\n    <AvatarPrimitive.Fallback\n      data-slot=\"avatar-fallback\"\n      className={cn(\n        \"bg-muted flex size-full items-center justify-center rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Avatar, AvatarImage, AvatarFallback }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-mic-selector",
      "type": "registry:block",
      "title": "Elevenlabs Mic Selector",
      "description": "Mic Selector",
      "dependencies": [
        "@radix-ui/react-dropdown-menu@^2.1.14",
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/mic-selector.tsx",
          "target": "@components/voice-agents/elevenlabs/mic-selector.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { LiveWaveform } from \"@/components/voice-agents/elevenlabs/live-waveform\"\nimport { cn } from \"@/lib/utils\"\nimport { Check, ChevronsUpDown, Mic, MicOff } from \"lucide-react\"\nimport { useCallback, useEffect, useState } from \"react\"\n\nexport interface AudioDevice {\n  deviceId: string\n  label: string\n  groupId: string\n}\n\nexport interface MicSelectorProps {\n  value?: string\n  onValueChange?: (deviceId: string) => void\n  muted?: boolean\n  onMutedChange?: (muted: boolean) => void\n  disabled?: boolean\n  className?: string\n}\n\nexport function MicSelector({\n  value,\n  onValueChange,\n  muted,\n  onMutedChange,\n  disabled,\n  className,\n}: MicSelectorProps) {\n  const { devices, loading, error, hasPermission, loadDevices } =\n    useAudioDevices()\n  const [selectedDevice, setSelectedDevice] = useState<string>(value || \"\")\n  const [internalMuted, setInternalMuted] = useState(false)\n  const [isDropdownOpen, setIsDropdownOpen] = useState(false)\n\n  // Use controlled muted if provided, otherwise use internal state\n  const isMuted = muted !== undefined ? muted : internalMuted\n\n  // Update internal state when controlled value changes\n  useEffect(() => {\n    if (value !== undefined) {\n      setSelectedDevice(value)\n    }\n  }, [value])\n\n  // Select first device by default\n  const defaultDeviceId = devices[0]?.deviceId || \"\"\n  useEffect(() => {\n    if (!selectedDevice && defaultDeviceId) {\n      const newDevice = defaultDeviceId\n      setSelectedDevice(newDevice)\n      onValueChange?.(newDevice)\n    }\n  }, [defaultDeviceId, selectedDevice, onValueChange])\n\n  const currentDevice = devices.find((d) => d.deviceId === selectedDevice) ||\n    devices[0] || {\n      label: loading ? \"Loading...\" : \"No microphone\",\n      deviceId: \"\",\n    }\n\n  const handleDeviceSelect = (deviceId: string, e?: React.MouseEvent) => {\n    e?.preventDefault()\n    setSelectedDevice(deviceId)\n    onValueChange?.(deviceId)\n  }\n\n  const handleDropdownOpenChange = async (open: boolean) => {\n    setIsDropdownOpen(open)\n    if (open && !hasPermission && !loading) {\n      await loadDevices()\n    }\n  }\n\n  const toggleMute = () => {\n    const newMuted = !isMuted\n    if (muted === undefined) {\n      setInternalMuted(newMuted)\n    }\n    onMutedChange?.(newMuted)\n  }\n\n  const isPreviewActive = isDropdownOpen && !isMuted\n\n  return (\n    <DropdownMenu onOpenChange={handleDropdownOpenChange}>\n      <DropdownMenuTrigger asChild>\n        <Button\n          variant=\"ghost\"\n          size=\"sm\"\n          className={cn(\n            \"hover:bg-accent flex w-40 min-w-0 shrink cursor-pointer items-center gap-1.5 sm:w-48\",\n            className\n          )}\n          disabled={loading || disabled}\n        >\n          {isMuted ? (\n            <MicOff className=\"h-4 w-4 flex-shrink-0\" />\n          ) : (\n            <Mic className=\"h-4 w-4 flex-shrink-0\" />\n          )}\n          <span className=\"min-w-0 flex-1 truncate text-left text-xs sm:text-sm\">\n            {currentDevice.label}\n          </span>\n          <ChevronsUpDown className=\"h-3 w-3 flex-shrink-0\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent align=\"center\" side=\"top\" className=\"w-72\">\n        {loading ? (\n          <DropdownMenuItem disabled>Loading devices...</DropdownMenuItem>\n        ) : error ? (\n          <DropdownMenuItem disabled>Error: {error}</DropdownMenuItem>\n        ) : (\n          devices.map((device) => (\n            <DropdownMenuItem\n              key={device.deviceId}\n              onClick={(e) => handleDeviceSelect(device.deviceId, e)}\n              onSelect={(e) => e.preventDefault()}\n              className=\"flex items-center justify-between\"\n            >\n              <span className=\"truncate\">{device.label}</span>\n              {selectedDevice === device.deviceId && (\n                <Check className=\"h-4 w-4 flex-shrink-0\" />\n              )}\n            </DropdownMenuItem>\n          ))\n        )}\n        {devices.length > 0 && (\n          <>\n            <DropdownMenuSeparator />\n            <div className=\"flex items-center gap-2 p-2\">\n              <Button\n                variant=\"ghost\"\n                size=\"sm\"\n                onClick={(e) => {\n                  e.preventDefault()\n                  toggleMute()\n                }}\n                className=\"h-8 gap-2\"\n              >\n                {isMuted ? (\n                  <MicOff className=\"h-4 w-4\" />\n                ) : (\n                  <Mic className=\"h-4 w-4\" />\n                )}\n                <span className=\"text-sm\">{isMuted ? \"Unmute\" : \"Mute\"}</span>\n              </Button>\n              <div className=\"bg-accent ml-auto w-16 overflow-hidden rounded-md p-1.5\">\n                <LiveWaveform\n                  active={isPreviewActive}\n                  deviceId={selectedDevice || defaultDeviceId}\n                  mode=\"static\"\n                  height={15}\n                  barWidth={3}\n                  barGap={1}\n                />\n              </div>\n            </div>\n          </>\n        )}\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n\nexport function useAudioDevices() {\n  const [devices, setDevices] = useState<AudioDevice[]>([])\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState<string | null>(null)\n  const [hasPermission, setHasPermission] = useState(false)\n\n  const loadDevicesWithoutPermission = useCallback(async () => {\n    try {\n      setLoading(true)\n      setError(null)\n\n      const deviceList = await navigator.mediaDevices.enumerateDevices()\n\n      const audioInputs = deviceList\n        .filter((device) => device.kind === \"audioinput\")\n        .map((device) => {\n          let cleanLabel =\n            device.label || `Microphone ${device.deviceId.slice(0, 8)}`\n          cleanLabel = cleanLabel.replace(/\\s*\\([^)]*\\)/g, \"\").trim()\n\n          return {\n            deviceId: device.deviceId,\n            label: cleanLabel,\n            groupId: device.groupId,\n          }\n        })\n\n      setDevices(audioInputs)\n    } catch (err) {\n      setError(\n        err instanceof Error ? err.message : \"Failed to get audio devices\"\n      )\n      console.error(\"Error getting audio devices:\", err)\n    } finally {\n      setLoading(false)\n    }\n  }, [])\n\n  const loadDevicesWithPermission = useCallback(async () => {\n    if (loading) return\n\n    try {\n      setLoading(true)\n      setError(null)\n\n      const tempStream = await navigator.mediaDevices.getUserMedia({\n        audio: true,\n      })\n      tempStream.getTracks().forEach((track) => track.stop())\n\n      const deviceList = await navigator.mediaDevices.enumerateDevices()\n\n      const audioInputs = deviceList\n        .filter((device) => device.kind === \"audioinput\")\n        .map((device) => {\n          let cleanLabel =\n            device.label || `Microphone ${device.deviceId.slice(0, 8)}`\n          cleanLabel = cleanLabel.replace(/\\s*\\([^)]*\\)/g, \"\").trim()\n\n          return {\n            deviceId: device.deviceId,\n            label: cleanLabel,\n            groupId: device.groupId,\n          }\n        })\n\n      setDevices(audioInputs)\n      setHasPermission(true)\n    } catch (err) {\n      setError(\n        err instanceof Error ? err.message : \"Failed to get audio devices\"\n      )\n      console.error(\"Error getting audio devices:\", err)\n    } finally {\n      setLoading(false)\n    }\n  }, [loading])\n\n  useEffect(() => {\n    loadDevicesWithoutPermission()\n  }, [loadDevicesWithoutPermission])\n\n  useEffect(() => {\n    const handleDeviceChange = () => {\n      if (hasPermission) {\n        loadDevicesWithPermission()\n      } else {\n        loadDevicesWithoutPermission()\n      }\n    }\n\n    navigator.mediaDevices.addEventListener(\"devicechange\", handleDeviceChange)\n\n    return () => {\n      navigator.mediaDevices.removeEventListener(\n        \"devicechange\",\n        handleDeviceChange\n      )\n    }\n  }, [hasPermission, loadDevicesWithPermission, loadDevicesWithoutPermission])\n\n  return {\n    devices,\n    loading,\n    error,\n    hasPermission,\n    loadDevices: loadDevicesWithPermission,\n  }\n}\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/dropdown-menu.tsx",
          "target": "@components/ui/dropdown-menu.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction DropdownMenu({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  return (\n    <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n  )\n}\n\nfunction DropdownMenuTrigger({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-md\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return (\n    <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return (\n    <DropdownMenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CircleIcon className=\"size-2 fill-current\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-semibold data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPrimitive.SubContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/live-waveform.tsx",
          "target": "@components/voice-agents/elevenlabs/live-waveform.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { acquireMediaStream } from \"@/components/voice-agents/elevenlabs/media\"\nimport { cn } from \"@/lib/utils\"\nimport { useEffect, useRef, type HTMLAttributes } from \"react\"\n\nexport type LiveWaveformProps = HTMLAttributes<HTMLDivElement> & {\n  active?: boolean\n  processing?: boolean\n  deviceId?: string\n  barWidth?: number\n  barHeight?: number\n  barGap?: number\n  barRadius?: number\n  barColor?: string\n  fadeEdges?: boolean\n  fadeWidth?: number\n  height?: string | number\n  sensitivity?: number\n  smoothingTimeConstant?: number\n  fftSize?: number\n  historySize?: number\n  updateRate?: number\n  mode?: \"scrolling\" | \"static\"\n  onError?: (error: Error) => void\n  onStreamReady?: (stream: MediaStream) => void\n  onStreamEnd?: () => void\n}\n\nexport const LiveWaveform = ({\n  active = false,\n  processing = false,\n  deviceId,\n  barWidth = 3,\n  barGap = 1,\n  barRadius = 1.5,\n  barColor,\n  fadeEdges = true,\n  fadeWidth = 24,\n  barHeight: baseBarHeight = 4,\n  height = 64,\n  sensitivity = 1,\n  smoothingTimeConstant = 0.8,\n  fftSize = 256,\n  historySize = 60,\n  updateRate = 30,\n  mode = \"static\",\n  onError,\n  onStreamReady,\n  onStreamEnd,\n  className,\n  ...props\n}: LiveWaveformProps) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const historyRef = useRef<number[]>([])\n  const analyserRef = useRef<AnalyserNode | null>(null)\n  const audioContextRef = useRef<AudioContext | null>(null)\n  const streamRef = useRef<MediaStream | null>(null)\n  const animationRef = useRef<number>(0)\n  const lastUpdateRef = useRef<number>(0)\n  const processingAnimationRef = useRef<number | null>(null)\n  const lastActiveDataRef = useRef<number[]>([])\n  const transitionProgressRef = useRef(0)\n  const staticBarsRef = useRef<number[]>([])\n  const needsRedrawRef = useRef(true)\n  const gradientCacheRef = useRef<CanvasGradient | null>(null)\n  const lastWidthRef = useRef(0)\n  const redrawRef = useRef<() => void>(() => {})\n\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n  // Handle canvas resizing\n  useEffect(() => {\n    const canvas = canvasRef.current\n    const container = containerRef.current\n    if (!canvas || !container) return\n\n    const resizeObserver = new ResizeObserver(() => {\n      const rect = container.getBoundingClientRect()\n      const dpr = window.devicePixelRatio || 1\n\n      canvas.width = rect.width * dpr\n      canvas.height = rect.height * dpr\n      canvas.style.width = `${rect.width}px`\n      canvas.style.height = `${rect.height}px`\n\n      const ctx = canvas.getContext(\"2d\")\n      if (ctx) {\n        ctx.scale(dpr, dpr)\n      }\n\n      gradientCacheRef.current = null\n      lastWidthRef.current = rect.width\n      needsRedrawRef.current = true\n      redrawRef.current()\n    })\n\n    resizeObserver.observe(container)\n    return () => resizeObserver.disconnect()\n  }, [])\n\n  useEffect(() => {\n    const reduceMotion = window.matchMedia(\n      \"(prefers-reduced-motion: reduce)\"\n    ).matches\n    if (processing && !active) {\n      let time = 0\n      transitionProgressRef.current = 0\n\n      const animateProcessing = () => {\n        time += 0.03\n        transitionProgressRef.current = Math.min(\n          1,\n          transitionProgressRef.current + 0.02\n        )\n\n        const processingData = []\n        const barCount = Math.floor(\n          (containerRef.current?.getBoundingClientRect().width || 200) /\n            (barWidth + barGap)\n        )\n\n        if (mode === \"static\") {\n          const halfCount = Math.floor(barCount / 2)\n\n          for (let i = 0; i < barCount; i++) {\n            const normalizedPosition = (i - halfCount) / halfCount\n            const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n            const wave1 = Math.sin(time * 1.5 + normalizedPosition * 3) * 0.25\n            const wave2 = Math.sin(time * 0.8 - normalizedPosition * 2) * 0.2\n            const wave3 = Math.cos(time * 2 + normalizedPosition) * 0.15\n            const combinedWave = wave1 + wave2 + wave3\n            const processingValue = (0.2 + combinedWave) * centerWeight\n\n            let finalValue = processingValue\n            if (\n              lastActiveDataRef.current.length > 0 &&\n              transitionProgressRef.current < 1\n            ) {\n              const lastDataIndex = Math.min(\n                i,\n                lastActiveDataRef.current.length - 1\n              )\n              const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n              finalValue =\n                lastValue * (1 - transitionProgressRef.current) +\n                processingValue * transitionProgressRef.current\n            }\n\n            processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n          }\n        } else {\n          for (let i = 0; i < barCount; i++) {\n            const normalizedPosition = (i - barCount / 2) / (barCount / 2)\n            const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n            const wave1 = Math.sin(time * 1.5 + i * 0.15) * 0.25\n            const wave2 = Math.sin(time * 0.8 - i * 0.1) * 0.2\n            const wave3 = Math.cos(time * 2 + i * 0.05) * 0.15\n            const combinedWave = wave1 + wave2 + wave3\n            const processingValue = (0.2 + combinedWave) * centerWeight\n\n            let finalValue = processingValue\n            if (\n              lastActiveDataRef.current.length > 0 &&\n              transitionProgressRef.current < 1\n            ) {\n              const lastDataIndex = Math.floor(\n                (i / barCount) * lastActiveDataRef.current.length\n              )\n              const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n              finalValue =\n                lastValue * (1 - transitionProgressRef.current) +\n                processingValue * transitionProgressRef.current\n            }\n\n            processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n          }\n        }\n\n        if (mode === \"static\") {\n          staticBarsRef.current = processingData\n        } else {\n          historyRef.current = processingData\n        }\n\n        needsRedrawRef.current = true\n        redrawRef.current()\n        if (!reduceMotion) {\n          processingAnimationRef.current =\n            requestAnimationFrame(animateProcessing)\n        }\n      }\n\n      animateProcessing()\n\n      return () => {\n        if (processingAnimationRef.current) {\n          cancelAnimationFrame(processingAnimationRef.current)\n        }\n      }\n    } else if (!active && !processing) {\n      const hasData =\n        mode === \"static\"\n          ? staticBarsRef.current.length > 0\n          : historyRef.current.length > 0\n\n      if (hasData) {\n        if (reduceMotion) {\n          staticBarsRef.current = []\n          historyRef.current = []\n          needsRedrawRef.current = true\n          redrawRef.current()\n          return\n        }\n        let fadeProgress = 0\n        let fadeFrame = 0\n        const fadeToIdle = () => {\n          fadeProgress += 0.03\n          if (fadeProgress < 1) {\n            if (mode === \"static\") {\n              staticBarsRef.current = staticBarsRef.current.map(\n                (value) => value * (1 - fadeProgress)\n              )\n            } else {\n              historyRef.current = historyRef.current.map(\n                (value) => value * (1 - fadeProgress)\n              )\n            }\n            needsRedrawRef.current = true\n            redrawRef.current()\n            fadeFrame = requestAnimationFrame(fadeToIdle)\n          } else {\n            if (mode === \"static\") {\n              staticBarsRef.current = []\n            } else {\n              historyRef.current = []\n            }\n          }\n        }\n        fadeToIdle()\n        return () => cancelAnimationFrame(fadeFrame)\n      }\n    }\n  }, [processing, active, barWidth, barGap, mode])\n\n  // Handle microphone setup and teardown\n  useEffect(() => {\n    let cancelled = false\n    if (!active) {\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n        streamRef.current = null\n        onStreamEnd?.()\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n        audioContextRef.current = null\n      }\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n        animationRef.current = 0\n      }\n      return\n    }\n\n    const setupMicrophone = async () => {\n      try {\n        const stream = await acquireMediaStream(\n          {\n            audio: deviceId\n              ? {\n                  deviceId: { exact: deviceId },\n                  echoCancellation: true,\n                  noiseSuppression: true,\n                  autoGainControl: true,\n                }\n              : {\n                  echoCancellation: true,\n                  noiseSuppression: true,\n                  autoGainControl: true,\n                },\n          },\n          () => cancelled\n        )\n        if (!stream) return\n        streamRef.current = stream\n        onStreamReady?.(stream)\n\n        const AudioContextConstructor =\n          window.AudioContext ||\n          (window as unknown as { webkitAudioContext: typeof AudioContext })\n            .webkitAudioContext\n        const audioContext = new AudioContextConstructor()\n        const analyser = audioContext.createAnalyser()\n        analyser.fftSize = fftSize\n        analyser.smoothingTimeConstant = smoothingTimeConstant\n\n        const source = audioContext.createMediaStreamSource(stream)\n        source.connect(analyser)\n\n        audioContextRef.current = audioContext\n        analyserRef.current = analyser\n\n        // Clear history when starting\n        historyRef.current = []\n      } catch (error) {\n        if (!cancelled) onError?.(error as Error)\n      }\n    }\n\n    setupMicrophone()\n\n    return () => {\n      cancelled = true\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n        streamRef.current = null\n        onStreamEnd?.()\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n        audioContextRef.current = null\n      }\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n        animationRef.current = 0\n      }\n    }\n  }, [\n    active,\n    deviceId,\n    fftSize,\n    smoothingTimeConstant,\n    onError,\n    onStreamReady,\n    onStreamEnd,\n  ])\n\n  // Animation loop\n  useEffect(() => {\n    const currentCanvas = canvasRef.current\n    if (!currentCanvas) return\n    const canvas: HTMLCanvasElement = currentCanvas\n\n    const currentContext = canvas.getContext(\"2d\")\n    if (!currentContext) return\n    const ctx: CanvasRenderingContext2D = currentContext\n\n    let rafId = 0\n\n    const scheduleRedraw = () => {\n      if (!rafId) rafId = requestAnimationFrame(animate)\n    }\n\n    function animate(currentTime: number) {\n      rafId = 0\n      // Render waveform\n      const rect = canvas.getBoundingClientRect()\n\n      // Update audio data if active\n      if (active && currentTime - lastUpdateRef.current > updateRate) {\n        lastUpdateRef.current = currentTime\n\n        if (analyserRef.current) {\n          const dataArray = new Uint8Array(\n            analyserRef.current.frequencyBinCount\n          )\n          analyserRef.current.getByteFrequencyData(dataArray)\n\n          if (mode === \"static\") {\n            // For static mode, update bars in place\n            const startFreq = Math.floor(dataArray.length * 0.05)\n            const endFreq = Math.floor(dataArray.length * 0.4)\n            const relevantData = dataArray.slice(startFreq, endFreq)\n\n            const barCount = Math.floor(rect.width / (barWidth + barGap))\n            const halfCount = Math.floor(barCount / 2)\n            const newBars: number[] = []\n\n            // Mirror the data for symmetric display\n            for (let i = halfCount - 1; i >= 0; i--) {\n              const dataIndex = Math.floor(\n                (i / halfCount) * relevantData.length\n              )\n              const value = Math.min(\n                1,\n                (relevantData[dataIndex] / 255) * sensitivity\n              )\n              newBars.push(Math.max(0.05, value))\n            }\n\n            for (let i = 0; i < halfCount; i++) {\n              const dataIndex = Math.floor(\n                (i / halfCount) * relevantData.length\n              )\n              const value = Math.min(\n                1,\n                (relevantData[dataIndex] / 255) * sensitivity\n              )\n              newBars.push(Math.max(0.05, value))\n            }\n\n            staticBarsRef.current = newBars\n            lastActiveDataRef.current = newBars\n          } else {\n            // Scrolling mode - original behavior\n            let sum = 0\n            const startFreq = Math.floor(dataArray.length * 0.05)\n            const endFreq = Math.floor(dataArray.length * 0.4)\n            const relevantData = dataArray.slice(startFreq, endFreq)\n\n            for (let i = 0; i < relevantData.length; i++) {\n              sum += relevantData[i]\n            }\n            const average = (sum / relevantData.length / 255) * sensitivity\n\n            // Add to history\n            historyRef.current.push(Math.min(1, Math.max(0.05, average)))\n            lastActiveDataRef.current = [...historyRef.current]\n\n            // Maintain history size\n            if (historyRef.current.length > historySize) {\n              historyRef.current.shift()\n            }\n          }\n          needsRedrawRef.current = true\n        }\n      }\n\n      // Only redraw if needed\n      if (!needsRedrawRef.current && !active && !processing) return\n\n      needsRedrawRef.current = active\n      ctx.clearRect(0, 0, rect.width, rect.height)\n\n      const computedBarColor =\n        barColor ||\n        (() => {\n          const style = getComputedStyle(canvas)\n          // Try to get the computed color value directly\n          const color = style.color\n          return color || \"#000\"\n        })()\n\n      const step = barWidth + barGap\n      const barCount = Math.floor(rect.width / step)\n      const centerY = rect.height / 2\n\n      // Draw bars based on mode\n      if (mode === \"static\") {\n        // Static mode - bars in fixed positions\n        const dataToRender = processing\n          ? staticBarsRef.current\n          : active\n            ? staticBarsRef.current\n            : staticBarsRef.current.length > 0\n              ? staticBarsRef.current\n              : []\n\n        for (let i = 0; i < barCount && i < dataToRender.length; i++) {\n          const value = dataToRender[i] || 0.1\n          const x = i * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.4 + value * 0.6\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n      } else {\n        // Scrolling mode - original behavior\n        for (let i = 0; i < barCount && i < historyRef.current.length; i++) {\n          const dataIndex = historyRef.current.length - 1 - i\n          const value = historyRef.current[dataIndex] || 0.1\n          const x = rect.width - (i + 1) * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.4 + value * 0.6\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n      }\n\n      // Apply edge fading\n      if (fadeEdges && fadeWidth > 0 && rect.width > 0) {\n        // Cache gradient if width hasn't changed\n        if (!gradientCacheRef.current || lastWidthRef.current !== rect.width) {\n          const gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n          const fadePercent = Math.min(0.3, fadeWidth / rect.width)\n\n          // destination-out: removes destination where source alpha is high\n          // We want: fade edges out, keep center solid\n          // Left edge: start opaque (1) = remove, fade to transparent (0) = keep\n          gradient.addColorStop(0, \"rgba(255,255,255,1)\")\n          gradient.addColorStop(fadePercent, \"rgba(255,255,255,0)\")\n          // Center stays transparent = keep everything\n          gradient.addColorStop(1 - fadePercent, \"rgba(255,255,255,0)\")\n          // Right edge: fade from transparent (0) = keep to opaque (1) = remove\n          gradient.addColorStop(1, \"rgba(255,255,255,1)\")\n\n          gradientCacheRef.current = gradient\n          lastWidthRef.current = rect.width\n        }\n\n        ctx.globalCompositeOperation = \"destination-out\"\n        ctx.fillStyle = gradientCacheRef.current\n        ctx.fillRect(0, 0, rect.width, rect.height)\n        ctx.globalCompositeOperation = \"source-over\"\n      }\n\n      ctx.globalAlpha = 1\n\n      if (active || processing) scheduleRedraw()\n    }\n\n    redrawRef.current = scheduleRedraw\n    scheduleRedraw()\n\n    return () => {\n      redrawRef.current = () => {}\n      if (rafId) {\n        cancelAnimationFrame(rafId)\n      }\n    }\n  }, [\n    active,\n    processing,\n    sensitivity,\n    updateRate,\n    historySize,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    barRadius,\n    barColor,\n    fadeEdges,\n    fadeWidth,\n    mode,\n  ])\n\n  return (\n    <div\n      className={cn(\"relative h-full w-full\", className)}\n      ref={containerRef}\n      style={{ height: heightStyle }}\n      aria-label={\n        active\n          ? \"Live audio waveform\"\n          : processing\n            ? \"Processing audio\"\n            : \"Audio waveform idle\"\n      }\n      role=\"img\"\n      {...props}\n    >\n      {!active && !processing && (\n        <div className=\"border-muted-foreground/20 absolute top-1/2 right-0 left-0 -translate-y-1/2 border-t-2 border-dotted\" />\n      )}\n      <canvas\n        className=\"block h-full w-full\"\n        ref={canvasRef}\n        aria-hidden=\"true\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/media.ts",
          "target": "@components/voice-agents/elevenlabs/media.ts",
          "type": "registry:component",
          "content": "export async function acquireMediaStream(\n  constraints: MediaStreamConstraints,\n  cancelled: () => boolean\n) {\n  const stream = await navigator.mediaDevices.getUserMedia(constraints)\n  if (!cancelled()) return stream\n  stream.getTracks().forEach((track) => track.stop())\n  return null\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-orb",
      "type": "registry:block",
      "title": "Elevenlabs Orb",
      "description": "Orb",
      "dependencies": [
        "tailwindcss@^4.1.7",
        "three@0.149.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/orb.tsx",
          "target": "@components/voice-agents/elevenlabs/orb.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useEffect, useRef, useState, type RefObject } from \"react\"\nimport * as THREE from \"three\"\n\nexport type AgentState = null | \"thinking\" | \"listening\" | \"talking\"\n\nexport type OrbProps = {\n  colors?: [string, string]\n  colorsRef?: RefObject<[string, string]>\n  resizeDebounce?: number\n  seed?: number\n  agentState?: AgentState\n  volumeMode?: \"auto\" | \"manual\"\n  manualInput?: number\n  manualOutput?: number\n  inputVolumeRef?: RefObject<number>\n  outputVolumeRef?: RefObject<number>\n  getInputVolume?: () => number\n  getOutputVolume?: () => number\n  className?: string\n}\n\nexport function Orb({\n  colors = [\"#CADCFC\", \"#A0B9D1\"],\n  colorsRef,\n  resizeDebounce = 100,\n  seed,\n  agentState = null,\n  volumeMode = \"auto\",\n  manualInput,\n  manualOutput,\n  inputVolumeRef,\n  outputVolumeRef,\n  getInputVolume,\n  getOutputVolume,\n  className,\n}: OrbProps) {\n  const hostRef = useRef<HTMLDivElement>(null)\n  const liveRef = useRef({\n    colors,\n    colorsRef,\n    agentState,\n    volumeMode,\n    manualInput,\n    manualOutput,\n    inputVolumeRef,\n    outputVolumeRef,\n    getInputVolume,\n    getOutputVolume,\n  })\n  const [failed, setFailed] = useState(false)\n\n  liveRef.current = {\n    colors,\n    colorsRef,\n    agentState,\n    volumeMode,\n    manualInput,\n    manualOutput,\n    inputVolumeRef,\n    outputVolumeRef,\n    getInputVolume,\n    getOutputVolume,\n  }\n\n  useEffect(() => {\n    const host = hostRef.current\n    if (!host) return\n\n    let renderer: THREE.WebGLRenderer\n    try {\n      renderer = new THREE.WebGLRenderer({\n        alpha: true,\n        antialias: true,\n        premultipliedAlpha: true,\n      })\n      renderer.outputEncoding = THREE.sRGBEncoding\n      renderer.toneMapping = THREE.ACESFilmicToneMapping\n    } catch {\n      setFailed(true)\n      return\n    }\n\n    const scene = new THREE.Scene()\n    const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 100)\n    camera.position.z = 5\n\n    const random = splitmix32(seed ?? Math.floor(Math.random() * 2 ** 32))\n    const initialColors = liveRef.current.colors\n    const offsets = new Float32Array(\n      Array.from({ length: 7 }, () => random() * Math.PI * 2)\n    )\n    const perlinNoiseTexture = createFallbackNoiseTexture(random)\n    perlinNoiseTexture.wrapS = THREE.RepeatWrapping\n    perlinNoiseTexture.wrapT = THREE.RepeatWrapping\n    let disposed = false\n\n    new THREE.TextureLoader().load(\n      \"https://storage.googleapis.com/eleven-public-cdn/images/perlin-noise.png\",\n      (texture) => {\n        if (disposed) {\n          texture.dispose()\n          return\n        }\n        texture.wrapS = THREE.RepeatWrapping\n        texture.wrapT = THREE.RepeatWrapping\n        material.uniforms.uPerlinTexture.value = texture\n      }\n    )\n\n    const isDark = () => document.documentElement.classList.contains(\"dark\")\n    const uniforms = {\n      uColor1: new THREE.Uniform(createManagedColor(initialColors[0])),\n      uColor2: new THREE.Uniform(createManagedColor(initialColors[1])),\n      uOffsets: { value: offsets },\n      uPerlinTexture: new THREE.Uniform(perlinNoiseTexture),\n      uTime: new THREE.Uniform(0),\n      uAnimation: new THREE.Uniform(0.1),\n      uInverted: new THREE.Uniform(isDark() ? 1 : 0),\n      uInputVolume: new THREE.Uniform(0),\n      uOutputVolume: new THREE.Uniform(0),\n      uOpacity: new THREE.Uniform(0),\n    }\n    const geometry = new THREE.CircleGeometry(3.5, 64)\n    const material = new THREE.ShaderMaterial({\n      uniforms,\n      fragmentShader,\n      vertexShader,\n      transparent: true,\n    })\n    const mesh = new THREE.Mesh(geometry, material)\n    scene.add(mesh)\n\n    renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2))\n    renderer.setClearColor(0x000000, 0)\n    renderer.domElement.setAttribute(\"aria-hidden\", \"true\")\n    renderer.domElement.style.width = \"100%\"\n    renderer.domElement.style.height = \"100%\"\n    renderer.domElement.style.display = \"block\"\n    host.appendChild(renderer.domElement)\n\n    let resizeTimer: ReturnType<typeof setTimeout> | undefined\n    const resize = () => {\n      clearTimeout(resizeTimer)\n      resizeTimer = setTimeout(() => {\n        const { width, height } = host.getBoundingClientRect()\n        if (!width || !height) return\n        renderer.setSize(width, height, false)\n        camera.aspect = width / height\n        camera.updateProjectionMatrix()\n      }, resizeDebounce)\n    }\n    const resizeObserver = new ResizeObserver(resize)\n    resizeObserver.observe(host)\n    resize()\n\n    const themeObserver = new MutationObserver(() => {\n      uniforms.uInverted.value = isDark() ? 1 : 0\n    })\n    themeObserver.observe(document.documentElement, {\n      attributes: true,\n      attributeFilter: [\"class\"],\n    })\n\n    let visible = true\n    const intersectionObserver = new IntersectionObserver(([entry]) => {\n      visible = entry?.isIntersecting ?? true\n    })\n    intersectionObserver.observe(host)\n\n    const reducedMotion = window.matchMedia(\n      \"(prefers-reduced-motion: reduce)\"\n    ).matches\n    const targetColor1 = createManagedColor(initialColors[0])\n    const targetColor2 = createManagedColor(initialColors[1])\n    let currentInput = 0\n    let currentOutput = 0\n    let animationSpeed = 0.1\n    let previous = performance.now()\n    let frameId = 0\n\n    const render = (now: number) => {\n      frameId = requestAnimationFrame(render)\n      if (!visible) {\n        previous = now\n        return\n      }\n\n      const delta = Math.min((now - previous) / 1000, 0.1)\n      previous = now\n      const live = liveRef.current\n      const liveColors = live.colorsRef?.current ?? live.colors\n      if (liveColors[0]) setManagedColor(targetColor1, liveColors[0])\n      if (liveColors[1]) setManagedColor(targetColor2, liveColors[1])\n\n      uniforms.uTime.value += reducedMotion ? 0 : delta * 0.5\n      uniforms.uOpacity.value = Math.min(1, uniforms.uOpacity.value + delta * 2)\n\n      let targetInput = 0\n      let targetOutput = 0.3\n      if (live.volumeMode === \"manual\") {\n        targetInput = clamp01(\n          live.manualInput ??\n            live.inputVolumeRef?.current ??\n            live.getInputVolume?.() ??\n            0\n        )\n        targetOutput = clamp01(\n          live.manualOutput ??\n            live.outputVolumeRef?.current ??\n            live.getOutputVolume?.() ??\n            0\n        )\n      } else if (!reducedMotion) {\n        const time = uniforms.uTime.value * 2\n        if (live.agentState === \"listening\") {\n          targetInput = clamp01(0.55 + Math.sin(time * 3.2) * 0.35)\n          targetOutput = 0.45\n        } else if (live.agentState === \"talking\") {\n          targetInput = clamp01(0.65 + Math.sin(time * 4.8) * 0.22)\n          targetOutput = clamp01(0.75 + Math.sin(time * 3.6) * 0.22)\n        } else if (live.agentState === \"thinking\") {\n          const base = 0.38 + 0.07 * Math.sin(time * 0.7)\n          const wander =\n            0.05 * Math.sin(time * 2.1) * Math.sin(time * 0.37 + 1.2)\n          targetInput = clamp01(base + wander)\n          targetOutput = clamp01(0.48 + 0.12 * Math.sin(time * 1.05 + 0.6))\n        }\n      }\n\n      currentInput += (targetInput - currentInput) * 0.2\n      currentOutput += (targetOutput - currentOutput) * 0.2\n      const targetSpeed = 0.1 + (1 - Math.pow(currentOutput - 1, 2)) * 0.9\n      animationSpeed += (targetSpeed - animationSpeed) * 0.12\n\n      uniforms.uAnimation.value += reducedMotion ? 0 : delta * animationSpeed\n      uniforms.uInputVolume.value = currentInput\n      uniforms.uOutputVolume.value = currentOutput\n      uniforms.uColor1.value.lerp(targetColor1, 0.08)\n      uniforms.uColor2.value.lerp(targetColor2, 0.08)\n      renderer.render(scene, camera)\n    }\n    frameId = requestAnimationFrame(render)\n\n    const onContextLost = (event: Event) => {\n      event.preventDefault()\n      setFailed(true)\n    }\n    renderer.domElement.addEventListener(\"webglcontextlost\", onContextLost)\n\n    return () => {\n      disposed = true\n      cancelAnimationFrame(frameId)\n      clearTimeout(resizeTimer)\n      resizeObserver.disconnect()\n      intersectionObserver.disconnect()\n      themeObserver.disconnect()\n      renderer.domElement.removeEventListener(\"webglcontextlost\", onContextLost)\n      geometry.dispose()\n      material.dispose()\n      const loadedTexture = material.uniforms.uPerlinTexture\n        .value as THREE.Texture\n      loadedTexture.dispose()\n      if (loadedTexture !== perlinNoiseTexture) perlinNoiseTexture.dispose()\n      renderer.dispose()\n      renderer.domElement.remove()\n    }\n  }, [resizeDebounce, seed])\n\n  return (\n    <div\n      ref={hostRef}\n      className={className ?? \"relative h-full w-full\"}\n      data-orb-renderer={failed ? \"fallback\" : \"webgl\"}\n    >\n      {failed ? (\n        <div\n          aria-hidden\n          className=\"h-full w-full rounded-full bg-[radial-gradient(circle_at_35%_30%,var(--background),#cadcfc_38%,#a0b9d1_72%,transparent_73%)]\"\n        />\n      ) : null}\n    </div>\n  )\n}\n\nfunction splitmix32(a: number) {\n  return function () {\n    a |= 0\n    a = (a + 0x9e3779b9) | 0\n    let t = a ^ (a >>> 16)\n    t = Math.imul(t, 0x21f0aaad)\n    t = t ^ (t >>> 15)\n    t = Math.imul(t, 0x735a2d97)\n    return ((t = t ^ (t >>> 15)) >>> 0) / 4294967296\n  }\n}\n\nfunction clamp01(n: number) {\n  if (!Number.isFinite(n)) return 0\n  return Math.min(1, Math.max(0, n))\n}\n\nfunction createManagedColor(value: string) {\n  return setManagedColor(new THREE.Color(), value)\n}\n\nfunction setManagedColor(color: THREE.Color, value: string) {\n  color.set(value)\n  if (THREE.ColorManagement.legacyMode) color.convertSRGBToLinear()\n  return color\n}\n\nfunction createFallbackNoiseTexture(random: () => number) {\n  const size = 32\n  const pixels = new Uint8Array(size * size * 4)\n  const phases = Array.from({ length: 6 }, () => random() * Math.PI * 2)\n  for (let y = 0; y < size; y++) {\n    for (let x = 0; x < size; x++) {\n      const px = (x / size) * Math.PI * 2\n      const py = (y / size) * Math.PI * 2\n      const noise =\n        0.5 +\n        0.2 * Math.sin(px + phases[0]) * Math.cos(py + phases[1]) +\n        0.12 * Math.sin(px * 2 + py + phases[2]) +\n        0.08 * Math.cos(px - py * 3 + phases[3]) +\n        0.05 * Math.sin(px * 4 + phases[4]) * Math.cos(py * 4 + phases[5])\n      const value = Math.round(clamp01(noise) * 255)\n      const offset = (y * size + x) * 4\n      pixels[offset] = value\n      pixels[offset + 1] = value\n      pixels[offset + 2] = value\n      pixels[offset + 3] = 255\n    }\n  }\n  const texture = new THREE.DataTexture(\n    pixels,\n    size,\n    size,\n    THREE.RGBAFormat,\n    THREE.UnsignedByteType\n  )\n  texture.minFilter = THREE.LinearFilter\n  texture.magFilter = THREE.LinearFilter\n  texture.needsUpdate = true\n  return texture\n}\nconst vertexShader = /* glsl */ `\nuniform float uTime;\nuniform sampler2D uPerlinTexture;\nvarying vec2 vUv;\n\nvoid main() {\n  vUv = uv;\n  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`\n\nconst fragmentShader = /* glsl */ `\nuniform float uTime;\nuniform float uAnimation;\nuniform float uInverted;\nuniform float uOffsets[7];\nuniform vec3 uColor1;\nuniform vec3 uColor2;\nuniform float uInputVolume;\nuniform float uOutputVolume;\nuniform float uOpacity;\nuniform sampler2D uPerlinTexture;\nvarying vec2 vUv;\n\nconst float PI = 3.14159265358979323846;\n\n// Draw a single oval with soft edges and calculate its gradient color\nbool drawOval(vec2 polarUv, vec2 polarCenter, float a, float b, bool reverseGradient, float softness, out vec4 color) {\n    vec2 p = polarUv - polarCenter;\n    float oval = (p.x * p.x) / (a * a) + (p.y * p.y) / (b * b);\n\n    float edge = smoothstep(1.0, 1.0 - softness, oval);\n\n    if (edge > 0.0) {\n        float gradient = reverseGradient ? (1.0 - (p.x / a + 1.0) / 2.0) : ((p.x / a + 1.0) / 2.0);\n        // Flatten gradient toward middle value for more uniform appearance\n        gradient = mix(0.5, gradient, 0.1);\n        color = vec4(vec3(gradient), 0.85 * edge);\n        return true;\n    }\n    return false;\n}\n\n// Map grayscale value to a 4-color ramp (color1, color2, color3, color4)\nvec3 colorRamp(float grayscale, vec3 color1, vec3 color2, vec3 color3, vec3 color4) {\n    if (grayscale < 0.33) {\n        return mix(color1, color2, grayscale * 3.0);\n    } else if (grayscale < 0.66) {\n        return mix(color2, color3, (grayscale - 0.33) * 3.0);\n    } else {\n        return mix(color3, color4, (grayscale - 0.66) * 3.0);\n    }\n}\n\nvec2 hash2(vec2 p) {\n    return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);\n}\n\n// 2D noise for the ring\nfloat noise2D(vec2 p) {\n    vec2 i = floor(p);\n    vec2 f = fract(p);\n    \n    vec2 u = f * f * (3.0 - 2.0 * f);\n    float n = mix(\n        mix(dot(hash2(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),\n            dot(hash2(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)), u.x),\n        mix(dot(hash2(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),\n            dot(hash2(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)), u.x),\n        u.y\n    );\n\n    return 0.5 + 0.5 * n;\n}\n\nfloat sharpRing(vec3 decomposed, float time) {\n    float ringStart = 1.0;\n    float ringWidth = 0.3;\n    float noiseScale = 5.0;\n\n    float noise = mix(\n        noise2D(vec2(decomposed.x, time) * noiseScale),\n        noise2D(vec2(decomposed.y, time) * noiseScale),\n        decomposed.z\n    );\n\n    noise = (noise - 0.5) * 2.5;\n\n    return ringStart + noise * ringWidth * 1.5;\n}\n\nfloat smoothRing(vec3 decomposed, float time) {\n    float ringStart = 0.9;\n    float ringWidth = 0.2;\n    float noiseScale = 6.0;\n\n    float noise = mix(\n        noise2D(vec2(decomposed.x, time) * noiseScale),\n        noise2D(vec2(decomposed.y, time) * noiseScale),\n        decomposed.z\n    );\n\n    noise = (noise - 0.5) * 5.0;\n\n    return ringStart + noise * ringWidth;\n}\n\nfloat flow(vec3 decomposed, float time) {\n    return mix(\n        texture(uPerlinTexture, vec2(time, decomposed.x / 2.0)).r,\n        texture(uPerlinTexture, vec2(time, decomposed.y / 2.0)).r,\n        decomposed.z\n    );\n}\n\nvoid main() {\n    // Normalize vUv to be centered around (0.0, 0.0)\n    vec2 uv = vUv * 2.0 - 1.0;\n\n    // Convert uv to polar coordinates\n    float radius = length(uv);\n    float theta = atan(uv.y, uv.x);\n    if (theta < 0.0) theta += 2.0 * PI; // Normalize theta to [0, 2*PI]\n\n    // Decomposed angle is used for sampling noise textures without seams:\n    // float noise = mix(sample(decomposed.x), sample(decomposed.y), decomposed.z);\n    vec3 decomposed = vec3(\n        // angle in the range [0, 1]\n        theta / (2.0 * PI),\n        // angle offset by 180 degrees in the range [1, 2]\n        mod(theta / (2.0 * PI) + 0.5, 1.0) + 1.0,\n        // mixing factor between two noises\n        abs(theta / PI - 1.0)\n    );\n\n    // Add noise to the angle for a flow-like distortion (reduced for flatter look)\n    float noise = flow(decomposed, radius * 0.03 - uAnimation * 0.2) - 0.5;\n    theta += noise * mix(0.08, 0.25, uOutputVolume);\n\n    // Initialize the base color to white\n    vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\n\n    // Original parameters for the ovals in polar coordinates\n    float originalCenters[7] = float[7](0.0, 0.5 * PI, 1.0 * PI, 1.5 * PI, 2.0 * PI, 2.5 * PI, 3.0 * PI);\n\n    // Parameters for the animated centers in polar coordinates\n    float centers[7];\n    for (int i = 0; i < 7; i++) {\n        centers[i] = originalCenters[i] + 0.5 * sin(uTime / 20.0 + uOffsets[i]);\n    }\n\n    float a, b;\n    vec4 ovalColor;\n\n    // Check if the pixel is inside any of the ovals\n    for (int i = 0; i < 7; i++) {\n        float noise = texture(uPerlinTexture, vec2(mod(centers[i] + uTime * 0.05, 1.0), 0.5)).r;\n        a = 0.5 + noise * 0.3; // Increased for more coverage\n        b = noise * mix(3.5, 2.5, uInputVolume); // Increased height for fuller appearance\n        bool reverseGradient = (i % 2 == 1); // Reverse gradient for every second oval\n\n        // Calculate the distance in polar coordinates\n        float distTheta = min(\n            abs(theta - centers[i]),\n            min(\n                abs(theta + 2.0 * PI - centers[i]),\n                abs(theta - 2.0 * PI - centers[i])\n            )\n        );\n        float distRadius = radius;\n\n        float softness = 0.6; // Increased softness for flatter, less pronounced edges\n\n        // Check if the pixel is inside the oval in polar coordinates\n        if (drawOval(vec2(distTheta, distRadius), vec2(0.0, 0.0), a, b, reverseGradient, softness, ovalColor)) {\n            // Blend the oval color with the existing color\n            color.rgb = mix(color.rgb, ovalColor.rgb, ovalColor.a);\n            color.a = max(color.a, ovalColor.a); // Max alpha\n        }\n    }\n    \n    // Calculate both noisy rings\n    float ringRadius1 = sharpRing(decomposed, uTime * 0.1);\n    float ringRadius2 = smoothRing(decomposed, uTime * 0.1);\n    \n    // Adjust rings based on input volume (reduced for flatter appearance)\n    float inputRadius1 = radius + uInputVolume * 0.2;\n    float inputRadius2 = radius + uInputVolume * 0.15;\n    float opacity1 = mix(0.2, 0.6, uInputVolume);\n    float opacity2 = mix(0.15, 0.45, uInputVolume);\n\n    // Blend both rings\n    float ringAlpha1 = (inputRadius2 >= ringRadius1) ? opacity1 : 0.0;\n    float ringAlpha2 = smoothstep(ringRadius2 - 0.05, ringRadius2 + 0.05, inputRadius1) * opacity2;\n    \n    float totalRingAlpha = max(ringAlpha1, ringAlpha2);\n    \n    // Apply screen blend mode for combined rings\n    vec3 ringColor = vec3(1.0); // White ring color\n    color.rgb = 1.0 - (1.0 - color.rgb) * (1.0 - ringColor * totalRingAlpha);\n\n    // Define colours to ramp against greyscale (could increase the amount of colours in the ramp)\n    vec3 color1 = vec3(0.0, 0.0, 0.0); // Black\n    vec3 color2 = uColor1; // Darker Color\n    vec3 color3 = uColor2; // Lighter Color\n    vec3 color4 = vec3(1.0, 1.0, 1.0); // White\n\n    // Convert grayscale color to the color ramp\n    float luminance = mix(color.r, 1.0 - color.r, uInverted);\n    color.rgb = colorRamp(luminance, color1, color2, color3, color4); // Apply the color ramp\n\n    // Apply fade-in opacity\n    color.a *= uOpacity;\n\n    gl_FragColor = color;\n}\n`\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-response",
      "type": "registry:block",
      "title": "Elevenlabs Response",
      "description": "Response",
      "dependencies": [
        "clsx@^2.1.1",
        "streamdown@2.4.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/response.tsx",
          "target": "@components/voice-agents/elevenlabs/response.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { memo, type ComponentProps } from \"react\"\nimport { Streamdown } from \"streamdown\"\n\ntype ResponseProps = ComponentProps<typeof Streamdown>\n\nexport const Response = memo(\n  ({ className, ...props }: ResponseProps) => (\n    <Streamdown\n      className={cn(\n        \"size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0\",\n        className\n      )}\n      {...props}\n    />\n  ),\n  (prevProps, nextProps) => prevProps.children === nextProps.children\n)\n\nResponse.displayName = \"Response\"\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-scrub-bar",
      "type": "registry:block",
      "title": "Elevenlabs Scrub Bar",
      "description": "Scrub Bar",
      "dependencies": [
        "@radix-ui/react-progress@^1.1.7",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/scrub-bar.tsx",
          "target": "@components/voice-agents/elevenlabs/scrub-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Progress } from \"@/components/ui/progress\"\nimport { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useRef,\n  type ComponentProps,\n  type HTMLAttributes,\n} from \"react\"\n\nfunction formatTimestamp(value: number) {\n  if (!Number.isFinite(value) || value < 0) return \"0:00\"\n  const totalSeconds = Math.floor(value)\n  const minutes = Math.floor(totalSeconds / 60)\n  const seconds = totalSeconds % 60\n  return `${minutes}:${seconds.toString().padStart(2, \"0\")}`\n}\n\ninterface ScrubBarContextValue {\n  duration: number\n  value: number\n  progress: number\n  onScrub?: (time: number) => void\n  onScrubStart?: () => void\n  onScrubEnd?: () => void\n}\n\nconst ScrubBarContext = createContext<ScrubBarContextValue | null>(null)\n\nfunction useScrubBarContext() {\n  const context = useContext(ScrubBarContext)\n  if (!context) {\n    throw new Error(\"useScrubBarContext must be used within a ScrubBar.Root\")\n  }\n  return context\n}\n\ninterface ScrubBarContainerProps extends HTMLAttributes<HTMLDivElement> {\n  duration: number\n  value: number\n  onScrub?: (time: number) => void\n  onScrubStart?: () => void\n  onScrubEnd?: () => void\n}\n\nfunction ScrubBarContainer({\n  duration,\n  value,\n  onScrub,\n  onScrubStart,\n  onScrubEnd,\n  children,\n  className,\n  ...props\n}: ScrubBarContainerProps) {\n  const progress = duration > 0 ? (value / duration) * 100 : 0\n\n  const contextValue: ScrubBarContextValue = {\n    duration,\n    value,\n    progress,\n    onScrub,\n    onScrubStart,\n    onScrubEnd,\n  }\n\n  return (\n    <ScrubBarContext.Provider value={contextValue}>\n      <div\n        data-slot=\"scrub-bar-root\"\n        className={cn(\"flex w-full items-center\", className)}\n        {...props}\n      >\n        {children}\n      </div>\n    </ScrubBarContext.Provider>\n  )\n}\nScrubBarContainer.displayName = \"ScrubBarContainer\"\n\ntype ScrubBarTrackProps = HTMLAttributes<HTMLDivElement>\n\nfunction ScrubBarTrack({ className, children, ...props }: ScrubBarTrackProps) {\n  const trackRef = useRef<HTMLDivElement | null>(null)\n  const { duration, onScrub, onScrubStart, onScrubEnd, value } =\n    useScrubBarContext()\n\n  const getTimeFromClientX = useCallback(\n    (clientX: number) => {\n      const track = trackRef.current\n      if (!track || !duration) return null\n      const rect = track.getBoundingClientRect()\n      const ratio = (clientX - rect.left) / rect.width\n      const clamped = Math.min(Math.max(ratio, 0), 1)\n      return duration * clamped\n    },\n    [duration]\n  )\n\n  const handlePointerDown = useCallback(\n    (event: React.PointerEvent<HTMLDivElement>) => {\n      if (!duration) return\n      event.preventDefault()\n      onScrubStart?.()\n      const time = getTimeFromClientX(event.clientX)\n      if (time != null) {\n        onScrub?.(time)\n      }\n\n      const handleMove = (moveEvent: PointerEvent) => {\n        const nextTime = getTimeFromClientX(moveEvent.clientX)\n        if (nextTime != null) {\n          onScrub?.(nextTime)\n        }\n      }\n\n      const handleUp = () => {\n        onScrubEnd?.()\n        window.removeEventListener(\"pointermove\", handleMove)\n        window.removeEventListener(\"pointerup\", handleUp)\n      }\n\n      window.addEventListener(\"pointermove\", handleMove)\n      window.addEventListener(\"pointerup\", handleUp, { once: true })\n    },\n    [duration, getTimeFromClientX, onScrub, onScrubEnd, onScrubStart]\n  )\n\n  const clampedValue = Math.min(Math.max(value, 0), duration || 0)\n\n  return (\n    <div\n      ref={trackRef}\n      data-slot=\"scrub-bar-track\"\n      className={cn(\n        \"bg-secondary relative h-2 w-full grow cursor-pointer touch-none rounded-full transition-none select-none\",\n        className\n      )}\n      onPointerDown={handlePointerDown}\n      role=\"slider\"\n      aria-valuemin={0}\n      aria-valuemax={duration || 0}\n      aria-valuenow={clampedValue}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\nScrubBarTrack.displayName = \"ScrubBarTrack\"\n\ntype ScrubBarProgressProps = Omit<ComponentProps<typeof Progress>, \"value\">\n\nfunction ScrubBarProgress({ className, ...props }: ScrubBarProgressProps) {\n  const { progress } = useScrubBarContext()\n\n  return (\n    <Progress\n      data-slot=\"scrub-bar-progress\"\n      value={progress}\n      className={cn(\"absolute h-full [&>div]:transition-none\", className)}\n      {...props}\n    />\n  )\n}\nScrubBarProgress.displayName = \"ScrubBarProgress\"\n\ntype ScrubBarThumbProps = HTMLAttributes<HTMLDivElement>\n\nfunction ScrubBarThumb({ className, children, ...props }: ScrubBarThumbProps) {\n  const { progress } = useScrubBarContext()\n  return (\n    <div\n      data-slot=\"scrub-bar-thumb\"\n      className={cn(\n        \"bg-primary absolute top-1/2 block h-4 w-4 -translate-x-1/2 -translate-y-1/2 rounded-full transition-colors disabled:pointer-events-none disabled:opacity-50\",\n        className\n      )}\n      style={{ left: `${progress}%` }}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\nScrubBarThumb.displayName = \"ScrubBarThumb\"\n\ninterface ScrubBarTimeLabelProps extends HTMLAttributes<HTMLSpanElement> {\n  time: number\n  format?: (time: number) => string\n}\n\nfunction ScrubBarTimeLabel({\n  className,\n  time,\n  format = formatTimestamp,\n  ...props\n}: ScrubBarTimeLabelProps) {\n  return (\n    <span\n      data-slot=\"scrub-bar-time-label\"\n      {...props}\n      className={cn(\"tabular-nums\", className)}\n    >\n      {format(time)}\n    </span>\n  )\n}\nScrubBarTimeLabel.displayName = \"ScrubBarTimeLabel\"\n\nexport {\n  ScrubBarContainer,\n  ScrubBarTrack,\n  ScrubBarProgress,\n  ScrubBarThumb,\n  ScrubBarTimeLabel,\n}\n"
        },
        {
          "path": "components/ui/progress.tsx",
          "target": "@components/ui/progress.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Progress = React.forwardRef<\n  React.ElementRef<typeof ProgressPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>\n>(({ className, value, ...props }, ref) => (\n  <ProgressPrimitive.Root\n    ref={ref}\n    className={cn(\n      \"relative h-2 w-full overflow-hidden rounded-full bg-secondary\",\n      className\n    )}\n    {...props}\n  >\n    <ProgressPrimitive.Indicator\n      className=\"h-full w-full flex-1 bg-primary transition-all\"\n      style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n    />\n  </ProgressPrimitive.Root>\n))\nProgress.displayName = ProgressPrimitive.Root.displayName\n\nexport { Progress }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-shimmering-text",
      "type": "registry:block",
      "title": "Elevenlabs Shimmering Text",
      "description": "Shimmering Text",
      "dependencies": [
        "clsx@^2.1.1",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/shimmering-text.tsx",
          "target": "@components/voice-agents/elevenlabs/shimmering-text.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport {\n  motion,\n  useInView,\n  UseInViewOptions,\n  useReducedMotion,\n} from \"motion/react\"\nimport React, { useMemo, useRef } from \"react\"\n\ninterface ShimmeringTextProps {\n  /** Text to display with shimmer effect */\n  text: string\n  /** Animation duration in seconds */\n  duration?: number\n  /** Delay before starting animation */\n  delay?: number\n  /** Whether to repeat the animation */\n  repeat?: boolean\n  /** Pause duration between repeats in seconds */\n  repeatDelay?: number\n  /** Custom className */\n  className?: string\n  /** Whether to start animation when component enters viewport */\n  startOnView?: boolean\n  /** Whether to animate only once */\n  once?: boolean\n  /** Margin for in-view detection (rootMargin) */\n  inViewMargin?: UseInViewOptions[\"margin\"]\n  /** Shimmer spread multiplier */\n  spread?: number\n  /** Base text color */\n  color?: string\n  /** Shimmer gradient color */\n  shimmerColor?: string\n}\n\nexport function ShimmeringText({\n  text,\n  duration = 2,\n  delay = 0,\n  repeat = true,\n  repeatDelay = 0.5,\n  className,\n  startOnView = true,\n  once = false,\n  inViewMargin,\n  spread = 2,\n  color,\n  shimmerColor,\n}: ShimmeringTextProps) {\n  const ref = useRef<HTMLSpanElement>(null)\n  const isInView = useInView(ref, { once, margin: inViewMargin })\n  const reduceMotion = useReducedMotion()\n\n  // Calculate dynamic spread based on text length\n  const dynamicSpread = useMemo(() => {\n    return text.length * spread\n  }, [text, spread])\n\n  // Determine if we should start animation\n  const shouldAnimate = !reduceMotion && (!startOnView || isInView)\n\n  return (\n    <motion.span\n      ref={ref}\n      className={cn(\n        \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n        \"[--base-color:var(--muted-foreground)] [--shimmer-color:var(--foreground)]\",\n        \"[background-repeat:no-repeat,padding-box]\",\n        \"[--shimmer-bg:linear-gradient(90deg,transparent_calc(50%-var(--spread)),var(--shimmer-color),transparent_calc(50%+var(--spread)))]\",\n        \"dark:[--base-color:var(--muted-foreground)] dark:[--shimmer-color:var(--foreground)]\",\n        className\n      )}\n      style={\n        {\n          \"--spread\": `${dynamicSpread}px`,\n          ...(color && { \"--base-color\": color }),\n          ...(shimmerColor && { \"--shimmer-color\": shimmerColor }),\n          backgroundImage: `var(--shimmer-bg), linear-gradient(var(--base-color), var(--base-color))`,\n        } as React.CSSProperties\n      }\n      initial={\n        reduceMotion\n          ? false\n          : {\n              backgroundPosition: \"100% center\",\n              opacity: 0,\n            }\n      }\n      animate={\n        shouldAnimate\n          ? {\n              backgroundPosition: \"0% center\",\n              opacity: 1,\n            }\n          : {}\n      }\n      transition={{\n        backgroundPosition: {\n          repeat: repeat ? Infinity : 0,\n          duration,\n          delay,\n          repeatDelay,\n          ease: \"linear\",\n        },\n        opacity: {\n          duration: 0.3,\n          delay,\n        },\n      }}\n    >\n      {text}\n    </motion.span>\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-speech-input",
      "type": "registry:block",
      "title": "Elevenlabs Speech Input",
      "description": "Speech Input",
      "dependencies": [
        "@elevenlabs/client@1.7.0",
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/speech-input.tsx",
          "target": "@components/voice-agents/elevenlabs/speech-input.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Skeleton } from \"@/components/ui/skeleton\"\nimport {\n  useScribe,\n  type AudioFormat,\n  type CommitStrategy,\n} from \"@/components/voice-agents/elevenlabs/use-scribe\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { MicIcon, SquareIcon, XIcon } from \"lucide-react\"\nimport { motion } from \"motion/react\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\"!px-0\", {\n  variants: {\n    size: {\n      default: \"h-9 w-9\",\n      sm: \"h-8 w-8\",\n      lg: \"h-10 w-10\",\n    },\n  },\n  defaultVariants: {\n    size: \"default\",\n  },\n})\n\ntype ButtonSize = VariantProps<typeof buttonVariants>[\"size\"]\n\nexport interface SpeechInputData {\n  /** The current partial (in-progress) transcript */\n  partialTranscript: string\n  /** Array of all committed (finalized) transcripts */\n  committedTranscripts: string[]\n  /** Full transcript combining committed and partial transcripts */\n  transcript: string\n}\n\ninterface SpeechInputContextValue {\n  isConnected: boolean\n  isConnecting: boolean\n  transcript: string\n  partialTranscript: string\n  committedTranscripts: string[]\n  error: string | null\n  start: () => Promise<void>\n  stop: () => void\n  cancel: () => void\n  size: ButtonSize\n}\n\nconst SpeechInputContext = React.createContext<SpeechInputContextValue | null>(\n  null\n)\n\nfunction useSpeechInput() {\n  const context = React.useContext(SpeechInputContext)\n  if (!context) {\n    throw new Error(\n      \"SpeechInput compound components must be used within a SpeechInput\"\n    )\n  }\n  return context\n}\n\nfunction buildTranscript({\n  partialTranscript,\n  committedTranscripts,\n}: {\n  partialTranscript: string\n  committedTranscripts: string[]\n}): string {\n  const committed = committedTranscripts.join(\" \").trim()\n  const partial = partialTranscript.trim()\n\n  if (committed && partial) {\n    return `${committed} ${partial}`\n  }\n  return committed || partial\n}\n\nfunction buildData({\n  partialTranscript,\n  committedTranscripts,\n}: {\n  partialTranscript: string\n  committedTranscripts: string[]\n}): SpeechInputData {\n  return {\n    partialTranscript,\n    committedTranscripts,\n    transcript: buildTranscript({ partialTranscript, committedTranscripts }),\n  }\n}\n\nexport interface SpeechInputProps {\n  children: React.ReactNode\n\n  /**\n   * Function that returns a token for authenticating with the speech service.\n   * This should be an async function that fetches a token from your backend.\n   */\n  getToken: () => Promise<string>\n\n  /**\n   * Called whenever the transcript changes (partial or committed)\n   */\n  onChange?: (data: SpeechInputData) => void\n\n  /**\n   * Called when recording is cancelled\n   */\n  onCancel?: (data: SpeechInputData) => void\n\n  /**\n   * Called when recording starts\n   */\n  onStart?: (data: SpeechInputData) => void\n\n  /**\n   * Called when recording stops\n   */\n  onStop?: (data: SpeechInputData) => void\n\n  /**\n   * Additional CSS classes for the root container\n   */\n  className?: string\n\n  /**\n   * Size variant for the component buttons\n   * @default \"default\"\n   */\n  size?: ButtonSize\n\n  /**\n   * Model ID for the speech recognition service\n   * @default \"scribe_v2_realtime\"\n   */\n  modelId?: string\n\n  /**\n   * Base URI for the speech recognition service\n   */\n  baseUri?: string\n\n  /**\n   * Strategy for committing transcripts\n   */\n  commitStrategy?: CommitStrategy\n\n  /**\n   * Silence threshold in seconds for VAD\n   */\n  vadSilenceThresholdSecs?: number\n\n  /**\n   * VAD threshold value\n   */\n  vadThreshold?: number\n\n  /**\n   * Minimum speech duration in milliseconds\n   */\n  minSpeechDurationMs?: number\n\n  /**\n   * Minimum silence duration in milliseconds\n   */\n  minSilenceDurationMs?: number\n\n  /**\n   * Language code for transcription (e.g., \"en\", \"es\", \"fr\")\n   */\n  languageCode?: string\n\n  /**\n   * Microphone configuration options\n   */\n  microphone?: {\n    deviceId?: string\n    echoCancellation?: boolean\n    noiseSuppression?: boolean\n    autoGainControl?: boolean\n    channelCount?: number\n  }\n\n  /**\n   * Audio format for manual audio mode\n   */\n  audioFormat?: AudioFormat\n\n  /**\n   * Sample rate for manual audio mode\n   */\n  sampleRate?: number\n\n  /**\n   * Called when an error occurs\n   */\n  onError?: (error: Error | Event) => void\n\n  /**\n   * Called when an authentication error occurs\n   */\n  onAuthError?: (data: { error: string }) => void\n\n  /**\n   * Called when a quota exceeded error occurs\n   */\n  onQuotaExceededError?: (data: { error: string }) => void\n}\n\nconst SpeechInput = React.forwardRef<HTMLDivElement, SpeechInputProps>(\n  function SpeechInput(\n    {\n      children,\n      getToken,\n      onChange,\n      onCancel,\n      onStart,\n      onStop,\n      className,\n      size = \"default\",\n      modelId = \"scribe_v2_realtime\",\n      baseUri,\n      commitStrategy,\n      vadSilenceThresholdSecs,\n      vadThreshold,\n      minSpeechDurationMs,\n      minSilenceDurationMs,\n      languageCode,\n      microphone = {\n        echoCancellation: true,\n        noiseSuppression: true,\n      },\n      audioFormat,\n      sampleRate,\n      onError,\n      onAuthError,\n      onQuotaExceededError,\n    },\n    ref\n  ) {\n    const transcriptsRef = React.useRef({\n      partialTranscript: \"\",\n      committedTranscripts: [] as string[],\n    })\n    const startRequestIdRef = React.useRef(0)\n\n    const scribe = useScribe({\n      modelId,\n      baseUri,\n      commitStrategy,\n      vadSilenceThresholdSecs,\n      vadThreshold,\n      minSpeechDurationMs,\n      minSilenceDurationMs,\n      languageCode,\n      audioFormat,\n      sampleRate,\n      microphone,\n      onPartialTranscript: (data) => {\n        transcriptsRef.current.partialTranscript = data.text\n        onChange?.(buildData(transcriptsRef.current))\n      },\n      onCommittedTranscript: (data) => {\n        transcriptsRef.current.committedTranscripts.push(data.text)\n        transcriptsRef.current.partialTranscript = \"\"\n        onChange?.(buildData(transcriptsRef.current))\n      },\n      onError,\n      onAuthError,\n      onQuotaExceededError,\n    })\n\n    const isConnecting = scribe.status === \"connecting\"\n\n    const start = React.useCallback(async () => {\n      const requestId = startRequestIdRef.current + 1\n      startRequestIdRef.current = requestId\n\n      transcriptsRef.current = {\n        partialTranscript: \"\",\n        committedTranscripts: [],\n      }\n      scribe.clearTranscripts()\n\n      try {\n        const token = await getToken()\n        if (startRequestIdRef.current !== requestId) {\n          return\n        }\n\n        await scribe.connect({\n          token,\n        })\n        if (startRequestIdRef.current !== requestId) {\n          scribe.disconnect()\n          return\n        }\n        onStart?.(buildData(transcriptsRef.current))\n      } catch (error) {\n        onError?.(error instanceof Error ? error : new Error(String(error)))\n      }\n    }, [getToken, scribe, onStart, onError])\n\n    const stop = React.useCallback(() => {\n      startRequestIdRef.current += 1\n      scribe.disconnect()\n      onStop?.(buildData(transcriptsRef.current))\n    }, [scribe, onStop])\n\n    const cancel = React.useCallback(() => {\n      startRequestIdRef.current += 1\n      const data = buildData(transcriptsRef.current)\n      scribe.disconnect()\n      scribe.clearTranscripts()\n      transcriptsRef.current = {\n        partialTranscript: \"\",\n        committedTranscripts: [],\n      }\n      onCancel?.(data)\n    }, [scribe, onCancel])\n\n    const contextValue: SpeechInputContextValue = React.useMemo(\n      () => ({\n        isConnected: scribe.isConnected,\n        isConnecting,\n        start,\n        stop,\n        cancel,\n        error: scribe.error,\n        size,\n        ...buildData({\n          partialTranscript: scribe.partialTranscript,\n          committedTranscripts: scribe.committedTranscripts.map((t) => t.text),\n        }),\n      }),\n      [\n        scribe.isConnected,\n        scribe.error,\n        scribe.partialTranscript,\n        scribe.committedTranscripts,\n        isConnecting,\n        start,\n        stop,\n        cancel,\n        size,\n      ]\n    )\n\n    const disconnect = scribe.disconnect\n    React.useEffect(() => {\n      return () => {\n        startRequestIdRef.current += 1\n        disconnect()\n      }\n    }, [disconnect])\n\n    return (\n      <SpeechInputContext.Provider value={contextValue}>\n        <div\n          ref={ref}\n          className={cn(\n            \"relative inline-flex items-center overflow-hidden rounded-md transition-all duration-200\",\n            scribe.isConnected\n              ? \"bg-background dark:bg-muted shadow-[inset_0_0_0_1px_var(--color-input),0_1px_2px_0_rgba(0,0,0,0.05)]\"\n              : \"\",\n            className\n          )}\n        >\n          {children}\n        </div>\n      </SpeechInputContext.Provider>\n    )\n  }\n)\n\nSpeechInput.displayName = \"SpeechInput\"\n\nexport type SpeechInputRecordButtonProps = Omit<\n  React.ComponentPropsWithoutRef<typeof Button>,\n  \"size\"\n>\n\n/**\n * Toggle button for starting/stopping speech recording.\n * Shows a microphone icon when idle and a stop icon when recording.\n */\nconst SpeechInputRecordButton = React.forwardRef<\n  HTMLButtonElement,\n  SpeechInputRecordButtonProps\n>(function SpeechInputRecordButton(\n  { className, onClick, variant = \"ghost\", disabled, ...props },\n  ref\n) {\n  const speechInput = useSpeechInput()\n\n  return (\n    <Button\n      ref={ref}\n      type=\"button\"\n      variant={variant}\n      onClick={(e) => {\n        if (speechInput.isConnected) {\n          speechInput.stop()\n        } else {\n          speechInput.start()\n        }\n        onClick?.(e)\n      }}\n      disabled={disabled ?? speechInput.isConnecting}\n      className={cn(\n        buttonVariants({ size: speechInput.size }),\n        \"relative flex items-center justify-center transition-all\",\n        speechInput.isConnected && \"scale-[80%]\",\n        className\n      )}\n      aria-label={\n        speechInput.isConnected ? \"Stop recording\" : \"Start recording\"\n      }\n      {...props}\n    >\n      <Skeleton\n        className={cn(\n          \"absolute h-4 w-4 rounded-full transition-all duration-200\",\n          speechInput.isConnecting\n            ? \"bg-primary scale-90\"\n            : \"scale-[60%] bg-transparent\"\n        )}\n      />\n      <SquareIcon\n        className={cn(\n          \"text-destructive absolute h-4 w-4 fill-current transition-all duration-200\",\n          !speechInput.isConnecting && speechInput.isConnected\n            ? \"scale-100 opacity-100\"\n            : \"scale-[60%] opacity-0\"\n        )}\n      />\n      <MicIcon\n        className={cn(\n          \"absolute h-4 w-4 transition-all duration-200\",\n          !speechInput.isConnecting && !speechInput.isConnected\n            ? \"scale-100 opacity-100\"\n            : \"scale-[60%] opacity-0\"\n        )}\n      />\n    </Button>\n  )\n})\n\nSpeechInputRecordButton.displayName = \"SpeechInputRecordButton\"\n\nexport interface SpeechInputPreviewProps\n  extends React.ComponentPropsWithoutRef<\"div\"> {\n  /**\n   * Text to show when no transcript is available\n   * @default \"Listening...\"\n   */\n  placeholder?: string\n}\n\n/**\n * Displays the current transcript with a placeholder when empty.\n * Only visible when actively recording.\n */\nconst SpeechInputPreview = React.forwardRef<\n  HTMLDivElement,\n  SpeechInputPreviewProps\n>(function SpeechInputPreview(\n  { className, placeholder = \"Listening...\", ...props },\n  ref\n) {\n  const speechInput = useSpeechInput()\n\n  const displayText = speechInput.transcript || placeholder\n  const showPlaceholder = !speechInput.transcript.trim()\n\n  return (\n    <div\n      ref={ref}\n      inert={speechInput.isConnected ? undefined : true}\n      className={cn(\n        \"relative self-stretch text-sm transition-[opacity,transform,width] duration-200 ease-out\",\n        showPlaceholder\n          ? \"text-muted-foreground italic\"\n          : \"text-muted-foreground\",\n        speechInput.isConnected ? \"w-28 opacity-100\" : \"w-0 opacity-0\",\n        className\n      )}\n      title={displayText}\n      aria-hidden={!speechInput.isConnected}\n      {...props}\n    >\n      <div className=\"absolute inset-y-0 -right-1 -left-1 [mask-image:linear-gradient(to_right,transparent,black_10px,black_calc(100%-10px),transparent)]\">\n        <motion.p\n          key=\"text\"\n          layout=\"position\"\n          className=\"absolute top-0 right-0 bottom-0 flex h-full min-w-full items-center px-1 whitespace-nowrap\"\n        >\n          {displayText}\n        </motion.p>\n      </div>\n    </div>\n  )\n})\n\nSpeechInputPreview.displayName = \"SpeechInputPreview\"\n\nexport type SpeechInputCancelButtonProps = Omit<\n  React.ComponentPropsWithoutRef<typeof Button>,\n  \"size\"\n>\n\n/**\n * Button to cancel the current recording and discard the transcript.\n * Only visible when actively recording.\n */\nconst SpeechInputCancelButton = React.forwardRef<\n  HTMLButtonElement,\n  SpeechInputCancelButtonProps\n>(function SpeechInputCancelButton(\n  { className, onClick, variant = \"ghost\", ...props },\n  ref\n) {\n  const speechInput = useSpeechInput()\n\n  return (\n    <Button\n      ref={ref}\n      type=\"button\"\n      variant={variant}\n      inert={speechInput.isConnected ? undefined : true}\n      onClick={(e) => {\n        speechInput.cancel()\n        onClick?.(e)\n      }}\n      className={cn(\n        buttonVariants({ size: speechInput.size }),\n        \"transition-[opacity,transform,width] duration-200 ease-out\",\n        speechInput.isConnected\n          ? \"scale-[80%] opacity-100\"\n          : \"pointer-events-none w-0 scale-100 opacity-0\",\n        className\n      )}\n      aria-label=\"Cancel recording\"\n      {...props}\n    >\n      <XIcon className=\"h-3 w-3\" />\n    </Button>\n  )\n})\n\nSpeechInputCancelButton.displayName = \"SpeechInputCancelButton\"\n\nexport {\n  SpeechInput,\n  SpeechInputRecordButton,\n  SpeechInputPreview,\n  SpeechInputCancelButton,\n  useSpeechInput,\n}\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/skeleton.tsx",
          "target": "@components/ui/skeleton.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"skeleton\"\n      className={cn(\"bg-primary/10 animate-pulse rounded-md\", className)}\n      {...props}\n    />\n  )\n}\n\nexport { Skeleton }\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/use-scribe.ts",
          "target": "@components/voice-agents/elevenlabs/use-scribe.ts",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { RealtimeEvents, Scribe } from \"@elevenlabs/client\"\nimport type {\n  AudioFormat,\n  AudioOptions,\n  CommitStrategy,\n  CommittedTranscriptMessage,\n  CommittedTranscriptWithTimestampsMessage,\n  MicrophoneOptions,\n  PartialTranscriptMessage,\n  RealtimeConnection,\n  ScribeAuthErrorMessage,\n  ScribeChunkSizeExceededErrorMessage,\n  ScribeCommitThrottledErrorMessage,\n  ScribeErrorMessage,\n  ScribeInputErrorMessage,\n  ScribeInsufficientAudioActivityErrorMessage,\n  ScribeQueueOverflowErrorMessage,\n  ScribeQuotaExceededErrorMessage,\n  ScribeRateLimitedErrorMessage,\n  ScribeResourceExhaustedErrorMessage,\n  ScribeSessionTimeLimitExceededErrorMessage,\n  ScribeTranscriberErrorMessage,\n  ScribeUnacceptedTermsErrorMessage,\n} from \"@elevenlabs/client\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\n// ============= Types =============\n\nexport type ScribeStatus =\n  | \"disconnected\"\n  | \"connecting\"\n  | \"connected\"\n  | \"transcribing\"\n  | \"error\"\n\nexport interface TranscriptSegment {\n  id: string\n  text: string\n  timestamp: number\n  isFinal: boolean\n}\n\nexport interface ScribeCallbacks {\n  onSessionStarted?: () => void\n  onPartialTranscript?: (data: { text: string }) => void\n  onCommittedTranscript?: (data: { text: string }) => void\n  onCommittedTranscriptWithTimestamps?: (data: {\n    text: string\n    timestamps?: { start: number; end: number }[]\n  }) => void\n  /** Called for any error (also called when specific error callbacks fire) */\n  onError?: (error: Error | Event) => void\n  onAuthError?: (data: { error: string }) => void\n  onQuotaExceededError?: (data: { error: string }) => void\n  onCommitThrottledError?: (data: { error: string }) => void\n  onTranscriberError?: (data: { error: string }) => void\n  onUnacceptedTermsError?: (data: { error: string }) => void\n  onRateLimitedError?: (data: { error: string }) => void\n  onInputError?: (data: { error: string }) => void\n  onQueueOverflowError?: (data: { error: string }) => void\n  onResourceExhaustedError?: (data: { error: string }) => void\n  onSessionTimeLimitExceededError?: (data: { error: string }) => void\n  onChunkSizeExceededError?: (data: { error: string }) => void\n  onInsufficientAudioActivityError?: (data: { error: string }) => void\n\n  onConnect?: () => void\n  onDisconnect?: () => void\n}\n\nexport interface ScribeHookOptions extends ScribeCallbacks {\n  // Connection options\n  token?: string\n  modelId?: string\n  baseUri?: string\n\n  // VAD options\n  commitStrategy?: CommitStrategy\n  vadSilenceThresholdSecs?: number\n  vadThreshold?: number\n  minSpeechDurationMs?: number\n  minSilenceDurationMs?: number\n  languageCode?: string\n\n  // Microphone options (for automatic microphone mode)\n  microphone?: {\n    deviceId?: string\n    echoCancellation?: boolean\n    noiseSuppression?: boolean\n    autoGainControl?: boolean\n    channelCount?: number\n  }\n\n  // Manual audio options\n  audioFormat?: AudioFormat\n  sampleRate?: number\n\n  // Auto-connect on mount\n  autoConnect?: boolean\n\n  // Include timestamps\n  includeTimestamps?: boolean\n}\n\nexport interface UseScribeReturn {\n  // State\n  status: ScribeStatus\n  isConnected: boolean\n  isTranscribing: boolean\n  partialTranscript: string\n  committedTranscripts: TranscriptSegment[]\n  error: string | null\n\n  // Connection methods\n  connect: (options?: Partial<ScribeHookOptions>) => Promise<void>\n  disconnect: () => void\n\n  // Audio methods (for manual mode)\n  sendAudio: (\n    audioBase64: string,\n    options?: { commit?: boolean; sampleRate?: number; previousText?: string }\n  ) => void\n  commit: () => void\n\n  // Utility methods\n  clearTranscripts: () => void\n  getConnection: () => RealtimeConnection | null\n}\n\n// ============= Hook Implementation =============\n\nexport function useScribe(options: ScribeHookOptions = {}): UseScribeReturn {\n  const {\n    // Callbacks\n    onSessionStarted,\n    onPartialTranscript,\n    onCommittedTranscript,\n    onCommittedTranscriptWithTimestamps,\n    onError,\n    onAuthError,\n    onQuotaExceededError,\n    onCommitThrottledError,\n    onTranscriberError,\n    onUnacceptedTermsError,\n    onRateLimitedError,\n    onInputError,\n    onQueueOverflowError,\n    onResourceExhaustedError,\n    onSessionTimeLimitExceededError,\n    onChunkSizeExceededError,\n    onInsufficientAudioActivityError,\n    onConnect,\n    onDisconnect,\n\n    // Connection options\n    token: defaultToken,\n    modelId: defaultModelId,\n    baseUri: defaultBaseUri,\n    commitStrategy: defaultCommitStrategy,\n    vadSilenceThresholdSecs: defaultVadSilenceThresholdSecs,\n    vadThreshold: defaultVadThreshold,\n    minSpeechDurationMs: defaultMinSpeechDurationMs,\n    minSilenceDurationMs: defaultMinSilenceDurationMs,\n    languageCode: defaultLanguageCode,\n\n    // Mode options\n    microphone: defaultMicrophone,\n    audioFormat: defaultAudioFormat,\n    sampleRate: defaultSampleRate,\n\n    // Auto-connect\n    autoConnect = false,\n  } = options\n\n  const connectionRef = useRef<RealtimeConnection | null>(null)\n  const connectionIdCounterRef = useRef(0)\n  const activeConnectionIdRef = useRef<number | null>(null)\n\n  const [status, setStatus] = useState<ScribeStatus>(\"disconnected\")\n  const [partialTranscript, setPartialTranscript] = useState<string>(\"\")\n  const [committedTranscripts, setCommittedTranscripts] = useState<\n    TranscriptSegment[]\n  >([])\n  const [error, setError] = useState<string | null>(null)\n\n  const disconnect = useCallback(() => {\n    const connection = connectionRef.current\n    if (!connection) {\n      setStatus(\"disconnected\")\n      activeConnectionIdRef.current = null\n      return\n    }\n\n    activeConnectionIdRef.current = null\n    connectionRef.current = null\n\n    try {\n      const result = connection.close()\n      if (\n        typeof result === \"object\" &&\n        result !== null &&\n        \"catch\" in result &&\n        typeof (result as Promise<unknown>).catch === \"function\"\n      ) {\n        const promise = result as Promise<void>\n        promise.catch(() => {\n          /* noop */\n        })\n      }\n    } catch (err) {\n      console.warn(\"[useScribe] Failed to close connection\", err)\n    } finally {\n      setStatus(\"disconnected\")\n      onDisconnect?.()\n    }\n  }, [onDisconnect])\n\n  // Cleanup on unmount\n  useEffect(() => {\n    return () => {\n      disconnect()\n    }\n  }, [disconnect])\n\n  const connect = useCallback(\n    async (runtimeOptions: Partial<ScribeHookOptions> = {}) => {\n      if (connectionRef.current) {\n        console.warn(\"Already connected\")\n        return\n      }\n\n      const connectionId = connectionIdCounterRef.current + 1\n      connectionIdCounterRef.current = connectionId\n\n      try {\n        setStatus(\"connecting\")\n        setError(null)\n\n        // Merge default options with runtime options\n        const token = runtimeOptions.token || defaultToken\n        const modelId = runtimeOptions.modelId || defaultModelId\n\n        if (!token) {\n          throw new Error(\"Token is required\")\n        }\n        if (!modelId) {\n          throw new Error(\"Model ID is required\")\n        }\n\n        // Determine mode: microphone or manual\n        const microphone = runtimeOptions.microphone || defaultMicrophone\n        const audioFormat = runtimeOptions.audioFormat || defaultAudioFormat\n        const sampleRate = runtimeOptions.sampleRate || defaultSampleRate\n\n        let connection: RealtimeConnection\n\n        const includeTimestamps =\n          runtimeOptions.includeTimestamps ??\n          !!(\n            runtimeOptions.onCommittedTranscriptWithTimestamps ||\n            onCommittedTranscriptWithTimestamps\n          )\n\n        if (microphone) {\n          // Microphone mode\n          connection = Scribe.connect({\n            token,\n            modelId,\n            baseUri: runtimeOptions.baseUri || defaultBaseUri,\n            commitStrategy:\n              runtimeOptions.commitStrategy || defaultCommitStrategy,\n            vadSilenceThresholdSecs:\n              runtimeOptions.vadSilenceThresholdSecs ||\n              defaultVadSilenceThresholdSecs,\n            vadThreshold: runtimeOptions.vadThreshold || defaultVadThreshold,\n            minSpeechDurationMs:\n              runtimeOptions.minSpeechDurationMs || defaultMinSpeechDurationMs,\n            minSilenceDurationMs:\n              runtimeOptions.minSilenceDurationMs ||\n              defaultMinSilenceDurationMs,\n            languageCode: runtimeOptions.languageCode || defaultLanguageCode,\n            microphone,\n            includeTimestamps,\n          } as MicrophoneOptions)\n        } else if (audioFormat && sampleRate) {\n          // Manual audio mode\n          connection = Scribe.connect({\n            token,\n            modelId,\n            baseUri: runtimeOptions.baseUri || defaultBaseUri,\n            commitStrategy:\n              runtimeOptions.commitStrategy || defaultCommitStrategy,\n            vadSilenceThresholdSecs:\n              runtimeOptions.vadSilenceThresholdSecs ||\n              defaultVadSilenceThresholdSecs,\n            vadThreshold: runtimeOptions.vadThreshold || defaultVadThreshold,\n            minSpeechDurationMs:\n              runtimeOptions.minSpeechDurationMs || defaultMinSpeechDurationMs,\n            minSilenceDurationMs:\n              runtimeOptions.minSilenceDurationMs ||\n              defaultMinSilenceDurationMs,\n            languageCode: runtimeOptions.languageCode || defaultLanguageCode,\n            includeTimestamps,\n            audioFormat,\n            sampleRate,\n          } as AudioOptions)\n        } else {\n          throw new Error(\n            \"Either microphone options or (audioFormat + sampleRate) must be provided\"\n          )\n        }\n\n        connectionRef.current = connection\n        activeConnectionIdRef.current = connectionId\n\n        const runIfCurrent =\n          <Args extends unknown[]>(handler: (...args: Args) => void) =>\n          (...args: Args) => {\n            if (activeConnectionIdRef.current !== connectionId) {\n              return\n            }\n            handler(...args)\n          }\n\n        // Set up event listeners\n        connection.on(\n          RealtimeEvents.SESSION_STARTED,\n          runIfCurrent(() => {\n            setStatus(\"connected\")\n            onSessionStarted?.()\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.PARTIAL_TRANSCRIPT,\n          runIfCurrent((data: unknown) => {\n            const message = data as PartialTranscriptMessage\n            setPartialTranscript(message.text)\n            setStatus(\"transcribing\")\n            onPartialTranscript?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.COMMITTED_TRANSCRIPT,\n          runIfCurrent((data: unknown) => {\n            const message = data as CommittedTranscriptMessage\n            const segment: TranscriptSegment = {\n              id: `${Date.now()}-${Math.random()}`,\n              text: message.text,\n              timestamp: Date.now(),\n              isFinal: true,\n            }\n            setCommittedTranscripts((prev) => [...prev, segment])\n            setPartialTranscript(\"\")\n            onCommittedTranscript?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS,\n          runIfCurrent((data: unknown) => {\n            const message = data as CommittedTranscriptWithTimestampsMessage\n            const segment: TranscriptSegment = {\n              id: `${Date.now()}-${Math.random()}`,\n              text: message.text,\n              timestamp: Date.now(),\n              isFinal: true,\n            }\n            setCommittedTranscripts((prev) => [...prev, segment])\n            setPartialTranscript(\"\")\n            onCommittedTranscriptWithTimestamps?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.ERROR,\n          runIfCurrent((err: unknown) => {\n            const message = err as ScribeErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onError?.(new Error(message.error))\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.AUTH_ERROR,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeAuthErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onAuthError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.QUOTA_EXCEEDED,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeQuotaExceededErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onQuotaExceededError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.COMMIT_THROTTLED,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeCommitThrottledErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onCommitThrottledError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.TRANSCRIBER_ERROR,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeTranscriberErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onTranscriberError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.UNACCEPTED_TERMS,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeUnacceptedTermsErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onUnacceptedTermsError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.RATE_LIMITED,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeRateLimitedErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onRateLimitedError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.INPUT_ERROR,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeInputErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onInputError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.QUEUE_OVERFLOW,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeQueueOverflowErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onQueueOverflowError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.RESOURCE_EXHAUSTED,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeResourceExhaustedErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onResourceExhaustedError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.SESSION_TIME_LIMIT_EXCEEDED,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeSessionTimeLimitExceededErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onSessionTimeLimitExceededError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.CHUNK_SIZE_EXCEEDED,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeChunkSizeExceededErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onChunkSizeExceededError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.INSUFFICIENT_AUDIO_ACTIVITY,\n          runIfCurrent((data: unknown) => {\n            const message = data as ScribeInsufficientAudioActivityErrorMessage\n            setError(message.error)\n            setStatus(\"error\")\n            onInsufficientAudioActivityError?.(message)\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.OPEN,\n          runIfCurrent(() => {\n            onConnect?.()\n          })\n        )\n\n        connection.on(\n          RealtimeEvents.CLOSE,\n          runIfCurrent(() => {\n            activeConnectionIdRef.current = null\n            connectionRef.current = null\n            setStatus(\"disconnected\")\n            onDisconnect?.()\n          })\n        )\n      } catch (err) {\n        const errorMessage =\n          err instanceof Error ? err.message : \"Failed to connect\"\n        setError(errorMessage)\n        setStatus(\"error\")\n        throw err\n      }\n    },\n    [\n      defaultToken,\n      defaultModelId,\n      defaultBaseUri,\n      defaultCommitStrategy,\n      defaultVadSilenceThresholdSecs,\n      defaultVadThreshold,\n      defaultMinSpeechDurationMs,\n      defaultMinSilenceDurationMs,\n      defaultLanguageCode,\n      defaultMicrophone,\n      defaultAudioFormat,\n      defaultSampleRate,\n      onSessionStarted,\n      onPartialTranscript,\n      onCommittedTranscript,\n      onCommittedTranscriptWithTimestamps,\n      onError,\n      onAuthError,\n      onQuotaExceededError,\n      onCommitThrottledError,\n      onTranscriberError,\n      onUnacceptedTermsError,\n      onRateLimitedError,\n      onInputError,\n      onQueueOverflowError,\n      onResourceExhaustedError,\n      onSessionTimeLimitExceededError,\n      onChunkSizeExceededError,\n      onInsufficientAudioActivityError,\n      onConnect,\n      onDisconnect,\n    ]\n  )\n\n  const sendAudio = useCallback(\n    (\n      audioBase64: string,\n      options?: { commit?: boolean; sampleRate?: number; previousText?: string }\n    ) => {\n      if (!connectionRef.current) {\n        throw new Error(\"Not connected to Scribe\")\n      }\n      connectionRef.current.send({ audioBase64, ...options })\n    },\n    []\n  )\n\n  const commit = useCallback(() => {\n    if (!connectionRef.current) {\n      throw new Error(\"Not connected to Scribe\")\n    }\n    connectionRef.current.commit()\n  }, [])\n\n  const clearTranscripts = useCallback(() => {\n    setCommittedTranscripts([])\n    setPartialTranscript(\"\")\n  }, [])\n\n  const getConnection = useCallback(() => {\n    return connectionRef.current\n  }, [])\n\n  // Auto-connect if enabled\n  useEffect(() => {\n    if (autoConnect) {\n      void connect()\n    }\n  }, [autoConnect, connect])\n\n  return {\n    // State\n    status,\n    isConnected: status === \"connected\" || status === \"transcribing\",\n    isTranscribing: status === \"transcribing\",\n    partialTranscript,\n    committedTranscripts,\n    error,\n\n    // Methods\n    connect,\n    disconnect,\n    sendAudio,\n    commit,\n    clearTranscripts,\n    getConnection,\n  }\n}\n\n// Export types and enums from client for convenience\nexport { AudioFormat, CommitStrategy, RealtimeEvents } from \"@elevenlabs/client\"\nexport type { RealtimeConnection } from \"@elevenlabs/client\"\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-transcript-viewer",
      "type": "registry:block",
      "title": "Elevenlabs Transcript Viewer",
      "description": "Transcript Viewer",
      "dependencies": [
        "@radix-ui/react-progress@^1.1.7",
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/transcript-viewer.tsx",
          "target": "@components/voice-agents/elevenlabs/transcript-viewer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  ScrubBarContainer,\n  ScrubBarProgress,\n  ScrubBarThumb,\n  ScrubBarTimeLabel,\n  ScrubBarTrack,\n} from \"@/components/voice-agents/elevenlabs/scrub-bar\"\nimport type { CharacterAlignmentResponseModel } from \"@/components/voice-agents/elevenlabs/types\"\nimport {\n  useTranscriptViewer,\n  type SegmentComposer,\n  type TranscriptSegment,\n  type TranscriptWord as TranscriptWordType,\n  type UseTranscriptViewerResult,\n} from \"@/components/voice-agents/elevenlabs/use-transcript-viewer\"\nimport { cn } from \"@/lib/utils\"\nimport { Pause, Play } from \"lucide-react\"\nimport {\n  createContext,\n  useContext,\n  useMemo,\n  type ComponentPropsWithoutRef,\n  type ComponentPropsWithRef,\n  type HTMLAttributes,\n  type ReactNode,\n} from \"react\"\n\ntype TranscriptGap = Extract<TranscriptSegment, { kind: \"gap\" }>\n\ntype TranscriptViewerContextValue = UseTranscriptViewerResult & {\n  audioProps: Omit<ComponentPropsWithRef<\"audio\">, \"children\" | \"src\">\n}\n\nconst TranscriptViewerContext =\n  createContext<TranscriptViewerContextValue | null>(null)\n\nfunction useTranscriptViewerContext() {\n  const context = useContext(TranscriptViewerContext)\n  if (!context) {\n    throw new Error(\n      \"useTranscriptViewerContext must be used within a TranscriptViewer\"\n    )\n  }\n  return context\n}\n\ntype TranscriptViewerProviderProps = {\n  value: TranscriptViewerContextValue\n  children: ReactNode\n}\n\nfunction TranscriptViewerProvider({\n  value,\n  children,\n}: TranscriptViewerProviderProps) {\n  return (\n    <TranscriptViewerContext.Provider value={value}>\n      {children}\n    </TranscriptViewerContext.Provider>\n  )\n}\n\ntype AudioType =\n  | \"audio/mpeg\"\n  | \"audio/wav\"\n  | \"audio/ogg\"\n  | \"audio/mp3\"\n  | \"audio/m4a\"\n  | \"audio/aac\"\n  | \"audio/webm\"\n\ntype TranscriptViewerContainerProps = {\n  audioSrc: string\n  audioType: AudioType\n  alignment: CharacterAlignmentResponseModel\n  segmentComposer?: SegmentComposer\n  hideAudioTags?: boolean\n  children?: ReactNode\n} & Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> &\n  Pick<\n    Parameters<typeof useTranscriptViewer>[0],\n    \"onPlay\" | \"onPause\" | \"onTimeUpdate\" | \"onEnded\" | \"onDurationChange\"\n  >\n\nfunction TranscriptViewerContainer({\n  audioSrc,\n  audioType = \"audio/mpeg\",\n  alignment,\n  segmentComposer,\n  hideAudioTags = true,\n  children,\n  className,\n  onPlay,\n  onPause,\n  onTimeUpdate,\n  onEnded,\n  onDurationChange,\n  ...props\n}: TranscriptViewerContainerProps) {\n  const viewerState = useTranscriptViewer({\n    alignment,\n    hideAudioTags,\n    segmentComposer,\n    onPlay,\n    onPause,\n    onTimeUpdate,\n    onEnded,\n    onDurationChange,\n  })\n\n  const { audioRef } = viewerState\n\n  const audioProps = useMemo(\n    () => ({\n      ref: audioRef,\n      controls: false,\n      preload: \"metadata\" as const,\n      src: audioSrc,\n      children: <source src={audioSrc} type={audioType} />,\n    }),\n    [audioRef, audioSrc, audioType]\n  )\n\n  const contextValue = useMemo(\n    () => ({\n      ...viewerState,\n      audioProps,\n    }),\n    [viewerState, audioProps]\n  )\n\n  return (\n    <TranscriptViewerProvider value={contextValue}>\n      <div\n        data-slot=\"transcript-viewer-root\"\n        className={cn(\"space-y-4 p-4\", className)}\n        {...props}\n      >\n        {children}\n      </div>\n    </TranscriptViewerProvider>\n  )\n}\n\ntype TranscriptViewerWordStatus = \"spoken\" | \"unspoken\" | \"current\"\ninterface TranscriptViewerWordProps\n  extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n  word: TranscriptWordType\n  status: TranscriptViewerWordStatus\n  children?: ReactNode\n}\n\nfunction TranscriptViewerWord({\n  word,\n  status,\n  className,\n  children,\n  ...props\n}: TranscriptViewerWordProps) {\n  return (\n    <span\n      data-slot=\"transcript-word\"\n      data-kind=\"word\"\n      data-status={status}\n      className={cn(\n        \"rounded-sm px-0.5 transition-colors\",\n        status === \"spoken\" && \"text-foreground\",\n        status === \"unspoken\" && \"text-muted-foreground\",\n        status === \"current\" && \"bg-primary text-primary-foreground\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? word.text}\n    </span>\n  )\n}\n\ninterface TranscriptViewerWordsProps extends HTMLAttributes<HTMLDivElement> {\n  renderWord?: (props: {\n    word: TranscriptWordType\n    status: TranscriptViewerWordStatus\n  }) => ReactNode\n  renderGap?: (props: {\n    segment: TranscriptGap\n    status: TranscriptViewerWordStatus\n  }) => ReactNode\n  wordClassNames?: string\n  gapClassNames?: string\n}\n\nfunction TranscriptViewerWords({\n  className,\n  renderWord,\n  renderGap,\n  wordClassNames,\n  gapClassNames,\n  ...props\n}: TranscriptViewerWordsProps) {\n  const {\n    spokenSegments,\n    unspokenSegments,\n    currentWord,\n    segments,\n    duration,\n    currentTime,\n  } = useTranscriptViewerContext()\n\n  const nearEnd = useMemo(() => {\n    if (!duration) return false\n    return currentTime >= duration - 0.01\n  }, [currentTime, duration])\n\n  const segmentsWithStatus = useMemo(() => {\n    if (nearEnd) {\n      return segments.map((segment) => ({ segment, status: \"spoken\" as const }))\n    }\n\n    const entries: Array<{\n      segment: TranscriptSegment\n      status: TranscriptViewerWordStatus\n    }> = []\n\n    for (const segment of spokenSegments) {\n      entries.push({ segment, status: \"spoken\" })\n    }\n\n    if (currentWord) {\n      entries.push({ segment: currentWord, status: \"current\" })\n    }\n\n    for (const segment of unspokenSegments) {\n      entries.push({ segment, status: \"unspoken\" })\n    }\n\n    return entries\n  }, [spokenSegments, unspokenSegments, currentWord, nearEnd, segments])\n\n  return (\n    <div\n      data-slot=\"transcript-words\"\n      className={cn(\"text-xl leading-relaxed\", className)}\n      {...props}\n    >\n      {segmentsWithStatus.map(({ segment, status }) => {\n        if (segment.kind === \"gap\") {\n          const content = renderGap\n            ? renderGap({ segment, status })\n            : segment.text\n          return (\n            <span\n              key={`gap-${segment.segmentIndex}`}\n              data-kind=\"gap\"\n              data-status={status}\n              className={cn(gapClassNames)}\n            >\n              {content}\n            </span>\n          )\n        }\n\n        if (renderWord) {\n          return (\n            <span\n              key={`word-${segment.segmentIndex}`}\n              data-kind=\"word\"\n              data-status={status}\n              className={cn(wordClassNames)}\n            >\n              {renderWord({ word: segment, status })}\n            </span>\n          )\n        }\n\n        return (\n          <TranscriptViewerWord\n            key={`word-${segment.segmentIndex}`}\n            word={segment}\n            status={status}\n            className={wordClassNames}\n          />\n        )\n      })}\n    </div>\n  )\n}\n\nfunction TranscriptViewerAudio({\n  ...props\n}: ComponentPropsWithoutRef<\"audio\">) {\n  const { audioProps } = useTranscriptViewerContext()\n  return (\n    <audio\n      data-slot=\"transcript-audio\"\n      {...audioProps}\n      {...props}\n      ref={audioProps.ref}\n    />\n  )\n}\n\ntype RenderChildren = (state: { isPlaying: boolean }) => ReactNode\n\ntype TranscriptViewerPlayPauseButtonProps = Omit<\n  ComponentPropsWithoutRef<typeof Button>,\n  \"children\"\n> & {\n  children?: ReactNode | RenderChildren\n}\n\nfunction TranscriptViewerPlayPauseButton({\n  className,\n  children,\n  onClick,\n  ...props\n}: TranscriptViewerPlayPauseButtonProps) {\n  const { isPlaying, play, pause } = useTranscriptViewerContext()\n  const Icon = isPlaying ? Pause : Play\n\n  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n    if (isPlaying) pause()\n    else play()\n    onClick?.(event)\n  }\n\n  const content =\n    typeof children === \"function\"\n      ? (children as RenderChildren)({ isPlaying })\n      : children\n\n  return (\n    <Button\n      data-slot=\"transcript-play-pause-button\"\n      type=\"button\"\n      variant=\"outline\"\n      size=\"icon\"\n      aria-label={isPlaying ? \"Pause audio\" : \"Play audio\"}\n      data-playing={isPlaying}\n      className={cn(\"cursor-pointer\", className)}\n      onClick={handleClick}\n      {...props}\n    >\n      {content ?? <Icon className=\"size-5\" />}\n    </Button>\n  )\n}\n\ntype TranscriptViewerScrubBarProps = Omit<\n  ComponentPropsWithoutRef<typeof ScrubBarContainer>,\n  \"duration\" | \"value\" | \"onScrub\" | \"onScrubStart\" | \"onScrubEnd\"\n> & {\n  showTimeLabels?: boolean\n  labelsClassName?: string\n  trackClassName?: string\n  progressClassName?: string\n  thumbClassName?: string\n}\n\n/**\n * A context-aware implementation of the scrub bar specific to the transcript viewer.\n */\nfunction TranscriptViewerScrubBar({\n  className,\n  showTimeLabels = true,\n  labelsClassName,\n  trackClassName,\n  progressClassName,\n  thumbClassName,\n  ...props\n}: TranscriptViewerScrubBarProps) {\n  const { duration, currentTime, seekToTime, startScrubbing, endScrubbing } =\n    useTranscriptViewerContext()\n  return (\n    <ScrubBarContainer\n      data-slot=\"transcript-scrub-bar\"\n      duration={duration}\n      value={currentTime}\n      onScrubStart={startScrubbing}\n      onScrubEnd={endScrubbing}\n      onScrub={seekToTime}\n      className={className}\n      {...props}\n    >\n      <div className=\"flex flex-1 flex-col gap-1\">\n        <ScrubBarTrack className={trackClassName}>\n          <ScrubBarProgress className={progressClassName} />\n          <ScrubBarThumb className={thumbClassName} />\n        </ScrubBarTrack>\n        {showTimeLabels && (\n          <div\n            className={cn(\n              \"text-muted-foreground flex items-center justify-between text-xs\",\n              labelsClassName\n            )}\n          >\n            <ScrubBarTimeLabel time={currentTime} />\n            <ScrubBarTimeLabel time={duration - currentTime} />\n          </div>\n        )}\n      </div>\n    </ScrubBarContainer>\n  )\n}\n\nexport {\n  TranscriptViewerContainer,\n  TranscriptViewerWords,\n  TranscriptViewerWord,\n  TranscriptViewerAudio,\n  TranscriptViewerPlayPauseButton,\n  TranscriptViewerScrubBar,\n  TranscriptViewerProvider,\n  useTranscriptViewerContext,\n}\nexport type { CharacterAlignmentResponseModel }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/scrub-bar.tsx",
          "target": "@components/voice-agents/elevenlabs/scrub-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Progress } from \"@/components/ui/progress\"\nimport { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useRef,\n  type ComponentProps,\n  type HTMLAttributes,\n} from \"react\"\n\nfunction formatTimestamp(value: number) {\n  if (!Number.isFinite(value) || value < 0) return \"0:00\"\n  const totalSeconds = Math.floor(value)\n  const minutes = Math.floor(totalSeconds / 60)\n  const seconds = totalSeconds % 60\n  return `${minutes}:${seconds.toString().padStart(2, \"0\")}`\n}\n\ninterface ScrubBarContextValue {\n  duration: number\n  value: number\n  progress: number\n  onScrub?: (time: number) => void\n  onScrubStart?: () => void\n  onScrubEnd?: () => void\n}\n\nconst ScrubBarContext = createContext<ScrubBarContextValue | null>(null)\n\nfunction useScrubBarContext() {\n  const context = useContext(ScrubBarContext)\n  if (!context) {\n    throw new Error(\"useScrubBarContext must be used within a ScrubBar.Root\")\n  }\n  return context\n}\n\ninterface ScrubBarContainerProps extends HTMLAttributes<HTMLDivElement> {\n  duration: number\n  value: number\n  onScrub?: (time: number) => void\n  onScrubStart?: () => void\n  onScrubEnd?: () => void\n}\n\nfunction ScrubBarContainer({\n  duration,\n  value,\n  onScrub,\n  onScrubStart,\n  onScrubEnd,\n  children,\n  className,\n  ...props\n}: ScrubBarContainerProps) {\n  const progress = duration > 0 ? (value / duration) * 100 : 0\n\n  const contextValue: ScrubBarContextValue = {\n    duration,\n    value,\n    progress,\n    onScrub,\n    onScrubStart,\n    onScrubEnd,\n  }\n\n  return (\n    <ScrubBarContext.Provider value={contextValue}>\n      <div\n        data-slot=\"scrub-bar-root\"\n        className={cn(\"flex w-full items-center\", className)}\n        {...props}\n      >\n        {children}\n      </div>\n    </ScrubBarContext.Provider>\n  )\n}\nScrubBarContainer.displayName = \"ScrubBarContainer\"\n\ntype ScrubBarTrackProps = HTMLAttributes<HTMLDivElement>\n\nfunction ScrubBarTrack({ className, children, ...props }: ScrubBarTrackProps) {\n  const trackRef = useRef<HTMLDivElement | null>(null)\n  const { duration, onScrub, onScrubStart, onScrubEnd, value } =\n    useScrubBarContext()\n\n  const getTimeFromClientX = useCallback(\n    (clientX: number) => {\n      const track = trackRef.current\n      if (!track || !duration) return null\n      const rect = track.getBoundingClientRect()\n      const ratio = (clientX - rect.left) / rect.width\n      const clamped = Math.min(Math.max(ratio, 0), 1)\n      return duration * clamped\n    },\n    [duration]\n  )\n\n  const handlePointerDown = useCallback(\n    (event: React.PointerEvent<HTMLDivElement>) => {\n      if (!duration) return\n      event.preventDefault()\n      onScrubStart?.()\n      const time = getTimeFromClientX(event.clientX)\n      if (time != null) {\n        onScrub?.(time)\n      }\n\n      const handleMove = (moveEvent: PointerEvent) => {\n        const nextTime = getTimeFromClientX(moveEvent.clientX)\n        if (nextTime != null) {\n          onScrub?.(nextTime)\n        }\n      }\n\n      const handleUp = () => {\n        onScrubEnd?.()\n        window.removeEventListener(\"pointermove\", handleMove)\n        window.removeEventListener(\"pointerup\", handleUp)\n      }\n\n      window.addEventListener(\"pointermove\", handleMove)\n      window.addEventListener(\"pointerup\", handleUp, { once: true })\n    },\n    [duration, getTimeFromClientX, onScrub, onScrubEnd, onScrubStart]\n  )\n\n  const clampedValue = Math.min(Math.max(value, 0), duration || 0)\n\n  return (\n    <div\n      ref={trackRef}\n      data-slot=\"scrub-bar-track\"\n      className={cn(\n        \"bg-secondary relative h-2 w-full grow cursor-pointer touch-none rounded-full transition-none select-none\",\n        className\n      )}\n      onPointerDown={handlePointerDown}\n      role=\"slider\"\n      aria-valuemin={0}\n      aria-valuemax={duration || 0}\n      aria-valuenow={clampedValue}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\nScrubBarTrack.displayName = \"ScrubBarTrack\"\n\ntype ScrubBarProgressProps = Omit<ComponentProps<typeof Progress>, \"value\">\n\nfunction ScrubBarProgress({ className, ...props }: ScrubBarProgressProps) {\n  const { progress } = useScrubBarContext()\n\n  return (\n    <Progress\n      data-slot=\"scrub-bar-progress\"\n      value={progress}\n      className={cn(\"absolute h-full [&>div]:transition-none\", className)}\n      {...props}\n    />\n  )\n}\nScrubBarProgress.displayName = \"ScrubBarProgress\"\n\ntype ScrubBarThumbProps = HTMLAttributes<HTMLDivElement>\n\nfunction ScrubBarThumb({ className, children, ...props }: ScrubBarThumbProps) {\n  const { progress } = useScrubBarContext()\n  return (\n    <div\n      data-slot=\"scrub-bar-thumb\"\n      className={cn(\n        \"bg-primary absolute top-1/2 block h-4 w-4 -translate-x-1/2 -translate-y-1/2 rounded-full transition-colors disabled:pointer-events-none disabled:opacity-50\",\n        className\n      )}\n      style={{ left: `${progress}%` }}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\nScrubBarThumb.displayName = \"ScrubBarThumb\"\n\ninterface ScrubBarTimeLabelProps extends HTMLAttributes<HTMLSpanElement> {\n  time: number\n  format?: (time: number) => string\n}\n\nfunction ScrubBarTimeLabel({\n  className,\n  time,\n  format = formatTimestamp,\n  ...props\n}: ScrubBarTimeLabelProps) {\n  return (\n    <span\n      data-slot=\"scrub-bar-time-label\"\n      {...props}\n      className={cn(\"tabular-nums\", className)}\n    >\n      {format(time)}\n    </span>\n  )\n}\nScrubBarTimeLabel.displayName = \"ScrubBarTimeLabel\"\n\nexport {\n  ScrubBarContainer,\n  ScrubBarTrack,\n  ScrubBarProgress,\n  ScrubBarThumb,\n  ScrubBarTimeLabel,\n}\n"
        },
        {
          "path": "components/ui/progress.tsx",
          "target": "@components/ui/progress.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Progress = React.forwardRef<\n  React.ElementRef<typeof ProgressPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>\n>(({ className, value, ...props }, ref) => (\n  <ProgressPrimitive.Root\n    ref={ref}\n    className={cn(\n      \"relative h-2 w-full overflow-hidden rounded-full bg-secondary\",\n      className\n    )}\n    {...props}\n  >\n    <ProgressPrimitive.Indicator\n      className=\"h-full w-full flex-1 bg-primary transition-all\"\n      style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n    />\n  </ProgressPrimitive.Root>\n))\nProgress.displayName = ProgressPrimitive.Root.displayName\n\nexport { Progress }\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/types.ts",
          "target": "@components/voice-agents/elevenlabs/types.ts",
          "type": "registry:component",
          "content": "export interface CharacterAlignmentResponseModel {\n  characters: string[]\n  characterStartTimesSeconds: number[]\n  characterEndTimesSeconds: number[]\n}\n\nexport interface ElevenLabsVoice {\n  voiceId?: string\n  name?: string\n  previewUrl?: string\n  labels?: Record<string, string | undefined>\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/use-transcript-viewer.ts",
          "target": "@components/voice-agents/elevenlabs/use-transcript-viewer.ts",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type { CharacterAlignmentResponseModel } from \"@/components/voice-agents/elevenlabs/types\"\nimport {\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n  type RefObject,\n} from \"react\"\n\ntype ComposeSegmentsOptions = {\n  hideAudioTags?: boolean\n}\n\ntype BaseSegment = {\n  segmentIndex: number\n  text: string\n}\n\ntype TranscriptWord = BaseSegment & {\n  kind: \"word\"\n  wordIndex: number\n  startTime: number\n  endTime: number\n}\n\ntype GapSegment = BaseSegment & {\n  kind: \"gap\"\n}\n\ntype TranscriptSegment = TranscriptWord | GapSegment\n\ntype ComposeSegmentsResult = {\n  segments: TranscriptSegment[]\n  words: TranscriptWord[]\n}\n\ntype SegmentComposer = (\n  alignment: CharacterAlignmentResponseModel\n) => ComposeSegmentsResult\n\nfunction composeSegments(\n  alignment: CharacterAlignmentResponseModel,\n  options: ComposeSegmentsOptions = {}\n): ComposeSegmentsResult {\n  const {\n    characters,\n    characterStartTimesSeconds: starts,\n    characterEndTimesSeconds: ends,\n  } = alignment\n\n  const segments: TranscriptSegment[] = []\n  const words: TranscriptWord[] = []\n\n  let wordBuffer = \"\"\n  let whitespaceBuffer = \"\"\n  let wordStart = 0\n  let wordEnd = 0\n  let segmentIndex = 0\n  let wordIndex = 0\n  let insideAudioTag = false\n\n  const hideAudioTags = options.hideAudioTags ?? false\n\n  const flushWhitespace = () => {\n    if (!whitespaceBuffer) return\n    segments.push({\n      kind: \"gap\",\n      segmentIndex: segmentIndex++,\n      text: whitespaceBuffer,\n    })\n    whitespaceBuffer = \"\"\n  }\n\n  const flushWord = () => {\n    if (!wordBuffer) return\n    const word: TranscriptWord = {\n      kind: \"word\",\n      segmentIndex: segmentIndex++,\n      wordIndex: wordIndex++,\n      text: wordBuffer,\n      startTime: wordStart,\n      endTime: wordEnd,\n    }\n    segments.push(word)\n    words.push(word)\n    wordBuffer = \"\"\n  }\n\n  for (let i = 0; i < characters.length; i++) {\n    const char = characters[i]\n    const start = starts[i] ?? 0\n    const end = ends[i] ?? start\n\n    if (hideAudioTags) {\n      if (char === \"[\") {\n        flushWord()\n        whitespaceBuffer = \"\"\n        insideAudioTag = true\n        continue\n      }\n\n      if (insideAudioTag) {\n        if (char === \"]\") insideAudioTag = false\n        continue\n      }\n    }\n\n    if (/\\s/.test(char)) {\n      flushWord()\n      whitespaceBuffer += char\n      continue\n    }\n\n    if (whitespaceBuffer) {\n      flushWhitespace()\n    }\n\n    if (!wordBuffer) {\n      wordBuffer = char\n      wordStart = start\n      wordEnd = end\n    } else {\n      wordBuffer += char\n      wordEnd = end\n    }\n  }\n\n  flushWord()\n  flushWhitespace()\n\n  return { segments, words }\n}\n\ntype UseTranscriptViewerProps = {\n  alignment: CharacterAlignmentResponseModel\n  segmentComposer?: SegmentComposer\n  hideAudioTags?: boolean\n  onPlay?: () => void\n  onPause?: () => void\n  onTimeUpdate?: (time: number) => void\n  onEnded?: () => void\n  onDurationChange?: (duration: number) => void\n}\n\ntype UseTranscriptViewerResult = {\n  segments: TranscriptSegment[]\n  words: TranscriptWord[]\n  spokenSegments: TranscriptSegment[]\n  unspokenSegments: TranscriptSegment[]\n  currentWord: TranscriptWord | null\n  currentSegmentIndex: number\n  currentWordIndex: number\n  seekToTime: (time: number) => void\n  seekToWord: (word: number | TranscriptWord) => void\n  audioRef: RefObject<HTMLAudioElement | null>\n  isPlaying: boolean\n  isScrubbing: boolean\n  duration: number\n  currentTime: number\n  play: () => void\n  pause: () => void\n  startScrubbing: () => void\n  endScrubbing: () => void\n}\n\nfunction useTranscriptViewer({\n  alignment,\n  hideAudioTags = true,\n  segmentComposer,\n  onPlay,\n  onPause,\n  onTimeUpdate,\n  onEnded,\n  onDurationChange,\n}: UseTranscriptViewerProps): UseTranscriptViewerResult {\n  const audioRef = useRef<HTMLAudioElement | null>(null)\n  const rafRef = useRef<number | null>(null)\n  const handleTimeUpdateRef = useRef<(time: number) => void>(() => {})\n  const onDurationChangeRef = useRef<(duration: number) => void>(() => {})\n\n  const [isPlaying, setIsPlaying] = useState(false)\n  const [isScrubbing, setIsScrubbing] = useState(false)\n  const [duration, setDuration] = useState(0)\n  const [currentTime, setCurrentTime] = useState(0)\n\n  const { segments, words } = useMemo(() => {\n    if (segmentComposer) {\n      return segmentComposer(alignment)\n    }\n    return composeSegments(alignment, { hideAudioTags })\n  }, [segmentComposer, alignment, hideAudioTags])\n\n  // Best-effort duration guess from alignment data while metadata loads\n  const guessedDuration = useMemo(() => {\n    const ends = alignment?.characterEndTimesSeconds\n    if (Array.isArray(ends) && ends.length) {\n      const last = ends[ends.length - 1]\n      return Number.isFinite(last) ? last : 0\n    }\n    if (words.length) {\n      const lastWord = words[words.length - 1]\n      return Number.isFinite(lastWord.endTime) ? lastWord.endTime : 0\n    }\n    return 0\n  }, [alignment, words])\n\n  const [currentWordIndex, setCurrentWordIndex] = useState<number>(() =>\n    words.length ? 0 : -1\n  )\n\n  useEffect(() => {\n    setCurrentTime(0)\n    setDuration(guessedDuration)\n    setIsPlaying(false)\n    setCurrentWordIndex(words.length ? 0 : -1)\n  }, [words.length, alignment, guessedDuration])\n\n  const findWordIndex = useCallback(\n    (time: number) => {\n      if (!words.length) return -1\n      let lo = 0\n      let hi = words.length - 1\n      let answer = -1\n      while (lo <= hi) {\n        const mid = Math.floor((lo + hi) / 2)\n        const word = words[mid]\n        if (time >= word.startTime && time < word.endTime) {\n          answer = mid\n          break\n        }\n        if (time < word.startTime) {\n          hi = mid - 1\n        } else {\n          lo = mid + 1\n        }\n      }\n      return answer\n    },\n    [words]\n  )\n\n  const handleTimeUpdate = useCallback(\n    (currentTime: number) => {\n      if (!words.length) return\n\n      const currentWord =\n        currentWordIndex >= 0 && currentWordIndex < words.length\n          ? words[currentWordIndex]\n          : undefined\n\n      if (!currentWord) {\n        const found = findWordIndex(currentTime)\n        if (found !== -1) setCurrentWordIndex(found)\n        return\n      }\n\n      let next = currentWordIndex\n      if (\n        currentTime >= currentWord.endTime &&\n        currentWordIndex + 1 < words.length\n      ) {\n        while (\n          next + 1 < words.length &&\n          currentTime >= words[next + 1].startTime\n        ) {\n          next++\n        }\n        // If we're inside the next word's window, pick it.\n        if (currentTime < words[next].endTime) {\n          setCurrentWordIndex(next)\n          return\n        }\n        // If we landed in a timing gap (no word contains currentTime),\n        // snap to the latest word that started at or before currentTime.\n        setCurrentWordIndex(next)\n        return\n      }\n\n      if (currentTime < currentWord.startTime) {\n        const found = findWordIndex(currentTime)\n        if (found !== -1) setCurrentWordIndex(found)\n        return\n      }\n\n      const found = findWordIndex(currentTime)\n      if (found !== -1 && found !== currentWordIndex) {\n        setCurrentWordIndex(found)\n      }\n    },\n    [findWordIndex, currentWordIndex, words]\n  )\n\n  useEffect(() => {\n    handleTimeUpdateRef.current = handleTimeUpdate\n  }, [handleTimeUpdate])\n\n  useEffect(() => {\n    onDurationChangeRef.current = onDurationChange ?? (() => {})\n  }, [onDurationChange])\n\n  const stopRaf = useCallback(() => {\n    if (rafRef.current != null) {\n      cancelAnimationFrame(rafRef.current)\n      rafRef.current = null\n    }\n  }, [])\n\n  const startRaf = useCallback(() => {\n    if (rafRef.current != null) return\n    const tick = () => {\n      const node = audioRef.current\n      if (!node) {\n        rafRef.current = null\n        return\n      }\n      const time = node.currentTime\n      setCurrentTime(time)\n      handleTimeUpdateRef.current(time)\n      // Opportunistically pick up duration when metadata arrives, even if\n      // duration events were missed or coalesced by the browser.\n      if (Number.isFinite(node.duration) && node.duration > 0) {\n        setDuration((prev) => {\n          if (!prev) {\n            onDurationChangeRef.current(node.duration)\n            return node.duration\n          }\n          return prev\n        })\n      }\n      rafRef.current = requestAnimationFrame(tick)\n    }\n    rafRef.current = requestAnimationFrame(tick)\n  }, [audioRef])\n\n  useEffect(() => {\n    const audio = audioRef.current\n    if (!audio) return\n\n    const syncPlayback = () => setIsPlaying(!audio.paused)\n    const syncTime = () => setCurrentTime(audio.currentTime)\n    const syncDuration = () =>\n      setDuration(Number.isFinite(audio.duration) ? audio.duration : 0)\n\n    const handlePlay = () => {\n      syncPlayback()\n      startRaf()\n      onPlay?.()\n    }\n    const handlePause = () => {\n      syncPlayback()\n      syncTime()\n      stopRaf()\n      onPause?.()\n    }\n    const handleEnded = () => {\n      syncPlayback()\n      syncTime()\n      stopRaf()\n      onEnded?.()\n    }\n    const handleTimeUpdate = () => {\n      syncTime()\n      onTimeUpdate?.(audio.currentTime)\n    }\n    const handleSeeked = () => {\n      syncTime()\n      handleTimeUpdateRef.current(audio.currentTime)\n    }\n    const handleDuration = () => {\n      syncDuration()\n      onDurationChange?.(audio.duration)\n    }\n\n    syncPlayback()\n    syncTime()\n    syncDuration()\n    if (!audio.paused) {\n      startRaf()\n    } else {\n      stopRaf()\n    }\n\n    audio.addEventListener(\"play\", handlePlay)\n    audio.addEventListener(\"pause\", handlePause)\n    audio.addEventListener(\"ended\", handleEnded)\n    audio.addEventListener(\"timeupdate\", handleTimeUpdate)\n    audio.addEventListener(\"seeked\", handleSeeked)\n    audio.addEventListener(\"durationchange\", handleDuration)\n    audio.addEventListener(\"loadedmetadata\", handleDuration)\n\n    return () => {\n      stopRaf()\n      audio.removeEventListener(\"play\", handlePlay)\n      audio.removeEventListener(\"pause\", handlePause)\n      audio.removeEventListener(\"ended\", handleEnded)\n      audio.removeEventListener(\"timeupdate\", handleTimeUpdate)\n      audio.removeEventListener(\"seeked\", handleSeeked)\n      audio.removeEventListener(\"durationchange\", handleDuration)\n      audio.removeEventListener(\"loadedmetadata\", handleDuration)\n    }\n  }, [\n    audioRef,\n    startRaf,\n    stopRaf,\n    onPlay,\n    onPause,\n    onEnded,\n    onTimeUpdate,\n    onDurationChange,\n  ])\n\n  const seekToTime = useCallback(\n    (time: number) => {\n      const node = audioRef.current\n      if (!node) return\n      // Optimistically update UI time immediately to reflect the seek,\n      // since some browsers coalesce timeupdate/seeked events under rapid seeks.\n      setCurrentTime(time)\n      node.currentTime = time\n      handleTimeUpdateRef.current(time)\n    },\n    [audioRef]\n  )\n\n  const seekToWord = useCallback(\n    (word: number | TranscriptWord) => {\n      const target = typeof word === \"number\" ? words[word] : word\n      if (!target) return\n      seekToTime(target.startTime)\n    },\n    [seekToTime, words]\n  )\n\n  const play = useCallback(() => {\n    const audio = audioRef.current\n    if (!audio) return\n    if (audio.paused) {\n      void audio.play()\n    }\n  }, [audioRef])\n\n  const pause = useCallback(() => {\n    const audio = audioRef.current\n    if (audio && !audio.paused) {\n      audio.pause()\n    }\n  }, [audioRef])\n\n  const startScrubbing = useCallback(() => {\n    setIsScrubbing(true)\n    stopRaf()\n  }, [stopRaf])\n\n  const endScrubbing = useCallback(() => {\n    setIsScrubbing(false)\n    const node = audioRef.current\n    if (node && !node.paused) {\n      startRaf()\n    }\n  }, [audioRef, startRaf])\n\n  const currentWord =\n    currentWordIndex >= 0 && currentWordIndex < words.length\n      ? words[currentWordIndex]\n      : null\n  const currentSegmentIndex = currentWord?.segmentIndex ?? -1\n\n  const spokenSegments = useMemo(() => {\n    if (!segments.length || currentSegmentIndex <= 0) return []\n    return segments.slice(0, currentSegmentIndex)\n  }, [segments, currentSegmentIndex])\n\n  const unspokenSegments = useMemo(() => {\n    if (!segments.length) return []\n    if (currentSegmentIndex === -1) return segments\n    if (currentSegmentIndex + 1 >= segments.length) return []\n    return segments.slice(currentSegmentIndex + 1)\n  }, [segments, currentSegmentIndex])\n\n  return {\n    segments,\n    words,\n    spokenSegments,\n    unspokenSegments,\n    currentWord,\n    currentSegmentIndex,\n    currentWordIndex,\n    seekToTime,\n    seekToWord,\n    audioRef,\n    isPlaying,\n    isScrubbing,\n    duration,\n    currentTime,\n    play,\n    pause,\n    startScrubbing,\n    endScrubbing,\n  }\n}\n\nexport { useTranscriptViewer }\nexport type {\n  UseTranscriptViewerProps,\n  UseTranscriptViewerResult,\n  ComposeSegmentsOptions,\n  ComposeSegmentsResult,\n  SegmentComposer,\n  TranscriptSegment,\n  TranscriptWord,\n  CharacterAlignmentResponseModel,\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-voice-button",
      "type": "registry:block",
      "title": "Elevenlabs Voice Button",
      "description": "Voice Button",
      "dependencies": [
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/voice-button.tsx",
          "target": "@components/voice-agents/elevenlabs/voice-button.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { LiveWaveform } from \"@/components/voice-agents/elevenlabs/live-waveform\"\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, XIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport type VoiceButtonState =\n  | \"idle\"\n  | \"recording\"\n  | \"processing\"\n  | \"success\"\n  | \"error\"\n\nexport interface VoiceButtonProps\n  extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"onError\"> {\n  /**\n   * Current state of the voice button\n   * @default \"idle\"\n   */\n  state?: VoiceButtonState\n\n  /**\n   * Callback when button is clicked\n   */\n  onPress?: () => void\n\n  /**\n   * Content to display on the left side (label)\n   * Can be a string or ReactNode for custom components\n   */\n  label?: React.ReactNode\n\n  /**\n   * Content to display on the right side (e.g., keyboard shortcut)\n   * Can be a string or ReactNode for custom components\n   * @example \"⌥Space\" or <kbd>⌘K</kbd>\n   */\n  trailing?: React.ReactNode\n\n  /**\n   * Icon to display in the center when idle (for icon size buttons)\n   */\n  icon?: React.ReactNode\n\n  /**\n   * Custom variant for the button\n   * @default \"outline\"\n   */\n  variant?:\n    | \"default\"\n    | \"destructive\"\n    | \"outline\"\n    | \"secondary\"\n    | \"ghost\"\n    | \"link\"\n\n  /**\n   * Size of the button\n   * @default \"default\"\n   */\n  size?: \"default\" | \"sm\" | \"lg\" | \"icon\"\n\n  /**\n   * Custom className for the button\n   */\n  className?: string\n\n  /**\n   * Custom className for the waveform container\n   */\n  waveformClassName?: string\n\n  /**\n   * Duration in ms to show success/error states\n   * @default 1500\n   */\n  feedbackDuration?: number\n\n  /**\n   * Disable the button\n   */\n  disabled?: boolean\n}\n\nexport function shouldCaptureVoiceButton(\n  state: VoiceButtonState,\n  disabled?: boolean\n) {\n  return state === \"recording\" && !disabled\n}\n\nexport const VoiceButton = React.forwardRef<\n  HTMLButtonElement,\n  VoiceButtonProps\n>(\n  (\n    {\n      state = \"idle\",\n      onPress,\n      label,\n      trailing,\n      icon,\n      variant = \"outline\",\n      size = \"default\",\n      className,\n      waveformClassName,\n      feedbackDuration = 1500,\n      disabled,\n      onClick,\n      ...props\n    },\n    ref\n  ) => {\n    const [showFeedback, setShowFeedback] = React.useState(false)\n\n    React.useEffect(() => {\n      if (state === \"success\" || state === \"error\") {\n        setShowFeedback(true)\n        const timeout = setTimeout(\n          () => setShowFeedback(false),\n          feedbackDuration\n        )\n        return () => clearTimeout(timeout)\n      } else {\n        // Reset feedback when state changes away from success/error\n        setShowFeedback(false)\n      }\n    }, [state, feedbackDuration])\n\n    const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n      onClick?.(e)\n      onPress?.()\n    }\n\n    const isRecording = state === \"recording\"\n    const isProcessing = state === \"processing\"\n    const isSuccess = state === \"success\"\n    const isError = state === \"error\"\n\n    const buttonVariant = variant\n    const isDisabled = disabled || isProcessing\n\n    const displayLabel = label\n\n    const shouldShowWaveform = isRecording || isProcessing || showFeedback\n    const shouldShowTrailing = !shouldShowWaveform && trailing\n\n    return (\n      <Button\n        ref={ref}\n        type=\"button\"\n        variant={buttonVariant}\n        size={size}\n        onClick={handleClick}\n        disabled={isDisabled}\n        className={cn(\n          \"gap-2 transition-all duration-200\",\n          size === \"icon\" && \"relative\",\n          className\n        )}\n        aria-label={typeof label === \"string\" ? label : \"Voice Button\"}\n        {...props}\n      >\n        {size !== \"icon\" && displayLabel && (\n          <span className=\"inline-flex shrink-0 items-center justify-start\">\n            {displayLabel}\n          </span>\n        )}\n\n        <div\n          className={cn(\n            \"relative box-content flex shrink-0 items-center justify-center overflow-hidden transition-all duration-300\",\n            size === \"icon\"\n              ? \"absolute inset-0 rounded-sm border-0\"\n              : \"h-5 w-24 rounded-sm border\",\n            isRecording\n              ? \"bg-primary/10 dark:bg-primary/5\"\n              : size === \"icon\"\n                ? \"bg-muted/50 border-0\"\n                : \"border-border bg-muted/50\",\n            waveformClassName\n          )}\n        >\n          {shouldShowWaveform && (\n            <LiveWaveform\n              active={shouldCaptureVoiceButton(state, disabled)}\n              processing={isProcessing || isSuccess}\n              barWidth={2}\n              barGap={1}\n              barRadius={4}\n              fadeEdges={false}\n              sensitivity={1.8}\n              smoothingTimeConstant={0.85}\n              height={20}\n              mode=\"static\"\n              className=\"animate-in fade-in absolute inset-0 h-full w-full duration-300\"\n            />\n          )}\n\n          {shouldShowTrailing && (\n            <div className=\"animate-in fade-in absolute inset-0 flex items-center justify-center duration-300\">\n              {typeof trailing === \"string\" ? (\n                <span className=\"text-muted-foreground px-1.5 font-mono text-[10px] font-medium select-none\">\n                  {trailing}\n                </span>\n              ) : (\n                trailing\n              )}\n            </div>\n          )}\n\n          {!shouldShowWaveform &&\n            !shouldShowTrailing &&\n            icon &&\n            size === \"icon\" && (\n              <div className=\"animate-in fade-in absolute inset-0 flex items-center justify-center duration-300\">\n                {icon}\n              </div>\n            )}\n\n          {isSuccess && showFeedback && (\n            <div className=\"animate-in fade-in bg-background/80 absolute inset-0 flex items-center justify-center duration-300\">\n              <span className=\"text-primary text-[10px] font-medium\">\n                <CheckIcon className=\"size-3.5\" />\n              </span>\n            </div>\n          )}\n\n          {/* Error Icon */}\n          {isError && showFeedback && (\n            <div className=\"animate-in fade-in bg-background/80 absolute inset-0 flex items-center justify-center duration-300\">\n              <span className=\"text-destructive text-[10px] font-medium\">\n                <XIcon className=\"size-3.5\" />\n              </span>\n            </div>\n          )}\n        </div>\n      </Button>\n    )\n  }\n)\n\nVoiceButton.displayName = \"VoiceButton\"\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/live-waveform.tsx",
          "target": "@components/voice-agents/elevenlabs/live-waveform.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { acquireMediaStream } from \"@/components/voice-agents/elevenlabs/media\"\nimport { cn } from \"@/lib/utils\"\nimport { useEffect, useRef, type HTMLAttributes } from \"react\"\n\nexport type LiveWaveformProps = HTMLAttributes<HTMLDivElement> & {\n  active?: boolean\n  processing?: boolean\n  deviceId?: string\n  barWidth?: number\n  barHeight?: number\n  barGap?: number\n  barRadius?: number\n  barColor?: string\n  fadeEdges?: boolean\n  fadeWidth?: number\n  height?: string | number\n  sensitivity?: number\n  smoothingTimeConstant?: number\n  fftSize?: number\n  historySize?: number\n  updateRate?: number\n  mode?: \"scrolling\" | \"static\"\n  onError?: (error: Error) => void\n  onStreamReady?: (stream: MediaStream) => void\n  onStreamEnd?: () => void\n}\n\nexport const LiveWaveform = ({\n  active = false,\n  processing = false,\n  deviceId,\n  barWidth = 3,\n  barGap = 1,\n  barRadius = 1.5,\n  barColor,\n  fadeEdges = true,\n  fadeWidth = 24,\n  barHeight: baseBarHeight = 4,\n  height = 64,\n  sensitivity = 1,\n  smoothingTimeConstant = 0.8,\n  fftSize = 256,\n  historySize = 60,\n  updateRate = 30,\n  mode = \"static\",\n  onError,\n  onStreamReady,\n  onStreamEnd,\n  className,\n  ...props\n}: LiveWaveformProps) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const historyRef = useRef<number[]>([])\n  const analyserRef = useRef<AnalyserNode | null>(null)\n  const audioContextRef = useRef<AudioContext | null>(null)\n  const streamRef = useRef<MediaStream | null>(null)\n  const animationRef = useRef<number>(0)\n  const lastUpdateRef = useRef<number>(0)\n  const processingAnimationRef = useRef<number | null>(null)\n  const lastActiveDataRef = useRef<number[]>([])\n  const transitionProgressRef = useRef(0)\n  const staticBarsRef = useRef<number[]>([])\n  const needsRedrawRef = useRef(true)\n  const gradientCacheRef = useRef<CanvasGradient | null>(null)\n  const lastWidthRef = useRef(0)\n  const redrawRef = useRef<() => void>(() => {})\n\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n  // Handle canvas resizing\n  useEffect(() => {\n    const canvas = canvasRef.current\n    const container = containerRef.current\n    if (!canvas || !container) return\n\n    const resizeObserver = new ResizeObserver(() => {\n      const rect = container.getBoundingClientRect()\n      const dpr = window.devicePixelRatio || 1\n\n      canvas.width = rect.width * dpr\n      canvas.height = rect.height * dpr\n      canvas.style.width = `${rect.width}px`\n      canvas.style.height = `${rect.height}px`\n\n      const ctx = canvas.getContext(\"2d\")\n      if (ctx) {\n        ctx.scale(dpr, dpr)\n      }\n\n      gradientCacheRef.current = null\n      lastWidthRef.current = rect.width\n      needsRedrawRef.current = true\n      redrawRef.current()\n    })\n\n    resizeObserver.observe(container)\n    return () => resizeObserver.disconnect()\n  }, [])\n\n  useEffect(() => {\n    const reduceMotion = window.matchMedia(\n      \"(prefers-reduced-motion: reduce)\"\n    ).matches\n    if (processing && !active) {\n      let time = 0\n      transitionProgressRef.current = 0\n\n      const animateProcessing = () => {\n        time += 0.03\n        transitionProgressRef.current = Math.min(\n          1,\n          transitionProgressRef.current + 0.02\n        )\n\n        const processingData = []\n        const barCount = Math.floor(\n          (containerRef.current?.getBoundingClientRect().width || 200) /\n            (barWidth + barGap)\n        )\n\n        if (mode === \"static\") {\n          const halfCount = Math.floor(barCount / 2)\n\n          for (let i = 0; i < barCount; i++) {\n            const normalizedPosition = (i - halfCount) / halfCount\n            const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n            const wave1 = Math.sin(time * 1.5 + normalizedPosition * 3) * 0.25\n            const wave2 = Math.sin(time * 0.8 - normalizedPosition * 2) * 0.2\n            const wave3 = Math.cos(time * 2 + normalizedPosition) * 0.15\n            const combinedWave = wave1 + wave2 + wave3\n            const processingValue = (0.2 + combinedWave) * centerWeight\n\n            let finalValue = processingValue\n            if (\n              lastActiveDataRef.current.length > 0 &&\n              transitionProgressRef.current < 1\n            ) {\n              const lastDataIndex = Math.min(\n                i,\n                lastActiveDataRef.current.length - 1\n              )\n              const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n              finalValue =\n                lastValue * (1 - transitionProgressRef.current) +\n                processingValue * transitionProgressRef.current\n            }\n\n            processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n          }\n        } else {\n          for (let i = 0; i < barCount; i++) {\n            const normalizedPosition = (i - barCount / 2) / (barCount / 2)\n            const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n            const wave1 = Math.sin(time * 1.5 + i * 0.15) * 0.25\n            const wave2 = Math.sin(time * 0.8 - i * 0.1) * 0.2\n            const wave3 = Math.cos(time * 2 + i * 0.05) * 0.15\n            const combinedWave = wave1 + wave2 + wave3\n            const processingValue = (0.2 + combinedWave) * centerWeight\n\n            let finalValue = processingValue\n            if (\n              lastActiveDataRef.current.length > 0 &&\n              transitionProgressRef.current < 1\n            ) {\n              const lastDataIndex = Math.floor(\n                (i / barCount) * lastActiveDataRef.current.length\n              )\n              const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n              finalValue =\n                lastValue * (1 - transitionProgressRef.current) +\n                processingValue * transitionProgressRef.current\n            }\n\n            processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n          }\n        }\n\n        if (mode === \"static\") {\n          staticBarsRef.current = processingData\n        } else {\n          historyRef.current = processingData\n        }\n\n        needsRedrawRef.current = true\n        redrawRef.current()\n        if (!reduceMotion) {\n          processingAnimationRef.current =\n            requestAnimationFrame(animateProcessing)\n        }\n      }\n\n      animateProcessing()\n\n      return () => {\n        if (processingAnimationRef.current) {\n          cancelAnimationFrame(processingAnimationRef.current)\n        }\n      }\n    } else if (!active && !processing) {\n      const hasData =\n        mode === \"static\"\n          ? staticBarsRef.current.length > 0\n          : historyRef.current.length > 0\n\n      if (hasData) {\n        if (reduceMotion) {\n          staticBarsRef.current = []\n          historyRef.current = []\n          needsRedrawRef.current = true\n          redrawRef.current()\n          return\n        }\n        let fadeProgress = 0\n        let fadeFrame = 0\n        const fadeToIdle = () => {\n          fadeProgress += 0.03\n          if (fadeProgress < 1) {\n            if (mode === \"static\") {\n              staticBarsRef.current = staticBarsRef.current.map(\n                (value) => value * (1 - fadeProgress)\n              )\n            } else {\n              historyRef.current = historyRef.current.map(\n                (value) => value * (1 - fadeProgress)\n              )\n            }\n            needsRedrawRef.current = true\n            redrawRef.current()\n            fadeFrame = requestAnimationFrame(fadeToIdle)\n          } else {\n            if (mode === \"static\") {\n              staticBarsRef.current = []\n            } else {\n              historyRef.current = []\n            }\n          }\n        }\n        fadeToIdle()\n        return () => cancelAnimationFrame(fadeFrame)\n      }\n    }\n  }, [processing, active, barWidth, barGap, mode])\n\n  // Handle microphone setup and teardown\n  useEffect(() => {\n    let cancelled = false\n    if (!active) {\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n        streamRef.current = null\n        onStreamEnd?.()\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n        audioContextRef.current = null\n      }\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n        animationRef.current = 0\n      }\n      return\n    }\n\n    const setupMicrophone = async () => {\n      try {\n        const stream = await acquireMediaStream(\n          {\n            audio: deviceId\n              ? {\n                  deviceId: { exact: deviceId },\n                  echoCancellation: true,\n                  noiseSuppression: true,\n                  autoGainControl: true,\n                }\n              : {\n                  echoCancellation: true,\n                  noiseSuppression: true,\n                  autoGainControl: true,\n                },\n          },\n          () => cancelled\n        )\n        if (!stream) return\n        streamRef.current = stream\n        onStreamReady?.(stream)\n\n        const AudioContextConstructor =\n          window.AudioContext ||\n          (window as unknown as { webkitAudioContext: typeof AudioContext })\n            .webkitAudioContext\n        const audioContext = new AudioContextConstructor()\n        const analyser = audioContext.createAnalyser()\n        analyser.fftSize = fftSize\n        analyser.smoothingTimeConstant = smoothingTimeConstant\n\n        const source = audioContext.createMediaStreamSource(stream)\n        source.connect(analyser)\n\n        audioContextRef.current = audioContext\n        analyserRef.current = analyser\n\n        // Clear history when starting\n        historyRef.current = []\n      } catch (error) {\n        if (!cancelled) onError?.(error as Error)\n      }\n    }\n\n    setupMicrophone()\n\n    return () => {\n      cancelled = true\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n        streamRef.current = null\n        onStreamEnd?.()\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n        audioContextRef.current = null\n      }\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n        animationRef.current = 0\n      }\n    }\n  }, [\n    active,\n    deviceId,\n    fftSize,\n    smoothingTimeConstant,\n    onError,\n    onStreamReady,\n    onStreamEnd,\n  ])\n\n  // Animation loop\n  useEffect(() => {\n    const currentCanvas = canvasRef.current\n    if (!currentCanvas) return\n    const canvas: HTMLCanvasElement = currentCanvas\n\n    const currentContext = canvas.getContext(\"2d\")\n    if (!currentContext) return\n    const ctx: CanvasRenderingContext2D = currentContext\n\n    let rafId = 0\n\n    const scheduleRedraw = () => {\n      if (!rafId) rafId = requestAnimationFrame(animate)\n    }\n\n    function animate(currentTime: number) {\n      rafId = 0\n      // Render waveform\n      const rect = canvas.getBoundingClientRect()\n\n      // Update audio data if active\n      if (active && currentTime - lastUpdateRef.current > updateRate) {\n        lastUpdateRef.current = currentTime\n\n        if (analyserRef.current) {\n          const dataArray = new Uint8Array(\n            analyserRef.current.frequencyBinCount\n          )\n          analyserRef.current.getByteFrequencyData(dataArray)\n\n          if (mode === \"static\") {\n            // For static mode, update bars in place\n            const startFreq = Math.floor(dataArray.length * 0.05)\n            const endFreq = Math.floor(dataArray.length * 0.4)\n            const relevantData = dataArray.slice(startFreq, endFreq)\n\n            const barCount = Math.floor(rect.width / (barWidth + barGap))\n            const halfCount = Math.floor(barCount / 2)\n            const newBars: number[] = []\n\n            // Mirror the data for symmetric display\n            for (let i = halfCount - 1; i >= 0; i--) {\n              const dataIndex = Math.floor(\n                (i / halfCount) * relevantData.length\n              )\n              const value = Math.min(\n                1,\n                (relevantData[dataIndex] / 255) * sensitivity\n              )\n              newBars.push(Math.max(0.05, value))\n            }\n\n            for (let i = 0; i < halfCount; i++) {\n              const dataIndex = Math.floor(\n                (i / halfCount) * relevantData.length\n              )\n              const value = Math.min(\n                1,\n                (relevantData[dataIndex] / 255) * sensitivity\n              )\n              newBars.push(Math.max(0.05, value))\n            }\n\n            staticBarsRef.current = newBars\n            lastActiveDataRef.current = newBars\n          } else {\n            // Scrolling mode - original behavior\n            let sum = 0\n            const startFreq = Math.floor(dataArray.length * 0.05)\n            const endFreq = Math.floor(dataArray.length * 0.4)\n            const relevantData = dataArray.slice(startFreq, endFreq)\n\n            for (let i = 0; i < relevantData.length; i++) {\n              sum += relevantData[i]\n            }\n            const average = (sum / relevantData.length / 255) * sensitivity\n\n            // Add to history\n            historyRef.current.push(Math.min(1, Math.max(0.05, average)))\n            lastActiveDataRef.current = [...historyRef.current]\n\n            // Maintain history size\n            if (historyRef.current.length > historySize) {\n              historyRef.current.shift()\n            }\n          }\n          needsRedrawRef.current = true\n        }\n      }\n\n      // Only redraw if needed\n      if (!needsRedrawRef.current && !active && !processing) return\n\n      needsRedrawRef.current = active\n      ctx.clearRect(0, 0, rect.width, rect.height)\n\n      const computedBarColor =\n        barColor ||\n        (() => {\n          const style = getComputedStyle(canvas)\n          // Try to get the computed color value directly\n          const color = style.color\n          return color || \"#000\"\n        })()\n\n      const step = barWidth + barGap\n      const barCount = Math.floor(rect.width / step)\n      const centerY = rect.height / 2\n\n      // Draw bars based on mode\n      if (mode === \"static\") {\n        // Static mode - bars in fixed positions\n        const dataToRender = processing\n          ? staticBarsRef.current\n          : active\n            ? staticBarsRef.current\n            : staticBarsRef.current.length > 0\n              ? staticBarsRef.current\n              : []\n\n        for (let i = 0; i < barCount && i < dataToRender.length; i++) {\n          const value = dataToRender[i] || 0.1\n          const x = i * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.4 + value * 0.6\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n      } else {\n        // Scrolling mode - original behavior\n        for (let i = 0; i < barCount && i < historyRef.current.length; i++) {\n          const dataIndex = historyRef.current.length - 1 - i\n          const value = historyRef.current[dataIndex] || 0.1\n          const x = rect.width - (i + 1) * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.4 + value * 0.6\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n      }\n\n      // Apply edge fading\n      if (fadeEdges && fadeWidth > 0 && rect.width > 0) {\n        // Cache gradient if width hasn't changed\n        if (!gradientCacheRef.current || lastWidthRef.current !== rect.width) {\n          const gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n          const fadePercent = Math.min(0.3, fadeWidth / rect.width)\n\n          // destination-out: removes destination where source alpha is high\n          // We want: fade edges out, keep center solid\n          // Left edge: start opaque (1) = remove, fade to transparent (0) = keep\n          gradient.addColorStop(0, \"rgba(255,255,255,1)\")\n          gradient.addColorStop(fadePercent, \"rgba(255,255,255,0)\")\n          // Center stays transparent = keep everything\n          gradient.addColorStop(1 - fadePercent, \"rgba(255,255,255,0)\")\n          // Right edge: fade from transparent (0) = keep to opaque (1) = remove\n          gradient.addColorStop(1, \"rgba(255,255,255,1)\")\n\n          gradientCacheRef.current = gradient\n          lastWidthRef.current = rect.width\n        }\n\n        ctx.globalCompositeOperation = \"destination-out\"\n        ctx.fillStyle = gradientCacheRef.current\n        ctx.fillRect(0, 0, rect.width, rect.height)\n        ctx.globalCompositeOperation = \"source-over\"\n      }\n\n      ctx.globalAlpha = 1\n\n      if (active || processing) scheduleRedraw()\n    }\n\n    redrawRef.current = scheduleRedraw\n    scheduleRedraw()\n\n    return () => {\n      redrawRef.current = () => {}\n      if (rafId) {\n        cancelAnimationFrame(rafId)\n      }\n    }\n  }, [\n    active,\n    processing,\n    sensitivity,\n    updateRate,\n    historySize,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    barRadius,\n    barColor,\n    fadeEdges,\n    fadeWidth,\n    mode,\n  ])\n\n  return (\n    <div\n      className={cn(\"relative h-full w-full\", className)}\n      ref={containerRef}\n      style={{ height: heightStyle }}\n      aria-label={\n        active\n          ? \"Live audio waveform\"\n          : processing\n            ? \"Processing audio\"\n            : \"Audio waveform idle\"\n      }\n      role=\"img\"\n      {...props}\n    >\n      {!active && !processing && (\n        <div className=\"border-muted-foreground/20 absolute top-1/2 right-0 left-0 -translate-y-1/2 border-t-2 border-dotted\" />\n      )}\n      <canvas\n        className=\"block h-full w-full\"\n        ref={canvasRef}\n        aria-hidden=\"true\"\n      />\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/media.ts",
          "target": "@components/voice-agents/elevenlabs/media.ts",
          "type": "registry:component",
          "content": "export async function acquireMediaStream(\n  constraints: MediaStreamConstraints,\n  cancelled: () => boolean\n) {\n  const stream = await navigator.mediaDevices.getUserMedia(constraints)\n  if (!cancelled()) return stream\n  stream.getTracks().forEach((track) => track.stop())\n  return null\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-voice-picker",
      "type": "registry:block",
      "title": "Elevenlabs Voice Picker",
      "description": "Voice Picker",
      "dependencies": [
        "@radix-ui/react-dropdown-menu@^2.1.14",
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "cmdk@1.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "three@0.149.0",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/voice-picker.tsx",
          "target": "@components/voice-agents/elevenlabs/voice-picker.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/components/ai-elements/_ui/command\"\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from \"@/components/ai-elements/_ui/popover\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  AudioPlayerProvider,\n  useAudioPlayer,\n} from \"@/components/voice-agents/elevenlabs/audio-player\"\nimport { Orb } from \"@/components/voice-agents/elevenlabs/orb\"\nimport type { ElevenLabsVoice } from \"@/components/voice-agents/elevenlabs/types\"\nimport { cn } from \"@/lib/utils\"\nimport { Check, ChevronsUpDown, Pause, Play } from \"lucide-react\"\nimport * as React from \"react\"\n\ninterface VoicePickerProps {\n  voices: ElevenLabsVoice[]\n  value?: string\n  onValueChange?: (value: string) => void\n  placeholder?: string\n  className?: string\n  open?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nfunction VoicePicker({\n  voices,\n  value,\n  onValueChange,\n  placeholder = \"Select a voice...\",\n  className,\n  open,\n  onOpenChange,\n}: VoicePickerProps) {\n  const [internalOpen, setInternalOpen] = React.useState(false)\n  const isControlled = open !== undefined\n  const isOpen = isControlled ? open : internalOpen\n  const setIsOpen = isControlled ? onOpenChange : setInternalOpen\n\n  const selectedVoice = voices.find((v) => v.voiceId === value)\n\n  return (\n    <AudioPlayerProvider>\n      <Popover open={isOpen} onOpenChange={setIsOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={isOpen}\n            className={cn(\"w-full justify-between\", className)}\n          >\n            {selectedVoice ? (\n              <div className=\"flex items-center gap-2 overflow-hidden\">\n                <div className=\"relative size-6 shrink-0 overflow-visible\">\n                  <Orb agentState=\"thinking\" className=\"absolute inset-0\" />\n                </div>\n                <span className=\"truncate\">{selectedVoice.name}</span>\n              </div>\n            ) : (\n              placeholder\n            )}\n            <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-[var(--radix-popover-trigger-width)] p-0\">\n          <Command>\n            <CommandInput placeholder=\"Search voices...\" />\n            <CommandList>\n              <CommandEmpty>No voice found.</CommandEmpty>\n              <CommandGroup>\n                {voices.map((voice) => (\n                  <VoicePickerItem\n                    key={voice.voiceId}\n                    voice={voice}\n                    isSelected={value === voice.voiceId}\n                    onSelect={() => {\n                      onValueChange?.(voice.voiceId!)\n                    }}\n                  />\n                ))}\n              </CommandGroup>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n    </AudioPlayerProvider>\n  )\n}\n\ninterface VoicePickerItemProps {\n  voice: ElevenLabsVoice\n  isSelected: boolean\n  onSelect: () => void\n}\n\nfunction VoicePickerItem({\n  voice,\n  isSelected,\n  onSelect,\n}: VoicePickerItemProps) {\n  const [isHovered, setIsHovered] = React.useState(false)\n  const player = useAudioPlayer()\n\n  const preview = voice.previewUrl\n  const audioItem = React.useMemo(\n    () => (preview ? { id: voice.voiceId!, src: preview, data: voice } : null),\n    [preview, voice]\n  )\n\n  const isPlaying =\n    audioItem && player.isItemActive(audioItem.id) && player.isPlaying\n\n  const handlePreview = React.useCallback(\n    async (e: React.MouseEvent) => {\n      e.preventDefault()\n      e.stopPropagation()\n\n      if (!audioItem) return\n\n      if (isPlaying) {\n        player.pause()\n      } else {\n        player.play(audioItem)\n      }\n    },\n    [audioItem, isPlaying, player]\n  )\n\n  return (\n    <CommandItem\n      value={voice.voiceId!}\n      keywords={[\n        voice.name,\n        voice.labels?.accent,\n        voice.labels?.gender,\n        voice.labels?.age,\n        voice.labels?.description,\n        voice.labels?.[\"use case\"],\n      ].filter((k): k is string => Boolean(k))}\n      onSelect={onSelect}\n      className=\"flex items-center gap-3\"\n    >\n      <div\n        className=\"relative z-10 size-8 shrink-0 cursor-pointer overflow-visible\"\n        onMouseEnter={() => setIsHovered(true)}\n        onMouseLeave={() => setIsHovered(false)}\n        onClick={handlePreview}\n      >\n        <Orb\n          agentState={isPlaying ? \"talking\" : undefined}\n          className=\"pointer-events-none absolute inset-0\"\n        />\n        {preview && isHovered && (\n          <div className=\"pointer-events-none absolute inset-0 flex size-8 shrink-0 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm transition-opacity hover:bg-black/50\">\n            {isPlaying ? (\n              <Pause className=\"size-3 text-white\" />\n            ) : (\n              <Play className=\"size-3 text-white\" />\n            )}\n          </div>\n        )}\n      </div>\n\n      <div className=\"flex flex-1 flex-col gap-0.5\">\n        <span className=\"font-medium\">{voice.name}</span>\n        {voice.labels && (\n          <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n            {voice.labels.accent && <span>{voice.labels.accent}</span>}\n            {voice.labels.gender && <span>•</span>}\n            {voice.labels.gender && (\n              <span className=\"capitalize\">{voice.labels.gender}</span>\n            )}\n            {voice.labels.age && <span>•</span>}\n            {voice.labels.age && (\n              <span className=\"capitalize\">{voice.labels.age}</span>\n            )}\n          </div>\n        )}\n      </div>\n\n      <Check\n        className={cn(\n          \"ml-auto size-4 shrink-0\",\n          isSelected ? \"opacity-100\" : \"opacity-0\"\n        )}\n      />\n    </CommandItem>\n  )\n}\n\nexport { VoicePicker, VoicePickerItem }\n"
        },
        {
          "path": "components/ai-elements/_ui/command.tsx",
          "target": "@components/ai-elements/_ui/command.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ai-elements/_ui/dialog\"\nimport { cn } from \"@/lib/utils\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction Command({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\n        \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandDialog({\n  title = \"Command Palette\",\n  description = \"Search for a command to run...\",\n  children,\n  className,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string\n  description?: string\n  className?: string\n  showCloseButton?: boolean\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent\n        className={cn(\"overflow-hidden p-0\", className)}\n        showCloseButton={showCloseButton}\n      >\n        <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction CommandInput({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div\n      data-slot=\"command-input-wrapper\"\n      className=\"flex h-9 items-center gap-2 border-b px-3\"\n    >\n      <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n      <CommandPrimitive.Input\n        data-slot=\"command-input\"\n        className={cn(\n          \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  )\n}\n\nfunction CommandList({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(\n        \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandEmpty({\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return (\n    <CommandPrimitive.Empty\n      data-slot=\"command-empty\"\n      className=\"py-6 text-center text-sm\"\n      {...props}\n    />\n  )\n}\n\nfunction CommandGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(\"bg-border -mx-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandItem({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"command-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandInput,\n  CommandList,\n  CommandEmpty,\n  CommandGroup,\n  CommandItem,\n  CommandShortcut,\n  CommandSeparator,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/dialog.tsx",
          "target": "@components/ai-elements/_ui/dialog.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as DialogPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Dialog({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n  showCloseButton?: boolean\n}) {\n  return (\n    <DialogPortal data-slot=\"dialog-portal\">\n      <DialogOverlay />\n      <DialogPrimitive.Content\n        data-slot=\"dialog-content\"\n        className={cn(\n          \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <DialogPrimitive.Close\n            data-slot=\"dialog-close\"\n            className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n          >\n            <XIcon />\n            <span className=\"sr-only\">Close</span>\n          </DialogPrimitive.Close>\n        )}\n      </DialogPrimitive.Content>\n    </DialogPortal>\n  )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"text-lg leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/popover.tsx",
          "target": "@components/ai-elements/_ui/popover.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Popover as PopoverPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Popover({\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n  return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n  return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n  return (\n    <PopoverPrimitive.Portal>\n      <PopoverPrimitive.Content\n        data-slot=\"popover-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n          className\n        )}\n        {...props}\n      />\n    </PopoverPrimitive.Portal>\n  )\n}\n\nfunction PopoverAnchor({\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n  return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/audio-player.tsx",
          "target": "@components/voice-agents/elevenlabs/audio-player.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { cn } from \"@/lib/utils\"\nimport { Check, PauseIcon, PlayIcon, Settings } from \"lucide-react\"\nimport { Slider as SliderPrimitive } from \"radix-ui\"\nimport {\n  ComponentProps,\n  createContext,\n  HTMLProps,\n  ReactNode,\n  RefObject,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\nenum ReadyState {\n  HAVE_NOTHING = 0,\n  HAVE_METADATA = 1,\n  HAVE_CURRENT_DATA = 2,\n  HAVE_FUTURE_DATA = 3,\n  HAVE_ENOUGH_DATA = 4,\n}\n\nenum NetworkState {\n  NETWORK_EMPTY = 0,\n  NETWORK_IDLE = 1,\n  NETWORK_LOADING = 2,\n  NETWORK_NO_SOURCE = 3,\n}\n\nfunction formatTime(seconds: number) {\n  const hrs = Math.floor(seconds / 3600)\n  const mins = Math.floor((seconds % 3600) / 60)\n  const secs = Math.floor(seconds % 60)\n\n  const formattedMins = mins < 10 ? `0${mins}` : mins\n  const formattedSecs = secs < 10 ? `0${secs}` : secs\n\n  return hrs > 0\n    ? `${hrs}:${formattedMins}:${formattedSecs}`\n    : `${mins}:${formattedSecs}`\n}\n\ninterface AudioPlayerItem<TData = unknown> {\n  id: string | number\n  src: string\n  data?: TData\n}\n\ninterface AudioPlayerApi<TData = unknown> {\n  ref: RefObject<HTMLAudioElement | null>\n  activeItem: AudioPlayerItem<TData> | null\n  duration: number | undefined\n  error: MediaError | null\n  isPlaying: boolean\n  isBuffering: boolean\n  playbackRate: number\n  isItemActive: (id: string | number | null) => boolean\n  setActiveItem: (item: AudioPlayerItem<TData> | null) => Promise<void>\n  play: (item?: AudioPlayerItem<TData> | null) => Promise<void>\n  pause: () => void\n  seek: (time: number) => void\n  setPlaybackRate: (rate: number) => void\n}\n\nconst AudioPlayerContext = createContext<AudioPlayerApi<unknown> | null>(null)\n\nexport function useAudioPlayer<TData = unknown>(): AudioPlayerApi<TData> {\n  const api = useContext(AudioPlayerContext) as AudioPlayerApi<TData> | null\n  if (!api) {\n    throw new Error(\n      \"useAudioPlayer cannot be called outside of AudioPlayerProvider\"\n    )\n  }\n  return api\n}\n\nconst AudioPlayerTimeContext = createContext<number | null>(null)\n\nexport const useAudioPlayerTime = () => {\n  const time = useContext(AudioPlayerTimeContext)\n  if (time === null) {\n    throw new Error(\n      \"useAudioPlayerTime cannot be called outside of AudioPlayerProvider\"\n    )\n  }\n  return time\n}\n\nexport function AudioPlayerProvider<TData = unknown>({\n  children,\n}: {\n  children: ReactNode\n}) {\n  const audioRef = useRef<HTMLAudioElement>(null)\n  const itemRef = useRef<AudioPlayerItem<TData> | null>(null)\n  const playPromiseRef = useRef<Promise<void> | null>(null)\n  const [readyState, setReadyState] = useState<number>(0)\n  const [networkState, setNetworkState] = useState<number>(0)\n  const [time, setTime] = useState<number>(0)\n  const [duration, setDuration] = useState<number | undefined>(undefined)\n  const [error, setError] = useState<MediaError | null>(null)\n  const [activeItem, _setActiveItem] = useState<AudioPlayerItem<TData> | null>(\n    null\n  )\n  const [paused, setPaused] = useState(true)\n  const [playbackRate, setPlaybackRateState] = useState<number>(1)\n\n  const setActiveItem = useCallback(\n    async (item: AudioPlayerItem<TData> | null) => {\n      if (!audioRef.current) return\n\n      if (item?.id === itemRef.current?.id) {\n        return\n      }\n      itemRef.current = item\n      const currentRate = audioRef.current.playbackRate\n      audioRef.current.pause()\n      audioRef.current.currentTime = 0\n      if (item === null) {\n        audioRef.current.removeAttribute(\"src\")\n      } else {\n        audioRef.current.src = item.src\n      }\n      audioRef.current.load()\n      audioRef.current.playbackRate = currentRate\n    },\n    []\n  )\n\n  const play = useCallback(\n    async (item?: AudioPlayerItem<TData> | null) => {\n      if (!audioRef.current) return\n\n      if (playPromiseRef.current) {\n        try {\n          await playPromiseRef.current\n        } catch (error) {\n          console.error(\"Play promise error:\", error)\n        }\n      }\n\n      if (item === undefined) {\n        const playPromise = audioRef.current.play()\n        playPromiseRef.current = playPromise\n        return playPromise\n      }\n      if (item?.id === activeItem?.id) {\n        const playPromise = audioRef.current.play()\n        playPromiseRef.current = playPromise\n        return playPromise\n      }\n\n      itemRef.current = item\n      const currentRate = audioRef.current.playbackRate\n      if (!audioRef.current.paused) {\n        audioRef.current.pause()\n      }\n      audioRef.current.currentTime = 0\n      if (item === null) {\n        audioRef.current.removeAttribute(\"src\")\n      } else {\n        audioRef.current.src = item.src\n      }\n      audioRef.current.load()\n      audioRef.current.playbackRate = currentRate\n      const playPromise = audioRef.current.play()\n      playPromiseRef.current = playPromise\n      return playPromise\n    },\n    [activeItem]\n  )\n\n  const pause = useCallback(async () => {\n    if (!audioRef.current) return\n\n    if (playPromiseRef.current) {\n      try {\n        await playPromiseRef.current\n      } catch (e) {\n        console.error(e)\n      }\n    }\n\n    audioRef.current.pause()\n    playPromiseRef.current = null\n  }, [])\n\n  const seek = useCallback((time: number) => {\n    if (!audioRef.current) return\n    audioRef.current.currentTime = time\n  }, [])\n\n  const setPlaybackRate = useCallback((rate: number) => {\n    if (!audioRef.current) return\n    audioRef.current.playbackRate = rate\n    setPlaybackRateState(rate)\n  }, [])\n\n  const isItemActive = useCallback(\n    (id: string | number | null) => {\n      return activeItem?.id === id\n    },\n    [activeItem]\n  )\n\n  useAnimationFrame(() => {\n    if (audioRef.current) {\n      _setActiveItem(itemRef.current)\n      setReadyState(audioRef.current.readyState)\n      setNetworkState(audioRef.current.networkState)\n      setTime(audioRef.current.currentTime)\n      setDuration(audioRef.current.duration)\n      setPaused(audioRef.current.paused)\n      setError(audioRef.current.error)\n      setPlaybackRateState(audioRef.current.playbackRate)\n    }\n  })\n\n  const isPlaying = !paused\n  const isBuffering =\n    readyState < ReadyState.HAVE_FUTURE_DATA &&\n    networkState === NetworkState.NETWORK_LOADING\n\n  const api = useMemo<AudioPlayerApi<TData>>(\n    () => ({\n      ref: audioRef,\n      duration,\n      error,\n      isPlaying,\n      isBuffering,\n      activeItem,\n      playbackRate,\n      isItemActive,\n      setActiveItem,\n      play,\n      pause,\n      seek,\n      setPlaybackRate,\n    }),\n    [\n      audioRef,\n      duration,\n      error,\n      isPlaying,\n      isBuffering,\n      activeItem,\n      playbackRate,\n      isItemActive,\n      setActiveItem,\n      play,\n      pause,\n      seek,\n      setPlaybackRate,\n    ]\n  )\n\n  return (\n    <AudioPlayerContext.Provider value={api as AudioPlayerApi<unknown>}>\n      <AudioPlayerTimeContext.Provider value={time}>\n        <audio ref={audioRef} className=\"hidden\" crossOrigin=\"anonymous\" />\n        {children}\n      </AudioPlayerTimeContext.Provider>\n    </AudioPlayerContext.Provider>\n  )\n}\n\nexport const AudioPlayerProgress = ({\n  ...otherProps\n}: Omit<\n  ComponentProps<typeof SliderPrimitive.Root>,\n  \"min\" | \"max\" | \"value\"\n>) => {\n  const player = useAudioPlayer()\n  const time = useAudioPlayerTime()\n  const wasPlayingRef = useRef(false)\n\n  return (\n    <SliderPrimitive.Root\n      {...otherProps}\n      value={[time]}\n      onValueChange={(vals) => {\n        player.seek(vals[0])\n        otherProps.onValueChange?.(vals)\n      }}\n      min={0}\n      max={player.duration ?? 0}\n      step={otherProps.step || 0.25}\n      onPointerDown={(e) => {\n        wasPlayingRef.current = player.isPlaying\n        player.pause()\n        otherProps.onPointerDown?.(e)\n      }}\n      onPointerUp={(e) => {\n        if (wasPlayingRef.current) {\n          player.play()\n        }\n        otherProps.onPointerUp?.(e)\n      }}\n      className={cn(\n        \"group/player relative flex h-4 touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col\",\n        otherProps.className\n      )}\n      onKeyDown={(e) => {\n        if (e.key === \" \") {\n          e.preventDefault()\n          if (!player.isPlaying) {\n            player.play()\n          } else {\n            player.pause()\n          }\n        }\n        otherProps.onKeyDown?.(e)\n      }}\n      disabled={\n        player.duration === undefined ||\n        !Number.isFinite(player.duration) ||\n        Number.isNaN(player.duration)\n      }\n    >\n      <SliderPrimitive.Track className=\"bg-muted relative h-[4px] w-full grow overflow-hidden rounded-full\">\n        <SliderPrimitive.Range className=\"bg-primary absolute h-full\" />\n      </SliderPrimitive.Track>\n      <SliderPrimitive.Thumb\n        className=\"relative flex h-0 w-0 items-center justify-center opacity-0 group-hover/player:opacity-100 focus-visible:opacity-100 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50\"\n        data-slot=\"slider-thumb\"\n      >\n        <div className=\"bg-foreground absolute size-3 rounded-full\" />\n      </SliderPrimitive.Thumb>\n    </SliderPrimitive.Root>\n  )\n}\n\nexport const AudioPlayerTime = ({\n  className,\n  ...otherProps\n}: HTMLProps<HTMLSpanElement>) => {\n  const time = useAudioPlayerTime()\n  return (\n    <span\n      {...otherProps}\n      className={cn(\"text-muted-foreground text-sm tabular-nums\", className)}\n    >\n      {formatTime(time)}\n    </span>\n  )\n}\n\nexport const AudioPlayerDuration = ({\n  className,\n  ...otherProps\n}: HTMLProps<HTMLSpanElement>) => {\n  const player = useAudioPlayer()\n  return (\n    <span\n      {...otherProps}\n      className={cn(\"text-muted-foreground text-sm tabular-nums\", className)}\n    >\n      {player.duration !== null &&\n      player.duration !== undefined &&\n      !Number.isNaN(player.duration)\n        ? formatTime(player.duration)\n        : \"--:--\"}\n    </span>\n  )\n}\n\ninterface SpinnerProps {\n  className?: string\n}\n\nfunction Spinner({ className }: SpinnerProps) {\n  return (\n    <div\n      className={cn(\n        \"border-muted border-t-foreground size-3.5 animate-spin rounded-full border-2\",\n        className\n      )}\n      role=\"status\"\n      aria-label=\"Loading\"\n    >\n      <span className=\"sr-only\">Loading...</span>\n    </div>\n  )\n}\n\ninterface PlayButtonProps extends React.ComponentProps<typeof Button> {\n  playing: boolean\n  onPlayingChange: (playing: boolean) => void\n  loading?: boolean\n}\n\nconst PlayButton = ({\n  playing,\n  onPlayingChange,\n  className,\n  onClick,\n  loading,\n  ...otherProps\n}: PlayButtonProps) => {\n  return (\n    <Button\n      {...otherProps}\n      onClick={(e) => {\n        onPlayingChange(!playing)\n        onClick?.(e)\n      }}\n      className={cn(\"relative\", className)}\n      aria-label={playing ? \"Pause\" : \"Play\"}\n      type=\"button\"\n    >\n      {playing ? (\n        <PauseIcon\n          className={cn(\"size-4\", loading && \"opacity-0\")}\n          aria-hidden=\"true\"\n        />\n      ) : (\n        <PlayIcon\n          className={cn(\"size-4\", loading && \"opacity-0\")}\n          aria-hidden=\"true\"\n        />\n      )}\n      {loading && (\n        <div className=\"absolute inset-0 flex items-center justify-center rounded-[inherit] backdrop-blur-xs\">\n          <Spinner />\n        </div>\n      )}\n    </Button>\n  )\n}\n\nexport interface AudioPlayerButtonProps<TData = unknown>\n  extends React.ComponentProps<typeof Button> {\n  item?: AudioPlayerItem<TData>\n}\n\nexport function AudioPlayerButton<TData = unknown>({\n  item,\n  ...otherProps\n}: AudioPlayerButtonProps<TData>) {\n  const player = useAudioPlayer<TData>()\n\n  if (!item) {\n    return (\n      <PlayButton\n        {...otherProps}\n        playing={player.isPlaying}\n        onPlayingChange={(shouldPlay) => {\n          if (shouldPlay) {\n            player.play()\n          } else {\n            player.pause()\n          }\n        }}\n        loading={player.isBuffering && player.isPlaying}\n      />\n    )\n  }\n\n  return (\n    <PlayButton\n      {...otherProps}\n      playing={player.isItemActive(item.id) && player.isPlaying}\n      onPlayingChange={(shouldPlay) => {\n        if (shouldPlay) {\n          player.play(item)\n        } else {\n          player.pause()\n        }\n      }}\n      loading={\n        player.isItemActive(item.id) && player.isBuffering && player.isPlaying\n      }\n    />\n  )\n}\n\ntype Callback = (delta: number) => void\n\nfunction useAnimationFrame(callback: Callback) {\n  const requestRef = useRef<number | null>(null)\n  const previousTimeRef = useRef<number | null>(null)\n  const callbackRef = useRef<Callback>(callback)\n\n  useEffect(() => {\n    callbackRef.current = callback\n  }, [callback])\n\n  useEffect(() => {\n    const animate = (time: number) => {\n      if (previousTimeRef.current !== null) {\n        const delta = time - previousTimeRef.current\n        callbackRef.current(delta)\n      }\n      previousTimeRef.current = time\n      requestRef.current = requestAnimationFrame(animate)\n    }\n\n    requestRef.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (requestRef.current) cancelAnimationFrame(requestRef.current)\n      previousTimeRef.current = null\n    }\n  }, [])\n}\n\nconst PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] as const\n\nexport interface AudioPlayerSpeedProps\n  extends React.ComponentProps<typeof Button> {\n  speeds?: readonly number[]\n}\n\nexport function AudioPlayerSpeed({\n  speeds = PLAYBACK_SPEEDS,\n  className,\n  variant = \"ghost\",\n  size = \"icon\",\n  ...props\n}: AudioPlayerSpeedProps) {\n  const player = useAudioPlayer()\n  const currentSpeed = player.playbackRate\n\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button\n          variant={variant}\n          size={size}\n          className={cn(className)}\n          aria-label=\"Playback speed\"\n          {...props}\n        >\n          <Settings className=\"size-4\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent align=\"end\" className=\"min-w-[120px]\">\n        {speeds.map((speed) => (\n          <DropdownMenuItem\n            key={speed}\n            onClick={() => player.setPlaybackRate(speed)}\n            className=\"flex items-center justify-between\"\n          >\n            <span className={speed === 1 ? \"\" : \"font-mono\"}>\n              {speed === 1 ? \"Normal\" : `${speed}x`}\n            </span>\n            {currentSpeed === speed && <Check className=\"size-4\" />}\n          </DropdownMenuItem>\n        ))}\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n\nexport interface AudioPlayerSpeedButtonGroupProps\n  extends Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> {\n  speeds?: readonly number[]\n}\n\nexport function AudioPlayerSpeedButtonGroup({\n  speeds = [0.5, 1, 1.5, 2],\n  className,\n  ...props\n}: AudioPlayerSpeedButtonGroupProps) {\n  const player = useAudioPlayer()\n  const currentSpeed = player.playbackRate\n\n  return (\n    <div\n      className={cn(\"flex items-center gap-1\", className)}\n      role=\"group\"\n      aria-label=\"Playback speed controls\"\n      {...props}\n    >\n      {speeds.map((speed) => (\n        <Button\n          key={speed}\n          variant={currentSpeed === speed ? \"default\" : \"outline\"}\n          size=\"sm\"\n          onClick={() => player.setPlaybackRate(speed)}\n          className=\"min-w-[50px] font-mono text-xs\"\n        >\n          {speed}x\n        </Button>\n      ))}\n    </div>\n  )\n}\n\nexport const exampleTracks = [\n  {\n    id: \"0\",\n    name: \"II - 00\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/00.mp3\",\n  },\n  {\n    id: \"1\",\n    name: \"II - 01\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/01.mp3\",\n  },\n  {\n    id: \"2\",\n    name: \"II - 02\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/02.mp3\",\n  },\n  {\n    id: \"3\",\n    name: \"II - 03\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/03.mp3\",\n  },\n  {\n    id: \"4\",\n    name: \"II - 04\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/04.mp3\",\n  },\n  {\n    id: \"5\",\n    name: \"II - 05\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/05.mp3\",\n  },\n  {\n    id: \"6\",\n    name: \"II - 06\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/06.mp3\",\n  },\n  {\n    id: \"7\",\n    name: \"II - 07\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/07.mp3\",\n  },\n  {\n    id: \"8\",\n    name: \"II - 08\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/08.mp3\",\n  },\n  {\n    id: \"9\",\n    name: \"II - 09\",\n    url: \"https://storage.googleapis.com/eleven-public-cdn/audio/ui-elevenlabs-io/09.mp3\",\n  },\n]\n"
        },
        {
          "path": "components/ui/dropdown-menu.tsx",
          "target": "@components/ui/dropdown-menu.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction DropdownMenu({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  return (\n    <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n  )\n}\n\nfunction DropdownMenuTrigger({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-md\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return (\n    <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return (\n    <DropdownMenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CircleIcon className=\"size-2 fill-current\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-semibold data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPrimitive.SubContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/orb.tsx",
          "target": "@components/voice-agents/elevenlabs/orb.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { useEffect, useRef, useState, type RefObject } from \"react\"\nimport * as THREE from \"three\"\n\nexport type AgentState = null | \"thinking\" | \"listening\" | \"talking\"\n\nexport type OrbProps = {\n  colors?: [string, string]\n  colorsRef?: RefObject<[string, string]>\n  resizeDebounce?: number\n  seed?: number\n  agentState?: AgentState\n  volumeMode?: \"auto\" | \"manual\"\n  manualInput?: number\n  manualOutput?: number\n  inputVolumeRef?: RefObject<number>\n  outputVolumeRef?: RefObject<number>\n  getInputVolume?: () => number\n  getOutputVolume?: () => number\n  className?: string\n}\n\nexport function Orb({\n  colors = [\"#CADCFC\", \"#A0B9D1\"],\n  colorsRef,\n  resizeDebounce = 100,\n  seed,\n  agentState = null,\n  volumeMode = \"auto\",\n  manualInput,\n  manualOutput,\n  inputVolumeRef,\n  outputVolumeRef,\n  getInputVolume,\n  getOutputVolume,\n  className,\n}: OrbProps) {\n  const hostRef = useRef<HTMLDivElement>(null)\n  const liveRef = useRef({\n    colors,\n    colorsRef,\n    agentState,\n    volumeMode,\n    manualInput,\n    manualOutput,\n    inputVolumeRef,\n    outputVolumeRef,\n    getInputVolume,\n    getOutputVolume,\n  })\n  const [failed, setFailed] = useState(false)\n\n  liveRef.current = {\n    colors,\n    colorsRef,\n    agentState,\n    volumeMode,\n    manualInput,\n    manualOutput,\n    inputVolumeRef,\n    outputVolumeRef,\n    getInputVolume,\n    getOutputVolume,\n  }\n\n  useEffect(() => {\n    const host = hostRef.current\n    if (!host) return\n\n    let renderer: THREE.WebGLRenderer\n    try {\n      renderer = new THREE.WebGLRenderer({\n        alpha: true,\n        antialias: true,\n        premultipliedAlpha: true,\n      })\n      renderer.outputEncoding = THREE.sRGBEncoding\n      renderer.toneMapping = THREE.ACESFilmicToneMapping\n    } catch {\n      setFailed(true)\n      return\n    }\n\n    const scene = new THREE.Scene()\n    const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 100)\n    camera.position.z = 5\n\n    const random = splitmix32(seed ?? Math.floor(Math.random() * 2 ** 32))\n    const initialColors = liveRef.current.colors\n    const offsets = new Float32Array(\n      Array.from({ length: 7 }, () => random() * Math.PI * 2)\n    )\n    const perlinNoiseTexture = createFallbackNoiseTexture(random)\n    perlinNoiseTexture.wrapS = THREE.RepeatWrapping\n    perlinNoiseTexture.wrapT = THREE.RepeatWrapping\n    let disposed = false\n\n    new THREE.TextureLoader().load(\n      \"https://storage.googleapis.com/eleven-public-cdn/images/perlin-noise.png\",\n      (texture) => {\n        if (disposed) {\n          texture.dispose()\n          return\n        }\n        texture.wrapS = THREE.RepeatWrapping\n        texture.wrapT = THREE.RepeatWrapping\n        material.uniforms.uPerlinTexture.value = texture\n      }\n    )\n\n    const isDark = () => document.documentElement.classList.contains(\"dark\")\n    const uniforms = {\n      uColor1: new THREE.Uniform(createManagedColor(initialColors[0])),\n      uColor2: new THREE.Uniform(createManagedColor(initialColors[1])),\n      uOffsets: { value: offsets },\n      uPerlinTexture: new THREE.Uniform(perlinNoiseTexture),\n      uTime: new THREE.Uniform(0),\n      uAnimation: new THREE.Uniform(0.1),\n      uInverted: new THREE.Uniform(isDark() ? 1 : 0),\n      uInputVolume: new THREE.Uniform(0),\n      uOutputVolume: new THREE.Uniform(0),\n      uOpacity: new THREE.Uniform(0),\n    }\n    const geometry = new THREE.CircleGeometry(3.5, 64)\n    const material = new THREE.ShaderMaterial({\n      uniforms,\n      fragmentShader,\n      vertexShader,\n      transparent: true,\n    })\n    const mesh = new THREE.Mesh(geometry, material)\n    scene.add(mesh)\n\n    renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2))\n    renderer.setClearColor(0x000000, 0)\n    renderer.domElement.setAttribute(\"aria-hidden\", \"true\")\n    renderer.domElement.style.width = \"100%\"\n    renderer.domElement.style.height = \"100%\"\n    renderer.domElement.style.display = \"block\"\n    host.appendChild(renderer.domElement)\n\n    let resizeTimer: ReturnType<typeof setTimeout> | undefined\n    const resize = () => {\n      clearTimeout(resizeTimer)\n      resizeTimer = setTimeout(() => {\n        const { width, height } = host.getBoundingClientRect()\n        if (!width || !height) return\n        renderer.setSize(width, height, false)\n        camera.aspect = width / height\n        camera.updateProjectionMatrix()\n      }, resizeDebounce)\n    }\n    const resizeObserver = new ResizeObserver(resize)\n    resizeObserver.observe(host)\n    resize()\n\n    const themeObserver = new MutationObserver(() => {\n      uniforms.uInverted.value = isDark() ? 1 : 0\n    })\n    themeObserver.observe(document.documentElement, {\n      attributes: true,\n      attributeFilter: [\"class\"],\n    })\n\n    let visible = true\n    const intersectionObserver = new IntersectionObserver(([entry]) => {\n      visible = entry?.isIntersecting ?? true\n    })\n    intersectionObserver.observe(host)\n\n    const reducedMotion = window.matchMedia(\n      \"(prefers-reduced-motion: reduce)\"\n    ).matches\n    const targetColor1 = createManagedColor(initialColors[0])\n    const targetColor2 = createManagedColor(initialColors[1])\n    let currentInput = 0\n    let currentOutput = 0\n    let animationSpeed = 0.1\n    let previous = performance.now()\n    let frameId = 0\n\n    const render = (now: number) => {\n      frameId = requestAnimationFrame(render)\n      if (!visible) {\n        previous = now\n        return\n      }\n\n      const delta = Math.min((now - previous) / 1000, 0.1)\n      previous = now\n      const live = liveRef.current\n      const liveColors = live.colorsRef?.current ?? live.colors\n      if (liveColors[0]) setManagedColor(targetColor1, liveColors[0])\n      if (liveColors[1]) setManagedColor(targetColor2, liveColors[1])\n\n      uniforms.uTime.value += reducedMotion ? 0 : delta * 0.5\n      uniforms.uOpacity.value = Math.min(1, uniforms.uOpacity.value + delta * 2)\n\n      let targetInput = 0\n      let targetOutput = 0.3\n      if (live.volumeMode === \"manual\") {\n        targetInput = clamp01(\n          live.manualInput ??\n            live.inputVolumeRef?.current ??\n            live.getInputVolume?.() ??\n            0\n        )\n        targetOutput = clamp01(\n          live.manualOutput ??\n            live.outputVolumeRef?.current ??\n            live.getOutputVolume?.() ??\n            0\n        )\n      } else if (!reducedMotion) {\n        const time = uniforms.uTime.value * 2\n        if (live.agentState === \"listening\") {\n          targetInput = clamp01(0.55 + Math.sin(time * 3.2) * 0.35)\n          targetOutput = 0.45\n        } else if (live.agentState === \"talking\") {\n          targetInput = clamp01(0.65 + Math.sin(time * 4.8) * 0.22)\n          targetOutput = clamp01(0.75 + Math.sin(time * 3.6) * 0.22)\n        } else if (live.agentState === \"thinking\") {\n          const base = 0.38 + 0.07 * Math.sin(time * 0.7)\n          const wander =\n            0.05 * Math.sin(time * 2.1) * Math.sin(time * 0.37 + 1.2)\n          targetInput = clamp01(base + wander)\n          targetOutput = clamp01(0.48 + 0.12 * Math.sin(time * 1.05 + 0.6))\n        }\n      }\n\n      currentInput += (targetInput - currentInput) * 0.2\n      currentOutput += (targetOutput - currentOutput) * 0.2\n      const targetSpeed = 0.1 + (1 - Math.pow(currentOutput - 1, 2)) * 0.9\n      animationSpeed += (targetSpeed - animationSpeed) * 0.12\n\n      uniforms.uAnimation.value += reducedMotion ? 0 : delta * animationSpeed\n      uniforms.uInputVolume.value = currentInput\n      uniforms.uOutputVolume.value = currentOutput\n      uniforms.uColor1.value.lerp(targetColor1, 0.08)\n      uniforms.uColor2.value.lerp(targetColor2, 0.08)\n      renderer.render(scene, camera)\n    }\n    frameId = requestAnimationFrame(render)\n\n    const onContextLost = (event: Event) => {\n      event.preventDefault()\n      setFailed(true)\n    }\n    renderer.domElement.addEventListener(\"webglcontextlost\", onContextLost)\n\n    return () => {\n      disposed = true\n      cancelAnimationFrame(frameId)\n      clearTimeout(resizeTimer)\n      resizeObserver.disconnect()\n      intersectionObserver.disconnect()\n      themeObserver.disconnect()\n      renderer.domElement.removeEventListener(\"webglcontextlost\", onContextLost)\n      geometry.dispose()\n      material.dispose()\n      const loadedTexture = material.uniforms.uPerlinTexture\n        .value as THREE.Texture\n      loadedTexture.dispose()\n      if (loadedTexture !== perlinNoiseTexture) perlinNoiseTexture.dispose()\n      renderer.dispose()\n      renderer.domElement.remove()\n    }\n  }, [resizeDebounce, seed])\n\n  return (\n    <div\n      ref={hostRef}\n      className={className ?? \"relative h-full w-full\"}\n      data-orb-renderer={failed ? \"fallback\" : \"webgl\"}\n    >\n      {failed ? (\n        <div\n          aria-hidden\n          className=\"h-full w-full rounded-full bg-[radial-gradient(circle_at_35%_30%,var(--background),#cadcfc_38%,#a0b9d1_72%,transparent_73%)]\"\n        />\n      ) : null}\n    </div>\n  )\n}\n\nfunction splitmix32(a: number) {\n  return function () {\n    a |= 0\n    a = (a + 0x9e3779b9) | 0\n    let t = a ^ (a >>> 16)\n    t = Math.imul(t, 0x21f0aaad)\n    t = t ^ (t >>> 15)\n    t = Math.imul(t, 0x735a2d97)\n    return ((t = t ^ (t >>> 15)) >>> 0) / 4294967296\n  }\n}\n\nfunction clamp01(n: number) {\n  if (!Number.isFinite(n)) return 0\n  return Math.min(1, Math.max(0, n))\n}\n\nfunction createManagedColor(value: string) {\n  return setManagedColor(new THREE.Color(), value)\n}\n\nfunction setManagedColor(color: THREE.Color, value: string) {\n  color.set(value)\n  if (THREE.ColorManagement.legacyMode) color.convertSRGBToLinear()\n  return color\n}\n\nfunction createFallbackNoiseTexture(random: () => number) {\n  const size = 32\n  const pixels = new Uint8Array(size * size * 4)\n  const phases = Array.from({ length: 6 }, () => random() * Math.PI * 2)\n  for (let y = 0; y < size; y++) {\n    for (let x = 0; x < size; x++) {\n      const px = (x / size) * Math.PI * 2\n      const py = (y / size) * Math.PI * 2\n      const noise =\n        0.5 +\n        0.2 * Math.sin(px + phases[0]) * Math.cos(py + phases[1]) +\n        0.12 * Math.sin(px * 2 + py + phases[2]) +\n        0.08 * Math.cos(px - py * 3 + phases[3]) +\n        0.05 * Math.sin(px * 4 + phases[4]) * Math.cos(py * 4 + phases[5])\n      const value = Math.round(clamp01(noise) * 255)\n      const offset = (y * size + x) * 4\n      pixels[offset] = value\n      pixels[offset + 1] = value\n      pixels[offset + 2] = value\n      pixels[offset + 3] = 255\n    }\n  }\n  const texture = new THREE.DataTexture(\n    pixels,\n    size,\n    size,\n    THREE.RGBAFormat,\n    THREE.UnsignedByteType\n  )\n  texture.minFilter = THREE.LinearFilter\n  texture.magFilter = THREE.LinearFilter\n  texture.needsUpdate = true\n  return texture\n}\nconst vertexShader = /* glsl */ `\nuniform float uTime;\nuniform sampler2D uPerlinTexture;\nvarying vec2 vUv;\n\nvoid main() {\n  vUv = uv;\n  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`\n\nconst fragmentShader = /* glsl */ `\nuniform float uTime;\nuniform float uAnimation;\nuniform float uInverted;\nuniform float uOffsets[7];\nuniform vec3 uColor1;\nuniform vec3 uColor2;\nuniform float uInputVolume;\nuniform float uOutputVolume;\nuniform float uOpacity;\nuniform sampler2D uPerlinTexture;\nvarying vec2 vUv;\n\nconst float PI = 3.14159265358979323846;\n\n// Draw a single oval with soft edges and calculate its gradient color\nbool drawOval(vec2 polarUv, vec2 polarCenter, float a, float b, bool reverseGradient, float softness, out vec4 color) {\n    vec2 p = polarUv - polarCenter;\n    float oval = (p.x * p.x) / (a * a) + (p.y * p.y) / (b * b);\n\n    float edge = smoothstep(1.0, 1.0 - softness, oval);\n\n    if (edge > 0.0) {\n        float gradient = reverseGradient ? (1.0 - (p.x / a + 1.0) / 2.0) : ((p.x / a + 1.0) / 2.0);\n        // Flatten gradient toward middle value for more uniform appearance\n        gradient = mix(0.5, gradient, 0.1);\n        color = vec4(vec3(gradient), 0.85 * edge);\n        return true;\n    }\n    return false;\n}\n\n// Map grayscale value to a 4-color ramp (color1, color2, color3, color4)\nvec3 colorRamp(float grayscale, vec3 color1, vec3 color2, vec3 color3, vec3 color4) {\n    if (grayscale < 0.33) {\n        return mix(color1, color2, grayscale * 3.0);\n    } else if (grayscale < 0.66) {\n        return mix(color2, color3, (grayscale - 0.33) * 3.0);\n    } else {\n        return mix(color3, color4, (grayscale - 0.66) * 3.0);\n    }\n}\n\nvec2 hash2(vec2 p) {\n    return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);\n}\n\n// 2D noise for the ring\nfloat noise2D(vec2 p) {\n    vec2 i = floor(p);\n    vec2 f = fract(p);\n    \n    vec2 u = f * f * (3.0 - 2.0 * f);\n    float n = mix(\n        mix(dot(hash2(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),\n            dot(hash2(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)), u.x),\n        mix(dot(hash2(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),\n            dot(hash2(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)), u.x),\n        u.y\n    );\n\n    return 0.5 + 0.5 * n;\n}\n\nfloat sharpRing(vec3 decomposed, float time) {\n    float ringStart = 1.0;\n    float ringWidth = 0.3;\n    float noiseScale = 5.0;\n\n    float noise = mix(\n        noise2D(vec2(decomposed.x, time) * noiseScale),\n        noise2D(vec2(decomposed.y, time) * noiseScale),\n        decomposed.z\n    );\n\n    noise = (noise - 0.5) * 2.5;\n\n    return ringStart + noise * ringWidth * 1.5;\n}\n\nfloat smoothRing(vec3 decomposed, float time) {\n    float ringStart = 0.9;\n    float ringWidth = 0.2;\n    float noiseScale = 6.0;\n\n    float noise = mix(\n        noise2D(vec2(decomposed.x, time) * noiseScale),\n        noise2D(vec2(decomposed.y, time) * noiseScale),\n        decomposed.z\n    );\n\n    noise = (noise - 0.5) * 5.0;\n\n    return ringStart + noise * ringWidth;\n}\n\nfloat flow(vec3 decomposed, float time) {\n    return mix(\n        texture(uPerlinTexture, vec2(time, decomposed.x / 2.0)).r,\n        texture(uPerlinTexture, vec2(time, decomposed.y / 2.0)).r,\n        decomposed.z\n    );\n}\n\nvoid main() {\n    // Normalize vUv to be centered around (0.0, 0.0)\n    vec2 uv = vUv * 2.0 - 1.0;\n\n    // Convert uv to polar coordinates\n    float radius = length(uv);\n    float theta = atan(uv.y, uv.x);\n    if (theta < 0.0) theta += 2.0 * PI; // Normalize theta to [0, 2*PI]\n\n    // Decomposed angle is used for sampling noise textures without seams:\n    // float noise = mix(sample(decomposed.x), sample(decomposed.y), decomposed.z);\n    vec3 decomposed = vec3(\n        // angle in the range [0, 1]\n        theta / (2.0 * PI),\n        // angle offset by 180 degrees in the range [1, 2]\n        mod(theta / (2.0 * PI) + 0.5, 1.0) + 1.0,\n        // mixing factor between two noises\n        abs(theta / PI - 1.0)\n    );\n\n    // Add noise to the angle for a flow-like distortion (reduced for flatter look)\n    float noise = flow(decomposed, radius * 0.03 - uAnimation * 0.2) - 0.5;\n    theta += noise * mix(0.08, 0.25, uOutputVolume);\n\n    // Initialize the base color to white\n    vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\n\n    // Original parameters for the ovals in polar coordinates\n    float originalCenters[7] = float[7](0.0, 0.5 * PI, 1.0 * PI, 1.5 * PI, 2.0 * PI, 2.5 * PI, 3.0 * PI);\n\n    // Parameters for the animated centers in polar coordinates\n    float centers[7];\n    for (int i = 0; i < 7; i++) {\n        centers[i] = originalCenters[i] + 0.5 * sin(uTime / 20.0 + uOffsets[i]);\n    }\n\n    float a, b;\n    vec4 ovalColor;\n\n    // Check if the pixel is inside any of the ovals\n    for (int i = 0; i < 7; i++) {\n        float noise = texture(uPerlinTexture, vec2(mod(centers[i] + uTime * 0.05, 1.0), 0.5)).r;\n        a = 0.5 + noise * 0.3; // Increased for more coverage\n        b = noise * mix(3.5, 2.5, uInputVolume); // Increased height for fuller appearance\n        bool reverseGradient = (i % 2 == 1); // Reverse gradient for every second oval\n\n        // Calculate the distance in polar coordinates\n        float distTheta = min(\n            abs(theta - centers[i]),\n            min(\n                abs(theta + 2.0 * PI - centers[i]),\n                abs(theta - 2.0 * PI - centers[i])\n            )\n        );\n        float distRadius = radius;\n\n        float softness = 0.6; // Increased softness for flatter, less pronounced edges\n\n        // Check if the pixel is inside the oval in polar coordinates\n        if (drawOval(vec2(distTheta, distRadius), vec2(0.0, 0.0), a, b, reverseGradient, softness, ovalColor)) {\n            // Blend the oval color with the existing color\n            color.rgb = mix(color.rgb, ovalColor.rgb, ovalColor.a);\n            color.a = max(color.a, ovalColor.a); // Max alpha\n        }\n    }\n    \n    // Calculate both noisy rings\n    float ringRadius1 = sharpRing(decomposed, uTime * 0.1);\n    float ringRadius2 = smoothRing(decomposed, uTime * 0.1);\n    \n    // Adjust rings based on input volume (reduced for flatter appearance)\n    float inputRadius1 = radius + uInputVolume * 0.2;\n    float inputRadius2 = radius + uInputVolume * 0.15;\n    float opacity1 = mix(0.2, 0.6, uInputVolume);\n    float opacity2 = mix(0.15, 0.45, uInputVolume);\n\n    // Blend both rings\n    float ringAlpha1 = (inputRadius2 >= ringRadius1) ? opacity1 : 0.0;\n    float ringAlpha2 = smoothstep(ringRadius2 - 0.05, ringRadius2 + 0.05, inputRadius1) * opacity2;\n    \n    float totalRingAlpha = max(ringAlpha1, ringAlpha2);\n    \n    // Apply screen blend mode for combined rings\n    vec3 ringColor = vec3(1.0); // White ring color\n    color.rgb = 1.0 - (1.0 - color.rgb) * (1.0 - ringColor * totalRingAlpha);\n\n    // Define colours to ramp against greyscale (could increase the amount of colours in the ramp)\n    vec3 color1 = vec3(0.0, 0.0, 0.0); // Black\n    vec3 color2 = uColor1; // Darker Color\n    vec3 color3 = uColor2; // Lighter Color\n    vec3 color4 = vec3(1.0, 1.0, 1.0); // White\n\n    // Convert grayscale color to the color ramp\n    float luminance = mix(color.r, 1.0 - color.r, uInverted);\n    color.rgb = colorRamp(luminance, color1, color2, color3, color4); // Apply the color ramp\n\n    // Apply fade-in opacity\n    color.a *= uOpacity;\n\n    gl_FragColor = color;\n}\n`\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/types.ts",
          "target": "@components/voice-agents/elevenlabs/types.ts",
          "type": "registry:component",
          "content": "export interface CharacterAlignmentResponseModel {\n  characters: string[]\n  characterStartTimesSeconds: number[]\n  characterEndTimesSeconds: number[]\n}\n\nexport interface ElevenLabsVoice {\n  voiceId?: string\n  name?: string\n  previewUrl?: string\n  labels?: Record<string, string | undefined>\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "elevenlabs-waveform",
      "type": "registry:block",
      "title": "Elevenlabs Waveform",
      "description": "Waveform",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/elevenlabs/waveform.tsx",
          "target": "@components/voice-agents/elevenlabs/waveform.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { acquireMediaStream } from \"@/components/voice-agents/elevenlabs/media\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n  type HTMLAttributes,\n} from \"react\"\n\nexport type WaveformProps = HTMLAttributes<HTMLDivElement> & {\n  data?: number[]\n  barWidth?: number\n  barHeight?: number\n  barGap?: number\n  barRadius?: number\n  barColor?: string\n  fadeEdges?: boolean\n  fadeWidth?: number\n  height?: string | number\n  active?: boolean\n  onBarClick?: (index: number, value: number) => void\n}\n\nexport const Waveform = ({\n  data = [],\n  barWidth = 4,\n  barHeight: baseBarHeight = 4,\n  barGap = 2,\n  barRadius = 2,\n  barColor,\n  fadeEdges = true,\n  fadeWidth = 24,\n  height = 128,\n  onBarClick,\n  className,\n  ...props\n}: WaveformProps) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    const container = containerRef.current\n    if (!canvas || !container) return\n\n    const resizeObserver = new ResizeObserver(() => {\n      const rect = container.getBoundingClientRect()\n      const dpr = window.devicePixelRatio || 1\n\n      canvas.width = rect.width * dpr\n      canvas.height = rect.height * dpr\n      canvas.style.width = `${rect.width}px`\n      canvas.style.height = `${rect.height}px`\n\n      const ctx = canvas.getContext(\"2d\")\n      if (ctx) {\n        ctx.scale(dpr, dpr)\n        renderWaveform()\n      }\n    })\n\n    const renderWaveform = () => {\n      const ctx = canvas.getContext(\"2d\")\n      if (!ctx) return\n\n      const rect = canvas.getBoundingClientRect()\n      ctx.clearRect(0, 0, rect.width, rect.height)\n\n      const computedBarColor =\n        barColor ||\n        getComputedStyle(canvas).getPropertyValue(\"--foreground\") ||\n        \"#000\"\n\n      const barCount = Math.floor(rect.width / (barWidth + barGap))\n      const centerY = rect.height / 2\n\n      for (let i = 0; i < barCount; i++) {\n        const dataIndex = Math.floor((i / barCount) * data.length)\n        const value = data[dataIndex] || 0\n        const barHeight = Math.max(baseBarHeight, value * rect.height * 0.8)\n        const x = i * (barWidth + barGap)\n        const y = centerY - barHeight / 2\n\n        ctx.fillStyle = computedBarColor\n        ctx.globalAlpha = 0.3 + value * 0.7\n\n        if (barRadius > 0) {\n          ctx.beginPath()\n          ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n          ctx.fill()\n        } else {\n          ctx.fillRect(x, y, barWidth, barHeight)\n        }\n      }\n\n      if (fadeEdges && fadeWidth > 0 && rect.width > 0) {\n        const gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n        const fadePercent = Math.min(0.2, fadeWidth / rect.width)\n\n        gradient.addColorStop(0, \"rgba(255,255,255,1)\")\n        gradient.addColorStop(fadePercent, \"rgba(255,255,255,0)\")\n        gradient.addColorStop(1 - fadePercent, \"rgba(255,255,255,0)\")\n        gradient.addColorStop(1, \"rgba(255,255,255,1)\")\n\n        ctx.globalCompositeOperation = \"destination-out\"\n        ctx.fillStyle = gradient\n        ctx.fillRect(0, 0, rect.width, rect.height)\n        ctx.globalCompositeOperation = \"source-over\"\n      }\n\n      ctx.globalAlpha = 1\n    }\n\n    resizeObserver.observe(container)\n    const themeObserver = new MutationObserver(renderWaveform)\n    themeObserver.observe(document.documentElement, {\n      attributes: true,\n      attributeFilter: [\"class\", \"style\", \"data-theme\"],\n    })\n    renderWaveform()\n\n    return () => {\n      resizeObserver.disconnect()\n      themeObserver.disconnect()\n    }\n  }, [\n    data,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    barRadius,\n    barColor,\n    fadeEdges,\n    fadeWidth,\n  ])\n\n  const handleClick = (e: React.MouseEvent<HTMLCanvasElement>) => {\n    if (!onBarClick) return\n\n    const rect = canvasRef.current?.getBoundingClientRect()\n    if (!rect) return\n\n    const x = e.clientX - rect.left\n    const barIndex = Math.floor(x / (barWidth + barGap))\n    const dataIndex = Math.floor(\n      (barIndex * data.length) / Math.floor(rect.width / (barWidth + barGap))\n    )\n\n    if (dataIndex >= 0 && dataIndex < data.length) {\n      onBarClick(dataIndex, data[dataIndex])\n    }\n  }\n\n  return (\n    <div\n      className={cn(\"relative\", className)}\n      ref={containerRef}\n      style={{ height: heightStyle }}\n      {...props}\n    >\n      <canvas\n        className=\"block h-full w-full\"\n        onClick={handleClick}\n        ref={canvasRef}\n      />\n    </div>\n  )\n}\n\nexport type ScrollingWaveformProps = Omit<\n  WaveformProps,\n  \"data\" | \"onBarClick\"\n> & {\n  speed?: number\n  barCount?: number\n  data?: number[]\n}\n\nexport const ScrollingWaveform = ({\n  speed = 50,\n  barCount = 60,\n  barWidth = 4,\n  barHeight: baseBarHeight = 4,\n  barGap = 2,\n  barRadius = 2,\n  barColor,\n  fadeEdges = true,\n  fadeWidth = 24,\n  height = 128,\n  data,\n  className,\n  ...props\n}: ScrollingWaveformProps) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const barsRef = useRef<Array<{ x: number; height: number }>>([])\n  const animationRef = useRef<number>(0)\n  const lastTimeRef = useRef<number>(0)\n  const seedRef = useRef(Math.random())\n  const dataIndexRef = useRef(0)\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    const container = containerRef.current\n    if (!canvas || !container) return\n\n    const resizeObserver = new ResizeObserver(() => {\n      const rect = container.getBoundingClientRect()\n      const dpr = window.devicePixelRatio || 1\n\n      canvas.width = rect.width * dpr\n      canvas.height = rect.height * dpr\n      canvas.style.width = `${rect.width}px`\n      canvas.style.height = `${rect.height}px`\n\n      const ctx = canvas.getContext(\"2d\")\n      if (ctx) {\n        ctx.scale(dpr, dpr)\n      }\n\n      if (barsRef.current.length === 0) {\n        const step = barWidth + barGap\n        let currentX = rect.width\n        let index = 0\n        const seededRandom = (i: number) => {\n          const x = Math.sin(seedRef.current * 10000 + i) * 10000\n          return x - Math.floor(x)\n        }\n        while (currentX > -step) {\n          barsRef.current.push({\n            x: currentX,\n            height: 0.2 + seededRandom(index++) * 0.6,\n          })\n          currentX -= step\n        }\n      }\n    })\n\n    resizeObserver.observe(container)\n    return () => resizeObserver.disconnect()\n  }, [barWidth, barGap])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    const ctx = canvas.getContext(\"2d\")\n    if (!ctx) return\n    const reduceMotion = window.matchMedia(\n      \"(prefers-reduced-motion: reduce)\"\n    ).matches\n\n    const animate = (currentTime: number) => {\n      const deltaTime = lastTimeRef.current\n        ? (currentTime - lastTimeRef.current) / 1000\n        : 0\n      lastTimeRef.current = currentTime\n\n      const rect = canvas.getBoundingClientRect()\n      ctx.clearRect(0, 0, rect.width, rect.height)\n\n      const computedBarColor =\n        barColor ||\n        getComputedStyle(canvas).getPropertyValue(\"--foreground\") ||\n        \"#000\"\n\n      const step = barWidth + barGap\n      for (let i = 0; i < barsRef.current.length; i++) {\n        barsRef.current[i].x -= speed * deltaTime\n      }\n\n      barsRef.current = barsRef.current.filter(\n        (bar) => bar.x + barWidth > -step\n      )\n\n      while (\n        barsRef.current.length === 0 ||\n        barsRef.current[barsRef.current.length - 1].x < rect.width\n      ) {\n        const lastBar = barsRef.current[barsRef.current.length - 1]\n        const nextX = lastBar ? lastBar.x + step : rect.width\n\n        let newHeight: number\n        if (data && data.length > 0) {\n          newHeight = data[dataIndexRef.current % data.length] || 0.1\n          dataIndexRef.current = (dataIndexRef.current + 1) % data.length\n        } else {\n          const time = Date.now() / 1000\n          const uniqueIndex = barsRef.current.length + time * 0.01\n          const seededRandom = (index: number) => {\n            const x = Math.sin(seedRef.current * 10000 + index * 137.5) * 10000\n            return x - Math.floor(x)\n          }\n          const wave1 = Math.sin(uniqueIndex * 0.1) * 0.2\n          const wave2 = Math.cos(uniqueIndex * 0.05) * 0.15\n          const randomComponent = seededRandom(uniqueIndex) * 0.4\n          newHeight = Math.max(\n            0.1,\n            Math.min(0.9, 0.3 + wave1 + wave2 + randomComponent)\n          )\n        }\n\n        barsRef.current.push({\n          x: nextX,\n          height: newHeight,\n        })\n        if (barsRef.current.length > barCount * 2) break\n      }\n\n      const centerY = rect.height / 2\n      for (const bar of barsRef.current) {\n        if (bar.x < rect.width && bar.x + barWidth > 0) {\n          const barHeight = Math.max(\n            baseBarHeight,\n            bar.height * rect.height * 0.6\n          )\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.3 + bar.height * 0.7\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(bar.x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(bar.x, y, barWidth, barHeight)\n          }\n        }\n      }\n\n      if (fadeEdges && fadeWidth > 0) {\n        const gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n        const fadePercent = Math.min(0.2, fadeWidth / rect.width)\n\n        gradient.addColorStop(0, \"rgba(255,255,255,1)\")\n        gradient.addColorStop(fadePercent, \"rgba(255,255,255,0)\")\n        gradient.addColorStop(1 - fadePercent, \"rgba(255,255,255,0)\")\n        gradient.addColorStop(1, \"rgba(255,255,255,1)\")\n\n        ctx.globalCompositeOperation = \"destination-out\"\n        ctx.fillStyle = gradient\n        ctx.fillRect(0, 0, rect.width, rect.height)\n        ctx.globalCompositeOperation = \"source-over\"\n      }\n\n      ctx.globalAlpha = 1\n\n      if (!reduceMotion) {\n        animationRef.current = requestAnimationFrame(animate)\n      }\n    }\n\n    animationRef.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n      }\n    }\n  }, [\n    speed,\n    barCount,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    barRadius,\n    barColor,\n    fadeEdges,\n    fadeWidth,\n    data,\n  ])\n\n  return (\n    <div\n      className={cn(\"relative flex items-center\", className)}\n      ref={containerRef}\n      style={{ height: heightStyle }}\n      {...props}\n    >\n      <canvas className=\"block h-full w-full\" ref={canvasRef} />\n    </div>\n  )\n}\n\nexport type AudioScrubberProps = WaveformProps & {\n  currentTime?: number\n  duration?: number\n  onSeek?: (time: number) => void\n  showHandle?: boolean\n}\n\nexport const AudioScrubber = ({\n  data = [],\n  currentTime = 0,\n  duration = 100,\n  onSeek,\n  showHandle = true,\n  barWidth = 3,\n  barHeight,\n  barGap = 1,\n  barRadius = 1,\n  barColor,\n  height = 128,\n  className,\n  ...props\n}: AudioScrubberProps) => {\n  const waveformData =\n    data.length > 0\n      ? data\n      : Array.from({ length: 100 }, () => 0.2 + Math.random() * 0.6)\n\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n  const safeDuration = Math.max(0, duration)\n  const safeTime = Math.min(safeDuration, Math.max(0, currentTime))\n  const progress = safeDuration > 0 ? safeTime / safeDuration : 0\n\n  return (\n    <div\n      className={cn(\n        \"focus-within:ring-ring relative cursor-pointer rounded-sm select-none focus-within:ring-2 focus-within:ring-offset-2\",\n        className\n      )}\n      style={{ height: heightStyle }}\n      {...props}\n    >\n      <Waveform\n        barColor={barColor}\n        barGap={barGap}\n        barRadius={barRadius}\n        barWidth={barWidth}\n        barHeight={barHeight}\n        data={waveformData}\n        fadeEdges={false}\n        height={height}\n      />\n\n      <input\n        aria-label=\"Audio waveform scrubber\"\n        className=\"absolute inset-0 z-10 m-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n        disabled={safeDuration === 0}\n        max={safeDuration}\n        min={0}\n        onChange={(event) => onSeek?.(Number(event.currentTarget.value))}\n        step=\"any\"\n        type=\"range\"\n        value={safeTime}\n      />\n\n      <div\n        className=\"bg-primary/20 pointer-events-none absolute inset-y-0 left-0\"\n        style={{ width: `${progress * 100}%` }}\n      />\n\n      <div\n        className=\"bg-primary pointer-events-none absolute top-0 bottom-0 w-0.5\"\n        style={{ left: `${progress * 100}%` }}\n      />\n\n      {showHandle && (\n        <div\n          className=\"border-background bg-primary pointer-events-none absolute top-1/2 h-4 w-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 shadow-lg transition-transform hover:scale-110\"\n          style={{ left: `${progress * 100}%` }}\n        />\n      )}\n    </div>\n  )\n}\n\nexport type MicrophoneWaveformProps = WaveformProps & {\n  active?: boolean\n  processing?: boolean\n  fftSize?: number\n  smoothingTimeConstant?: number\n  sensitivity?: number\n  onError?: (error: Error) => void\n}\n\nexport const MicrophoneWaveform = ({\n  active = false,\n  processing = false,\n  fftSize = 256,\n  smoothingTimeConstant = 0.8,\n  sensitivity = 1,\n  onError,\n  ...props\n}: MicrophoneWaveformProps) => {\n  const [data, setData] = useState<number[]>([])\n  const analyserRef = useRef<AnalyserNode | null>(null)\n  const audioContextRef = useRef<AudioContext | null>(null)\n  const streamRef = useRef<MediaStream | null>(null)\n  const animationIdRef = useRef<number | null>(null)\n  const processingAnimationRef = useRef<number | null>(null)\n  const lastActiveDataRef = useRef<number[]>([])\n  const dataRef = useRef<number[]>([])\n  const transitionProgressRef = useRef(0)\n\n  useEffect(() => {\n    dataRef.current = data\n  }, [data])\n\n  useEffect(() => {\n    if (processing && !active) {\n      let time = 0\n      transitionProgressRef.current = 0\n\n      const animateProcessing = () => {\n        time += 0.03\n        transitionProgressRef.current = Math.min(\n          1,\n          transitionProgressRef.current + 0.02\n        )\n\n        const processingData = []\n        const barCount = 45\n\n        for (let i = 0; i < barCount; i++) {\n          const normalizedPosition = (i - barCount / 2) / (barCount / 2)\n          const centerWeight = 1 - Math.abs(normalizedPosition) * 0.4\n\n          const wave1 = Math.sin(time * 1.5 + i * 0.15) * 0.25\n          const wave2 = Math.sin(time * 0.8 - i * 0.1) * 0.2\n          const wave3 = Math.cos(time * 2 + i * 0.05) * 0.15\n          const combinedWave = wave1 + wave2 + wave3\n          const processingValue = (0.2 + combinedWave) * centerWeight\n\n          let finalValue = processingValue\n          if (\n            lastActiveDataRef.current.length > 0 &&\n            transitionProgressRef.current < 1\n          ) {\n            const lastDataIndex = Math.floor(\n              (i / barCount) * lastActiveDataRef.current.length\n            )\n            const lastValue = lastActiveDataRef.current[lastDataIndex] || 0\n            finalValue =\n              lastValue * (1 - transitionProgressRef.current) +\n              processingValue * transitionProgressRef.current\n          }\n\n          processingData.push(Math.max(0.05, Math.min(1, finalValue)))\n        }\n\n        setData(processingData)\n        processingAnimationRef.current =\n          requestAnimationFrame(animateProcessing)\n      }\n\n      animateProcessing()\n\n      return () => {\n        if (processingAnimationRef.current) {\n          cancelAnimationFrame(processingAnimationRef.current)\n        }\n      }\n    } else if (!active && !processing) {\n      if (dataRef.current.length > 0) {\n        let fadeProgress = 0\n        let fadeFrame = 0\n        const fadeToIdle = () => {\n          fadeProgress += 0.03\n          if (fadeProgress < 1) {\n            const fadedData = dataRef.current.map(\n              (value) => value * (1 - fadeProgress)\n            )\n            dataRef.current = fadedData\n            setData(fadedData)\n            fadeFrame = requestAnimationFrame(fadeToIdle)\n          } else {\n            dataRef.current = []\n            setData([])\n          }\n        }\n        fadeToIdle()\n        return () => cancelAnimationFrame(fadeFrame)\n      }\n      return\n    }\n  }, [processing, active])\n\n  useEffect(() => {\n    let cancelled = false\n    if (!active) {\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n      }\n      if (animationIdRef.current) {\n        cancelAnimationFrame(animationIdRef.current)\n      }\n      return\n    }\n\n    const setupMicrophone = async () => {\n      try {\n        const stream = await acquireMediaStream(\n          { audio: true },\n          () => cancelled\n        )\n        if (!stream) return\n        streamRef.current = stream\n\n        const audioContext = new (window.AudioContext ||\n          (window as unknown as { webkitAudioContext: typeof AudioContext })\n            .webkitAudioContext)()\n        const analyser = audioContext.createAnalyser()\n        analyser.fftSize = fftSize\n        analyser.smoothingTimeConstant = smoothingTimeConstant\n\n        const source = audioContext.createMediaStreamSource(stream)\n        source.connect(analyser)\n\n        audioContextRef.current = audioContext\n        analyserRef.current = analyser\n\n        const dataArray = new Uint8Array(analyser.frequencyBinCount)\n\n        const updateData = () => {\n          if (!analyserRef.current || !active) return\n\n          analyserRef.current.getByteFrequencyData(dataArray)\n\n          const startFreq = Math.floor(dataArray.length * 0.05)\n          const endFreq = Math.floor(dataArray.length * 0.4)\n          const relevantData = dataArray.slice(startFreq, endFreq)\n\n          const halfLength = Math.floor(relevantData.length / 2)\n          const normalizedData = []\n\n          for (let i = halfLength - 1; i >= 0; i--) {\n            const value = Math.min(1, (relevantData[i] / 255) * sensitivity)\n            normalizedData.push(value)\n          }\n\n          for (let i = 0; i < halfLength; i++) {\n            const value = Math.min(1, (relevantData[i] / 255) * sensitivity)\n            normalizedData.push(value)\n          }\n\n          setData(normalizedData)\n          lastActiveDataRef.current = normalizedData\n\n          animationIdRef.current = requestAnimationFrame(updateData)\n        }\n\n        updateData()\n      } catch (error) {\n        if (!cancelled) onError?.(error as Error)\n      }\n    }\n\n    setupMicrophone()\n\n    return () => {\n      cancelled = true\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n      }\n      if (animationIdRef.current) {\n        cancelAnimationFrame(animationIdRef.current)\n      }\n    }\n  }, [active, fftSize, smoothingTimeConstant, sensitivity, onError])\n\n  return <Waveform data={data} {...props} />\n}\n\nexport type StaticWaveformProps = WaveformProps & {\n  bars?: number\n  seed?: number\n}\n\nexport const StaticWaveform = ({\n  bars = 40,\n  seed = 42,\n  ...props\n}: StaticWaveformProps) => {\n  const data = useMemo(() => {\n    const random = (seedValue: number) => {\n      const x = Math.sin(seedValue) * 10000\n      return x - Math.floor(x)\n    }\n\n    return Array.from({ length: bars }, (_, i) => 0.2 + random(seed + i) * 0.6)\n  }, [bars, seed])\n\n  return <Waveform data={data} {...props} />\n}\n\nexport type LiveMicrophoneWaveformProps = Omit<\n  ScrollingWaveformProps,\n  \"barCount\"\n> & {\n  active?: boolean\n  fftSize?: number\n  smoothingTimeConstant?: number\n  sensitivity?: number\n  onError?: (error: Error) => void\n  historySize?: number\n  updateRate?: number\n  savedHistoryRef?: React.MutableRefObject<number[]>\n  dragOffset?: number\n  setDragOffset?: (offset: number) => void\n  enableAudioPlayback?: boolean\n  playbackRate?: number\n}\n\nexport const LiveMicrophoneWaveform = ({\n  active = false,\n  fftSize = 256,\n  smoothingTimeConstant = 0.8,\n  sensitivity = 1,\n  onError,\n  historySize = 150,\n  updateRate = 50,\n  barWidth = 3,\n  barHeight: baseBarHeight = 4,\n  barGap = 1,\n  barRadius = 1,\n  barColor,\n  fadeEdges = true,\n  fadeWidth = 24,\n  height = 128,\n  className,\n  savedHistoryRef,\n  dragOffset: externalDragOffset,\n  setDragOffset: externalSetDragOffset,\n  enableAudioPlayback = true,\n  playbackRate = 1,\n  ...props\n}: LiveMicrophoneWaveformProps) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const internalHistoryRef = useRef<number[]>([])\n  const historyRef = savedHistoryRef || internalHistoryRef\n  const analyserRef = useRef<AnalyserNode | null>(null)\n  const audioContextRef = useRef<AudioContext | null>(null)\n  const streamRef = useRef<MediaStream | null>(null)\n  const animationRef = useRef<number>(0)\n  const lastUpdateRef = useRef<number>(0)\n  const [internalDragOffset, setInternalDragOffset] = useState(0)\n  const [isDragging, setIsDragging] = useState(false)\n  const [playbackPosition, setPlaybackPosition] = useState<number | null>(null)\n  const dragStartXRef = useRef<number>(0)\n  const dragStartOffsetRef = useRef<number>(0)\n  const playbackStartTimeRef = useRef<number>(0)\n\n  // Audio recording and playback refs\n  const mediaRecorderRef = useRef<MediaRecorder | null>(null)\n  const audioChunksRef = useRef<Blob[]>([])\n  const audioBufferRef = useRef<AudioBuffer | null>(null)\n  const sourceNodeRef = useRef<AudioBufferSourceNode | null>(null)\n  const scrubSourceRef = useRef<AudioBufferSourceNode | null>(null)\n\n  // Use external drag state if provided, otherwise use internal\n  const dragOffset = externalDragOffset ?? internalDragOffset\n  const setDragOffset = externalSetDragOffset ?? setInternalDragOffset\n\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    const container = containerRef.current\n    if (!canvas || !container) return\n\n    const resizeObserver = new ResizeObserver(() => {\n      const rect = container.getBoundingClientRect()\n      const dpr = window.devicePixelRatio || 1\n\n      canvas.width = rect.width * dpr\n      canvas.height = rect.height * dpr\n      canvas.style.width = `${rect.width}px`\n      canvas.style.height = `${rect.height}px`\n\n      const ctx = canvas.getContext(\"2d\")\n      if (ctx) {\n        ctx.scale(dpr, dpr)\n      }\n    })\n\n    resizeObserver.observe(container)\n    return () => resizeObserver.disconnect()\n  }, [])\n\n  useEffect(() => {\n    let cancelled = false\n    if (!active) {\n      if (\n        mediaRecorderRef.current &&\n        mediaRecorderRef.current.state !== \"inactive\"\n      ) {\n        mediaRecorderRef.current.stop()\n      }\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n      }\n      // Process recorded audio when stopping\n      if (enableAudioPlayback && audioChunksRef.current.length > 0) {\n        const audioBlob = new Blob(audioChunksRef.current, {\n          type: \"audio/webm\",\n        })\n        processAudioBlob(audioBlob)\n      }\n      return\n    }\n\n    setDragOffset?.(0)\n    historyRef.current = []\n    audioChunksRef.current = []\n    audioBufferRef.current = null\n    setPlaybackPosition(null)\n\n    const setupMicrophone = async () => {\n      try {\n        const stream = await acquireMediaStream(\n          { audio: true },\n          () => cancelled\n        )\n        if (!stream) return\n        streamRef.current = stream\n\n        const audioContext = new (window.AudioContext ||\n          (window as unknown as { webkitAudioContext: typeof AudioContext })\n            .webkitAudioContext)()\n        const analyser = audioContext.createAnalyser()\n        analyser.fftSize = fftSize\n        analyser.smoothingTimeConstant = smoothingTimeConstant\n\n        const source = audioContext.createMediaStreamSource(stream)\n        source.connect(analyser)\n\n        audioContextRef.current = audioContext\n        analyserRef.current = analyser\n\n        if (enableAudioPlayback) {\n          const mediaRecorder = new MediaRecorder(stream)\n          mediaRecorderRef.current = mediaRecorder\n\n          mediaRecorder.ondataavailable = (event) => {\n            if (event.data.size > 0) {\n              audioChunksRef.current.push(event.data)\n            }\n          }\n\n          mediaRecorder.start(100)\n        }\n      } catch (error) {\n        if (!cancelled) onError?.(error as Error)\n      }\n    }\n\n    setupMicrophone()\n\n    return () => {\n      cancelled = true\n      if (\n        mediaRecorderRef.current &&\n        mediaRecorderRef.current.state !== \"inactive\"\n      ) {\n        mediaRecorderRef.current.stop()\n      }\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n      }\n      if (sourceNodeRef.current) {\n        sourceNodeRef.current.stop()\n      }\n      if (scrubSourceRef.current) {\n        scrubSourceRef.current.stop()\n      }\n    }\n  }, [\n    active,\n    fftSize,\n    smoothingTimeConstant,\n    onError,\n    setDragOffset,\n    enableAudioPlayback,\n    historyRef,\n  ])\n\n  const processAudioBlob = async (blob: Blob) => {\n    try {\n      const arrayBuffer = await blob.arrayBuffer()\n      if (audioContextRef.current) {\n        const audioBuffer =\n          await audioContextRef.current.decodeAudioData(arrayBuffer)\n        audioBufferRef.current = audioBuffer\n      }\n    } catch (error) {\n      console.error(\"Error processing audio:\", error)\n    }\n  }\n\n  const playScrubSound = useCallback(\n    (position: number, direction: number) => {\n      if (\n        !enableAudioPlayback ||\n        !audioBufferRef.current ||\n        !audioContextRef.current\n      )\n        return\n\n      if (scrubSourceRef.current) {\n        try {\n          scrubSourceRef.current.stop()\n        } catch {}\n      }\n\n      const source = audioContextRef.current.createBufferSource()\n      source.buffer = audioBufferRef.current\n\n      const speed = Math.abs(direction)\n      const playbackRate =\n        direction > 0\n          ? Math.min(3, 1 + speed * 0.1)\n          : Math.max(-3, -1 - speed * 0.1)\n\n      source.playbackRate.value = playbackRate\n\n      const filter = audioContextRef.current.createBiquadFilter()\n      filter.type = \"lowpass\"\n      filter.frequency.value = Math.max(200, 2000 - speed * 100)\n\n      source.connect(filter)\n      filter.connect(audioContextRef.current.destination)\n\n      const startTime = Math.max(\n        0,\n        Math.min(position, audioBufferRef.current.duration - 0.1)\n      )\n      source.start(0, startTime, 0.1)\n      scrubSourceRef.current = source\n    },\n    [enableAudioPlayback]\n  )\n\n  const playFromPosition = useCallback(\n    (position: number) => {\n      if (\n        !enableAudioPlayback ||\n        !audioBufferRef.current ||\n        !audioContextRef.current\n      )\n        return\n\n      if (sourceNodeRef.current) {\n        try {\n          sourceNodeRef.current.stop()\n        } catch {}\n      }\n\n      const source = audioContextRef.current.createBufferSource()\n      source.buffer = audioBufferRef.current\n      source.playbackRate.value = playbackRate\n      source.connect(audioContextRef.current.destination)\n\n      const startTime = Math.max(\n        0,\n        Math.min(position, audioBufferRef.current.duration)\n      )\n      source.start(0, startTime)\n      sourceNodeRef.current = source\n\n      playbackStartTimeRef.current =\n        audioContextRef.current.currentTime - startTime\n      setPlaybackPosition(startTime)\n\n      source.onended = () => {\n        setPlaybackPosition(null)\n      }\n    },\n    [enableAudioPlayback, playbackRate]\n  )\n\n  useEffect(() => {\n    if (playbackPosition === null || !audioBufferRef.current) return\n\n    let animationId: number\n    const updatePlaybackVisual = () => {\n      if (\n        audioContextRef.current &&\n        sourceNodeRef.current &&\n        audioBufferRef.current\n      ) {\n        const elapsed =\n          audioContextRef.current.currentTime - playbackStartTimeRef.current\n        const currentPos = playbackPosition + elapsed * playbackRate\n\n        if (currentPos < audioBufferRef.current.duration) {\n          const progressRatio = currentPos / audioBufferRef.current.duration\n          const currentBarIndex = Math.floor(\n            progressRatio * historyRef.current.length\n          )\n          const step = barWidth + barGap\n\n          const containerWidth =\n            containerRef.current?.getBoundingClientRect().width || 0\n          const viewBars = Math.floor(containerWidth / step)\n          const targetOffset =\n            -(currentBarIndex - (historyRef.current.length - viewBars)) * step\n          const clampedOffset = Math.max(\n            -(historyRef.current.length - viewBars) * step,\n            Math.min(0, targetOffset)\n          )\n\n          setDragOffset?.(clampedOffset)\n          animationId = requestAnimationFrame(updatePlaybackVisual)\n        } else {\n          setPlaybackPosition(null)\n          const step = barWidth + barGap\n          const containerWidth =\n            containerRef.current?.getBoundingClientRect().width || 0\n          const viewBars = Math.floor(containerWidth / step)\n          setDragOffset?.(-(historyRef.current.length - viewBars) * step)\n        }\n      }\n    }\n\n    animationId = requestAnimationFrame(updatePlaybackVisual)\n\n    return () => {\n      if (animationId) cancelAnimationFrame(animationId)\n    }\n  }, [\n    playbackPosition,\n    playbackRate,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    setDragOffset,\n    historyRef,\n  ])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n    if (!active && historyRef.current.length === 0 && playbackPosition === null)\n      return\n\n    const ctx = canvas.getContext(\"2d\")\n    if (!ctx) return\n\n    const animate = (currentTime: number) => {\n      if (active && currentTime - lastUpdateRef.current > updateRate) {\n        lastUpdateRef.current = currentTime\n\n        if (analyserRef.current) {\n          const dataArray = new Uint8Array(\n            analyserRef.current.frequencyBinCount\n          )\n          analyserRef.current.getByteFrequencyData(dataArray)\n\n          let sum = 0\n          for (let i = 0; i < dataArray.length; i++) {\n            sum += dataArray[i]\n          }\n          const average = (sum / dataArray.length / 255) * sensitivity\n\n          historyRef.current.push(Math.min(1, Math.max(0.05, average)))\n\n          if (historyRef.current.length > historySize) {\n            historyRef.current.shift()\n          }\n        }\n      }\n\n      const rect = canvas.getBoundingClientRect()\n      ctx.clearRect(0, 0, rect.width, rect.height)\n\n      const computedBarColor =\n        barColor ||\n        getComputedStyle(canvas).getPropertyValue(\"--foreground\") ||\n        \"#000\"\n\n      const step = barWidth + barGap\n      const barCount = Math.floor(rect.width / step)\n      const centerY = rect.height / 2\n\n      const dataToRender = historyRef.current\n\n      if (dataToRender.length > 0) {\n        const offsetInBars = Math.floor(dragOffset / step)\n\n        for (let i = 0; i < barCount; i++) {\n          let dataIndex\n\n          if (active) {\n            dataIndex = dataToRender.length - 1 - i\n          } else {\n            dataIndex = Math.max(\n              0,\n              Math.min(\n                dataToRender.length - 1,\n                dataToRender.length - 1 - i - Math.floor(offsetInBars)\n              )\n            )\n          }\n\n          if (dataIndex >= 0 && dataIndex < dataToRender.length) {\n            const value = dataToRender[dataIndex]\n            if (value !== undefined) {\n              const x = rect.width - (i + 1) * step\n              const barHeight = Math.max(\n                baseBarHeight,\n                value * rect.height * 0.7\n              )\n              const y = centerY - barHeight / 2\n\n              ctx.fillStyle = computedBarColor\n              ctx.globalAlpha = 0.3 + value * 0.7\n\n              if (barRadius > 0) {\n                ctx.beginPath()\n                ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n                ctx.fill()\n              } else {\n                ctx.fillRect(x, y, barWidth, barHeight)\n              }\n            }\n          }\n        }\n      }\n\n      if (fadeEdges && fadeWidth > 0) {\n        const gradient = ctx.createLinearGradient(0, 0, rect.width, 0)\n        const fadePercent = Math.min(0.2, fadeWidth / rect.width)\n\n        gradient.addColorStop(0, \"rgba(255,255,255,1)\")\n        gradient.addColorStop(fadePercent, \"rgba(255,255,255,0)\")\n        gradient.addColorStop(1 - fadePercent, \"rgba(255,255,255,0)\")\n        gradient.addColorStop(1, \"rgba(255,255,255,1)\")\n\n        ctx.globalCompositeOperation = \"destination-out\"\n        ctx.fillStyle = gradient\n        ctx.fillRect(0, 0, rect.width, rect.height)\n        ctx.globalCompositeOperation = \"source-over\"\n      }\n\n      ctx.globalAlpha = 1\n\n      animationRef.current = requestAnimationFrame(animate)\n    }\n\n    if (active || historyRef.current.length > 0 || playbackPosition !== null) {\n      animationRef.current = requestAnimationFrame(animate)\n    }\n\n    return () => {\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n      }\n    }\n  }, [\n    active,\n    sensitivity,\n    updateRate,\n    historySize,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    barRadius,\n    barColor,\n    fadeEdges,\n    fadeWidth,\n    dragOffset,\n    playbackPosition,\n    historyRef,\n  ])\n\n  const handleMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {\n    if (active || historyRef.current.length === 0) return\n\n    e.preventDefault()\n    setIsDragging(true)\n    dragStartXRef.current = e.clientX\n    dragStartOffsetRef.current = dragOffset\n  }\n\n  useEffect(() => {\n    if (!isDragging) return\n\n    let lastScrubTime = 0\n    let lastMouseX = dragStartXRef.current\n    const handleMouseMove = (e: MouseEvent) => {\n      const deltaX = e.clientX - dragStartXRef.current\n      const newOffset = dragStartOffsetRef.current - deltaX * 0.5 // Reduce sensitivity\n\n      const step = barWidth + barGap\n      const maxBars = historyRef.current.length\n      const viewWidth = canvasRef.current?.getBoundingClientRect().width || 0\n      const viewBars = Math.floor(viewWidth / step)\n\n      const maxOffset = Math.max(0, (maxBars - viewBars) * step)\n      const minOffset = 0\n      const clampedOffset = Math.max(minOffset, Math.min(maxOffset, newOffset))\n\n      setDragOffset?.(clampedOffset)\n\n      const now = Date.now()\n      if (\n        enableAudioPlayback &&\n        audioBufferRef.current &&\n        now - lastScrubTime > 50\n      ) {\n        lastScrubTime = now\n        const offsetBars = Math.floor(clampedOffset / step)\n        const rightmostBarIndex = Math.max(\n          0,\n          Math.min(maxBars - 1, maxBars - 1 - offsetBars)\n        )\n        const audioPosition =\n          (rightmostBarIndex / maxBars) * audioBufferRef.current.duration\n        const direction = e.clientX - lastMouseX\n        lastMouseX = e.clientX\n        playScrubSound(\n          Math.max(\n            0,\n            Math.min(audioBufferRef.current.duration - 0.1, audioPosition)\n          ),\n          direction\n        )\n      }\n    }\n\n    const handleMouseUp = () => {\n      setIsDragging(false)\n\n      if (enableAudioPlayback && audioBufferRef.current) {\n        const step = barWidth + barGap\n        const maxBars = historyRef.current.length\n        const offsetBars = Math.floor(dragOffset / step)\n        const rightmostBarIndex = Math.max(\n          0,\n          Math.min(maxBars - 1, maxBars - 1 - offsetBars)\n        )\n        const audioPosition =\n          (rightmostBarIndex / maxBars) * audioBufferRef.current.duration\n        playFromPosition(\n          Math.max(\n            0,\n            Math.min(audioBufferRef.current.duration - 0.1, audioPosition)\n          )\n        )\n      }\n\n      if (scrubSourceRef.current) {\n        try {\n          scrubSourceRef.current.stop()\n        } catch {}\n      }\n    }\n\n    document.addEventListener(\"mousemove\", handleMouseMove)\n    document.addEventListener(\"mouseup\", handleMouseUp)\n\n    return () => {\n      document.removeEventListener(\"mousemove\", handleMouseMove)\n      document.removeEventListener(\"mouseup\", handleMouseUp)\n    }\n  }, [\n    isDragging,\n    barWidth,\n    barGap,\n    setDragOffset,\n    dragOffset,\n    enableAudioPlayback,\n    playScrubSound,\n    playFromPosition,\n    historyRef,\n  ])\n\n  return (\n    <div\n      className={cn(\n        \"relative flex items-center\",\n        !active && historyRef.current.length > 0 && \"cursor-pointer\",\n        className\n      )}\n      onMouseDown={handleMouseDown}\n      ref={containerRef}\n      role={!active && historyRef.current.length > 0 ? \"slider\" : undefined}\n      aria-label={\n        !active && historyRef.current.length > 0\n          ? \"Drag to scrub through recording\"\n          : undefined\n      }\n      aria-valuenow={\n        !active && historyRef.current.length > 0\n          ? Math.abs(dragOffset)\n          : undefined\n      }\n      aria-valuemin={!active && historyRef.current.length > 0 ? 0 : undefined}\n      aria-valuemax={\n        !active && historyRef.current.length > 0\n          ? historyRef.current.length\n          : undefined\n      }\n      tabIndex={!active && historyRef.current.length > 0 ? 0 : undefined}\n      style={{ height: heightStyle }}\n      {...props}\n    >\n      <canvas className=\"block h-full w-full\" ref={canvasRef} />\n    </div>\n  )\n}\n\nexport type RecordingWaveformProps = Omit<\n  WaveformProps,\n  \"data\" | \"onBarClick\"\n> & {\n  recording?: boolean\n  fftSize?: number\n  smoothingTimeConstant?: number\n  sensitivity?: number\n  onError?: (error: Error) => void\n  onRecordingComplete?: (data: number[]) => void\n  updateRate?: number\n  showHandle?: boolean\n}\n\nexport const RecordingWaveform = ({\n  recording = false,\n  fftSize = 256,\n  smoothingTimeConstant = 0.8,\n  sensitivity = 1,\n  onError,\n  onRecordingComplete,\n  updateRate = 50,\n  showHandle = true,\n  barWidth = 3,\n  barHeight: baseBarHeight = 4,\n  barGap = 1,\n  barRadius = 1,\n  barColor,\n  height = 128,\n  className,\n  ...props\n}: RecordingWaveformProps) => {\n  const [recordedData, setRecordedData] = useState<number[]>([])\n  const [viewPosition, setViewPosition] = useState(1)\n  const [isDragging, setIsDragging] = useState(false)\n  const [isRecordingComplete, setIsRecordingComplete] = useState(false)\n\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const containerRef = useRef<HTMLDivElement>(null)\n  const recordingDataRef = useRef<number[]>([])\n  const analyserRef = useRef<AnalyserNode | null>(null)\n  const audioContextRef = useRef<AudioContext | null>(null)\n  const streamRef = useRef<MediaStream | null>(null)\n  const animationRef = useRef<number>(0)\n  const lastUpdateRef = useRef<number>(0)\n\n  const heightStyle = typeof height === \"number\" ? `${height}px` : height\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    const container = containerRef.current\n    if (!canvas || !container) return\n\n    const resizeObserver = new ResizeObserver(() => {\n      const rect = container.getBoundingClientRect()\n      const dpr = window.devicePixelRatio || 1\n\n      canvas.width = rect.width * dpr\n      canvas.height = rect.height * dpr\n      canvas.style.width = `${rect.width}px`\n      canvas.style.height = `${rect.height}px`\n\n      const ctx = canvas.getContext(\"2d\")\n      if (ctx) {\n        ctx.scale(dpr, dpr)\n      }\n    })\n\n    resizeObserver.observe(container)\n    return () => resizeObserver.disconnect()\n  }, [])\n\n  useEffect(() => {\n    let cancelled = false\n    if (!recording) {\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n      }\n\n      if (recordingDataRef.current.length > 0) {\n        setRecordedData([...recordingDataRef.current])\n        setIsRecordingComplete(true)\n        onRecordingComplete?.(recordingDataRef.current)\n      }\n      return\n    }\n\n    setIsRecordingComplete(false)\n    recordingDataRef.current = []\n    setRecordedData([])\n    setViewPosition(1)\n\n    const setupMicrophone = async () => {\n      try {\n        const stream = await acquireMediaStream(\n          { audio: true },\n          () => cancelled\n        )\n        if (!stream) return\n        streamRef.current = stream\n\n        const audioContext = new (window.AudioContext ||\n          (window as unknown as { webkitAudioContext: typeof AudioContext })\n            .webkitAudioContext)()\n        const analyser = audioContext.createAnalyser()\n        analyser.fftSize = fftSize\n        analyser.smoothingTimeConstant = smoothingTimeConstant\n\n        const source = audioContext.createMediaStreamSource(stream)\n        source.connect(analyser)\n\n        audioContextRef.current = audioContext\n        analyserRef.current = analyser\n      } catch (error) {\n        if (!cancelled) onError?.(error as Error)\n      }\n    }\n\n    setupMicrophone()\n\n    return () => {\n      cancelled = true\n      if (streamRef.current) {\n        streamRef.current.getTracks().forEach((track) => track.stop())\n      }\n      if (\n        audioContextRef.current &&\n        audioContextRef.current.state !== \"closed\"\n      ) {\n        audioContextRef.current.close()\n      }\n    }\n  }, [recording, fftSize, smoothingTimeConstant, onError, onRecordingComplete])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    const ctx = canvas.getContext(\"2d\")\n    if (!ctx) return\n\n    const animate = (currentTime: number) => {\n      if (recording && currentTime - lastUpdateRef.current > updateRate) {\n        lastUpdateRef.current = currentTime\n\n        if (analyserRef.current) {\n          const dataArray = new Uint8Array(\n            analyserRef.current.frequencyBinCount\n          )\n          analyserRef.current.getByteFrequencyData(dataArray)\n\n          let sum = 0\n          for (let i = 0; i < dataArray.length; i++) {\n            sum += dataArray[i]\n          }\n          const average = (sum / dataArray.length / 255) * sensitivity\n\n          recordingDataRef.current.push(Math.min(1, Math.max(0.05, average)))\n        }\n      }\n\n      const rect = canvas.getBoundingClientRect()\n      ctx.clearRect(0, 0, rect.width, rect.height)\n\n      const computedBarColor =\n        barColor ||\n        getComputedStyle(canvas).getPropertyValue(\"--foreground\") ||\n        \"#000\"\n\n      const dataToRender = recording ? recordingDataRef.current : recordedData\n\n      if (dataToRender.length > 0) {\n        const step = barWidth + barGap\n        const barsVisible = Math.floor(rect.width / step)\n        const centerY = rect.height / 2\n\n        let startIndex = 0\n        if (!recording && isRecordingComplete) {\n          const totalBars = dataToRender.length\n          if (totalBars > barsVisible) {\n            startIndex = Math.floor((totalBars - barsVisible) * viewPosition)\n          }\n        } else if (recording) {\n          startIndex = Math.max(0, dataToRender.length - barsVisible)\n        }\n\n        for (\n          let i = 0;\n          i < barsVisible && startIndex + i < dataToRender.length;\n          i++\n        ) {\n          const value = dataToRender[startIndex + i] || 0.1\n          const x = i * step\n          const barHeight = Math.max(baseBarHeight, value * rect.height * 0.7)\n          const y = centerY - barHeight / 2\n\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 0.3 + value * 0.7\n\n          if (barRadius > 0) {\n            ctx.beginPath()\n            ctx.roundRect(x, y, barWidth, barHeight, barRadius)\n            ctx.fill()\n          } else {\n            ctx.fillRect(x, y, barWidth, barHeight)\n          }\n        }\n\n        if (!recording && isRecordingComplete && showHandle) {\n          const indicatorX = rect.width * viewPosition\n\n          ctx.strokeStyle = computedBarColor\n          ctx.globalAlpha = 0.5\n          ctx.lineWidth = 2\n          ctx.beginPath()\n          ctx.moveTo(indicatorX, 0)\n          ctx.lineTo(indicatorX, rect.height)\n          ctx.stroke()\n          ctx.fillStyle = computedBarColor\n          ctx.globalAlpha = 1\n          ctx.beginPath()\n          ctx.arc(indicatorX, centerY, 6, 0, Math.PI * 2)\n          ctx.fill()\n        }\n      }\n\n      ctx.globalAlpha = 1\n\n      animationRef.current = requestAnimationFrame(animate)\n    }\n\n    animationRef.current = requestAnimationFrame(animate)\n\n    return () => {\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n      }\n    }\n  }, [\n    recording,\n    recordedData,\n    viewPosition,\n    isRecordingComplete,\n    sensitivity,\n    updateRate,\n    showHandle,\n    barWidth,\n    baseBarHeight,\n    barGap,\n    barRadius,\n    barColor,\n  ])\n\n  const handleScrub = useCallback(\n    (clientX: number) => {\n      const container = containerRef.current\n      if (!container || recording || !isRecordingComplete) return\n\n      const rect = container.getBoundingClientRect()\n      const x = Math.max(0, Math.min(clientX - rect.left, rect.width))\n      const position = x / rect.width\n\n      setViewPosition(position)\n    },\n    [recording, isRecordingComplete]\n  )\n\n  const handleMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {\n    if (recording || !isRecordingComplete) return\n\n    e.preventDefault()\n    setIsDragging(true)\n    handleScrub(e.clientX)\n  }\n\n  useEffect(() => {\n    if (!isDragging) return\n\n    const handleMouseMove = (e: MouseEvent) => {\n      handleScrub(e.clientX)\n    }\n\n    const handleMouseUp = () => {\n      setIsDragging(false)\n    }\n\n    document.addEventListener(\"mousemove\", handleMouseMove)\n    document.addEventListener(\"mouseup\", handleMouseUp)\n\n    return () => {\n      document.removeEventListener(\"mousemove\", handleMouseMove)\n      document.removeEventListener(\"mouseup\", handleMouseUp)\n    }\n  }, [isDragging, handleScrub])\n\n  return (\n    <div\n      aria-label={\n        isRecordingComplete && !recording\n          ? \"Drag to scrub through recording\"\n          : undefined\n      }\n      aria-valuenow={\n        isRecordingComplete && !recording ? viewPosition * 100 : undefined\n      }\n      aria-valuemin={isRecordingComplete && !recording ? 0 : undefined}\n      aria-valuemax={isRecordingComplete && !recording ? 100 : undefined}\n      className={cn(\n        \"relative flex items-center\",\n        isRecordingComplete && !recording && \"cursor-pointer\",\n        className\n      )}\n      onMouseDown={handleMouseDown}\n      ref={containerRef}\n      role={isRecordingComplete && !recording ? \"slider\" : undefined}\n      style={{ height: heightStyle }}\n      tabIndex={isRecordingComplete && !recording ? 0 : undefined}\n      {...props}\n    >\n      <canvas className=\"block h-full w-full\" ref={canvasRef} />\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/media.ts",
          "target": "@components/voice-agents/elevenlabs/media.ts",
          "type": "registry:component",
          "content": "export async function acquireMediaStream(\n  constraints: MediaStreamConstraints,\n  cancelled: () => boolean\n) {\n  const stream = await navigator.mediaDevices.getUserMedia(constraints)\n  if (!cancelled()) return stream\n  stream.getTracks().forEach((track) => track.stop())\n  return null\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/LICENSE",
          "target": "@components/voice-agents/elevenlabs/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Eleven Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/elevenlabs/SOURCE.json",
          "target": "@components/voice-agents/elevenlabs/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"ElevenLabs UI\",\n  \"repository\": \"https://github.com/elevenlabs/ui\",\n  \"commit\": \"88a5342ee74632a3f66f3cf9a75cbe87f97007f9\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2025 ElevenLabs Inc.\",\n  \"changes\": [\n    \"Mapped shared shadcn controls and project tokens to Agents Kit.\",\n    \"Replaced React Three Fiber and Drei in Orb with the existing Three.js renderer while preserving shaders, props, and uniform behavior.\",\n    \"Replaced ElevenLabs SDK-only public data types with compatible local structural types.\",\n    \"Changed framer-motion imports to the installed motion package.\",\n    \"Added Orb reduced-motion and offscreen pause, capped DPR, cleanup, and render-failure fallback behavior.\",\n    \"Stopped inactive LiveWaveform render loops and reduced nonessential waveform motion.\",\n    \"Prevented disabled demos and cancelled permission requests from retaining microphone streams.\",\n    \"Made AudioScrubber share its requested height with the nested waveform and use a native range input for pointer, touch, and keyboard seeking.\",\n    \"Redraw static waveforms after root theme changes so canvas colors stay readable without reloading.\"\n  ],\n  \"components\": [\n    {\n      \"name\": \"audio-player\",\n      \"path\": \"audio-player.tsx\",\n      \"title\": \"Audio Player\"\n    },\n    {\n      \"name\": \"bar-visualizer\",\n      \"path\": \"bar-visualizer.tsx\",\n      \"title\": \"Bar Visualizer\"\n    },\n    {\n      \"name\": \"conversation-bar\",\n      \"path\": \"conversation-bar.tsx\",\n      \"title\": \"Conversation Bar\"\n    },\n    {\n      \"name\": \"conversation\",\n      \"path\": \"conversation.tsx\",\n      \"title\": \"Conversation\"\n    },\n    {\n      \"name\": \"live-waveform\",\n      \"path\": \"live-waveform.tsx\",\n      \"title\": \"Live Waveform\"\n    },\n    {\n      \"name\": \"matrix\",\n      \"path\": \"matrix.tsx\",\n      \"title\": \"Matrix\"\n    },\n    {\n      \"name\": \"message\",\n      \"path\": \"message.tsx\",\n      \"title\": \"Message\"\n    },\n    {\n      \"name\": \"mic-selector\",\n      \"path\": \"mic-selector.tsx\",\n      \"title\": \"Mic Selector\"\n    },\n    {\n      \"name\": \"orb\",\n      \"path\": \"orb.tsx\",\n      \"title\": \"Orb\"\n    },\n    {\n      \"name\": \"response\",\n      \"path\": \"response.tsx\",\n      \"title\": \"Response\"\n    },\n    {\n      \"name\": \"scrub-bar\",\n      \"path\": \"scrub-bar.tsx\",\n      \"title\": \"Scrub Bar\"\n    },\n    {\n      \"name\": \"shimmering-text\",\n      \"path\": \"shimmering-text.tsx\",\n      \"title\": \"Shimmering Text\"\n    },\n    {\n      \"name\": \"speech-input\",\n      \"path\": \"speech-input.tsx\",\n      \"title\": \"Speech Input\"\n    },\n    {\n      \"name\": \"transcript-viewer\",\n      \"path\": \"transcript-viewer.tsx\",\n      \"title\": \"Transcript Viewer\"\n    },\n    {\n      \"name\": \"voice-button\",\n      \"path\": \"voice-button.tsx\",\n      \"title\": \"Voice Button\"\n    },\n    {\n      \"name\": \"voice-picker\",\n      \"path\": \"voice-picker.tsx\",\n      \"title\": \"Voice Picker\"\n    },\n    {\n      \"name\": \"waveform\",\n      \"path\": \"waveform.tsx\",\n      \"title\": \"Waveform\"\n    }\n  ]\n}\n"
        }
      ],
      "categories": [
        "ElevenLabs"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "orbkit-shdr-11",
      "type": "registry:block",
      "title": "Orbkit Shdr 11",
      "description": "Hydrogen",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/orbkit/shdr-11.tsx",
          "target": "@components/voice-agents/orbkit/shdr-11.tsx",
          "type": "registry:component",
          "content": "/*\n * Deliberately not a `\"use client\"` module. The directive lives on the runtime\n * in `orbkit-core`, which owns the hooks; keeping it off this file lets server\n * components read `shdr11Orb` as real data (its param schema drives the docs\n * tables and the playground controls) instead of an opaque client reference.\n */\nimport { ShaderOrb, type OrbVariant, type ShaderOrbProps } from \"./core\"\n\n/* ----------------------------------------------------------------------------\n   SHDR-11 — the quantum-orbital orb.\n\n   Renders |psi|^2 of a hydrogen-like wave function projected onto the orb's\n   dome, shaded with rainbow chromatic bands over a dark metallic sphere.\n\n   The dome point is rotated around Y (the fake 3D of a flat disc), its spin\n   axis precesses so the pattern never settles into a visible loop, and a\n   drifting fbm field warps the 3D domain so the wave function smears and\n   migrates around the sphere instead of wobbling in place.\n---------------------------------------------------------------------------- */\n\nconst HYDROGEN_FRAG = `\nconst float PI = 3.14159265359;\nvoid main() {\n  vec2 uv = orbUV();\n  float r2d = length(uv);\n  float R = uP_radius + uP_swell * uInput;\n  float mask = smoothstep(0.012, -0.012, r2d - R);\n  float nr = clamp(r2d / max(R, 0.001), 0.0, 1.0);\n  float z = sqrt(max(1.0 - nr * nr, 0.0));\n\n  // uP_speed and uP_flowSpeed arrive pre-integrated as clocks (see\n  // OrbParamDef.integrate), so state transitions stay phase-continuous.\n  // The state volumes reshape the orbital itself: the params set the base,\n  // input/output excitement bends zoom, radial form, probability and chroma,\n  // so each state settles into a different interference pattern.\n  float posScale = uP_posScale * (0.8 + 0.45 * uOutput + 0.2 * uInput);\n  float radialPow = uP_radialPow * (0.7 + 0.8 * uOutput);\n  float radialDecay = uP_radialDecay * (1.25 - 0.5 * uOutput);\n  float probPow = uP_probPow * (1.3 - 0.55 * uOutput);\n  float probGain = uP_probGain * (0.7 + 0.6 * uOutput + 0.5 * uInput);\n  float waveFreq = uP_waveFreq * (0.6 + 1.0 * uOutput);\n  float chromaSpread = uP_chromaSpread * (0.6 + 0.9 * uOutput + 0.5 * uInput);\n\n  // dome point rotated around Y — the fake 3D of the flat disc\n  float animTime = uP_speed; // integrated clock\n  float cosT = cos(animTime * uP_rotSpeed);\n  float sinT = sin(animTime * uP_rotSpeed);\n  vec3 sp = vec3(uv / max(R, 0.001), z) * posScale;\n  vec3 pos = vec3(sp.x * cosT - sp.z * sinT, sp.y, sp.x * sinT + sp.z * cosT);\n\n  // precession: the rotation axis itself drifts, so the pattern never\n  // settles into a repeating spin\n  float tilt = sin(animTime * 0.21 + 1.7) * uP_precess;\n  float cx = cos(tilt), sx = sin(tilt);\n  pos = vec3(pos.x, pos.y * cx - pos.z * sx, pos.y * sx + pos.z * cx);\n\n  // liquid flow: drifting fbm warps the 3D domain, so the wave function\n  // smears and migrates around the sphere instead of wobbling in place.\n  // (sampled on pos components — continuous everywhere, no phi seam)\n  float flowT = uP_flowSpeed; // integrated clock\n  float fAmp = uP_flowAmp * (0.7 + 0.6 * uOutput + 0.4 * uInput);\n  vec3 w;\n  w.x = fbm(pos.yz * uP_flowScale + vec2(flowT * 0.70, -flowT * 0.40));\n  w.y = fbm(pos.zx * uP_flowScale + vec2(-flowT * 0.55, flowT * 0.62) + 3.7);\n  w.z = fbm(pos.xy * uP_flowScale + vec2(flowT * 0.50, flowT * 0.85) + 7.1);\n  pos += (w - 0.5) * fAmp;\n\n  float r = length(pos) + 0.001;\n  float theta = acos(clamp(pos.y / r, -1.0, 1.0));\n  float phi = atan(pos.z, pos.x);\n\n  float a0 = 0.5;\n  float rho = 2.0 * r / (5.0 * a0);\n  float radial = pow(rho, radialPow) * exp(-rho / radialDecay);\n  float angular = pow(sin(theta), 3.0) * cos(phi + animTime * 0.2); // single lobe\n\n  float psi = radial * angular;\n  float probability = psi * psi;\n\n  // travelling spiral wave — the modulation moves across the surface instead\n  // of pulsing in place. The azimuthal harmonic count must be a whole number,\n  // else sin(phi * f) doesn't line up across the +/-PI wrap and leaves a\n  // vertical meridian seam. Snap it to the nearest integer.\n  float waveN = max(1.0, floor(waveFreq + 0.5));\n  float wavePhase = phi * waveN + theta * 2.5 - animTime * 2.0;\n  probability *= (0.85 + 0.15 * sin(wavePhase));\n\n  // drifting bright patches, like convection cells wandering the surface\n  float patches = fbm(pos.xy * 1.6 + vec2(flowT * 0.4, -flowT * 0.3));\n  probability *= 0.65 + 0.7 * patches;\n\n  probability = pow(probability, probPow) * probGain;\n  probability = clamp(probability, 0.0, 1.0);\n\n  float fresnel = pow(1.0 - z, 1.5);\n\n  // rainbow chromatic aberration\n  float chromaOffset = phi * 2.0 + theta * 1.5 + animTime * 0.3 + probability * 3.0;\n  vec3 rainbow;\n  rainbow.r = sin(chromaOffset) * 0.5 + 0.5;\n  rainbow.g = sin(chromaOffset + chromaSpread) * 0.5 + 0.5;\n  rainbow.b = sin(chromaOffset + chromaSpread * 2.0) * 0.5 + 0.5;\n  rainbow = normalize(rainbow + 0.01) * length(rainbow);\n\n  float bandFreq = chromaOffset * 3.0 + fresnel * 2.4;\n  vec3 chromaticBands;\n  chromaticBands.r = sin(bandFreq) * 0.5 + 0.5;\n  chromaticBands.g = sin(bandFreq + 2.094) * 0.5 + 0.5;\n  chromaticBands.b = sin(bandFreq + 4.189) * 0.5 + 0.5;\n\n  vec3 glowColor = mix(rainbow, chromaticBands, 0.12);\n  glowColor = pow(glowColor, vec3(0.8));\n\n  vec3 darkMetal = vec3(uP_metalDark);\n  vec3 lightMetal = mix(vec3(0.9, 0.92, 0.95), glowColor, 0.7);\n\n  float metalGradient = smoothstep(0.0, 1.0, probability * 0.7 + fresnel * 0.3);\n  vec3 metalColor = mix(darkMetal, lightMetal, metalGradient);\n\n  float orbGlow = uP_glow + 0.6 * uOutput;\n  float totalGlow = (0.25 + fresnel * 0.6 + probability * 0.8) * orbGlow;\n  float glowAmount = clamp(pow(totalGlow, 0.7), 0.0, 1.0);\n\n  vec3 surfaceColor = mix(metalColor, glowColor, glowAmount);\n\n  vec3 normal = vec3(uv / max(R, 0.001), z);\n  float specular = pow(max(dot(normal, normalize(vec3(1.0, 1.0, 2.0))), 0.0), 32.0);\n  surfaceColor += mix(vec3(1.0), glowColor, 0.6) * specular * 0.4;\n\n  float visibility = clamp(probability * 1.2 + fresnel * 0.3 + uP_baseVis + uInput * 0.15, 0.0, 1.0);\n\n  float a = mask * visibility;\n  gl_FragColor = vec4(surfaceColor * a, a);\n}\n`\n\nexport const shdr11Orb: OrbVariant = {\n  key: \"shdr-11\",\n  label: \"SHDR-11\",\n  note: \"quantum orbital, rainbow chroma\",\n  frag: HYDROGEN_FRAG,\n  params: [\n    {\n      key: \"speed\",\n      label: \"Anim speed\",\n      min: 0.015,\n      max: 10,\n      step: 0.05,\n      default: 0.9,\n      integrate: true,\n    },\n    {\n      key: \"rotSpeed\",\n      label: \"Rotation speed\",\n      min: 0,\n      max: 5,\n      step: 0.05,\n      default: 0.5,\n    },\n    {\n      key: \"radius\",\n      label: \"Radius\",\n      min: 0.15,\n      max: 3,\n      step: 0.015,\n      default: 0.9,\n    },\n    {\n      key: \"swell\",\n      label: \"Input swell\",\n      min: 0,\n      max: 1,\n      step: 0.01,\n      default: 0.07,\n    },\n    {\n      key: \"posScale\",\n      label: \"Orbital zoom\",\n      min: 0.15,\n      max: 10,\n      step: 0.05,\n      default: 0.5,\n    },\n    {\n      key: \"flowSpeed\",\n      label: \"Flow speed\",\n      min: 0,\n      max: 10,\n      step: 0.05,\n      default: 0.35,\n      integrate: true,\n    },\n    {\n      key: \"flowAmp\",\n      label: \"Flow amount\",\n      min: 0,\n      max: 4,\n      step: 0.05,\n      default: 0.45,\n    },\n    {\n      key: \"flowScale\",\n      label: \"Flow scale\",\n      min: 0.3,\n      max: 10,\n      step: 0.1,\n      default: 0.3,\n    },\n    {\n      key: \"precess\",\n      label: \"Precession\",\n      min: 0,\n      max: 4,\n      step: 0.05,\n      default: 0.3,\n    },\n    {\n      key: \"radialPow\",\n      label: \"Radial power\",\n      min: 0.5,\n      max: 15,\n      step: 0.1,\n      default: 0.5,\n    },\n    {\n      key: \"radialDecay\",\n      label: \"Radial decay\",\n      min: 0.3,\n      max: 30,\n      step: 0.15,\n      default: 1,\n    },\n    {\n      key: \"probPow\",\n      label: \"Probability curve\",\n      min: 0.1,\n      max: 3,\n      step: 0.015,\n      default: 0.4,\n    },\n    {\n      key: \"probGain\",\n      label: \"Probability gain\",\n      min: 0.15,\n      max: 15,\n      step: 0.1,\n      default: 3,\n    },\n    {\n      key: \"waveFreq\",\n      label: \"Wave frequency\",\n      min: 0,\n      max: 20,\n      step: 0.5,\n      default: 4,\n    },\n    {\n      key: \"chromaSpread\",\n      label: \"Chroma spread\",\n      min: 0,\n      max: 1.5,\n      step: 0.01,\n      default: 0.18,\n    },\n    { key: \"glow\", label: \"Glow\", min: 0, max: 5, step: 0.05, default: 0.9 },\n    {\n      key: \"metalDark\",\n      label: \"Metal darkness\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0,\n    },\n    {\n      key: \"baseVis\",\n      label: \"Base visibility\",\n      min: 0,\n      max: 1.5,\n      step: 0.01,\n      default: 0.12,\n    },\n  ],\n  colors: [],\n  statePresets: {\n    // idle look, tuned by hand — the schema defaults mirror this set\n    idle: {\n      speed: 0.9,\n      rotSpeed: 0.5,\n      radius: 0.9,\n      swell: 0.07,\n      posScale: 0.5,\n      flowSpeed: 0.35,\n      flowAmp: 0.45,\n      flowScale: 0.3,\n      precess: 0.3,\n      radialPow: 0.5,\n      radialDecay: 1,\n      probPow: 0.4,\n      probGain: 3,\n      waveFreq: 4,\n      chromaSpread: 0.18,\n      glow: 0.9,\n      metalDark: 0,\n      baseVis: 0.12,\n    },\n    // thinking: wider zoom, heavier flow, tighter shells, wide chroma —\n    // restless but not loud\n    thinking: {\n      speed: 0.9,\n      rotSpeed: 0.5,\n      radius: 0.9,\n      swell: 0.07,\n      posScale: 0.65,\n      flowSpeed: 0.35,\n      flowAmp: 1.1,\n      flowScale: 0.3,\n      precess: 0,\n      radialPow: 0.5,\n      radialDecay: 1.9,\n      probPow: 0.4,\n      probGain: 3,\n      waveFreq: 4,\n      chromaSpread: 0.41,\n      glow: 0.9,\n      metalDark: 0,\n      baseVis: 0.12,\n    },\n    // speaking: fast anim, full zoom, quick fine-grained flow, strong\n    // precession, bright gain — the loudest, most energetic pattern\n    speaking: {\n      speed: 2.45,\n      rotSpeed: 0.5,\n      radius: 0.9,\n      swell: 0.07,\n      posScale: 1,\n      flowSpeed: 2.75,\n      flowAmp: 0.8,\n      flowScale: 2.2,\n      precess: 1.3,\n      radialPow: 0.5,\n      radialDecay: 1,\n      probPow: 0.31,\n      probGain: 4.3,\n      waveFreq: 4,\n      chromaSpread: 0.12,\n      glow: 0.9,\n      metalDark: 0,\n      baseVis: 0.12,\n    },\n  },\n}\n\nexport type Shdr11Props = Omit<ShaderOrbProps, \"variant\">\n\nexport function Shdr11({ size = 280, ...rest }: Shdr11Props) {\n  return <ShaderOrb variant={shdr11Orb} size={size} {...rest} />\n}\n\nexport default Shdr11\n"
        },
        {
          "path": "components/voice-agents/orbkit/core.tsx",
          "target": "@components/voice-agents/orbkit/core.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport React, {\n  useEffect,\n  useRef,\n  useState,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/* ----------------------------------------------------------------------------\n   Orbkit core — raw WebGL shader orb runtime. No dependencies.\n\n   An orb is a full-screen triangle rendered into a transparent canvas by a\n   fragment shader. Every orb declares a parameter schema (sliders + colors);\n   the values are uploaded as uniforms each frame from a ref, so a controls\n   panel can tune them live without ever remounting the canvas (a remount would\n   drop the WebGL context).\n\n   Animation model: every state synthesizes two volume signals — input (user\n   speech energy) and output (agent speech energy) — smooths them, and the\n   shaders react to those. The flow clock's speed itself follows the output\n   volume, so orbs visibly quicken when the agent is talking.\n---------------------------------------------------------------------------- */\n\nexport type OrbState = \"idle\" | \"thinking\" | \"speaking\"\n\nexport const ORB_STATES = [\"idle\", \"thinking\", \"speaking\"] as const\n\nfunction clamp01(n: number) {\n  return Math.min(1, Math.max(0, n))\n}\n\n/** Per-state [input, output] volume synthesis. */\n/**\n * Transition rate shared by params, colours and the flow-speed multiplier.\n * They must move together: if the rate multiplier eases faster than the look,\n * a state change spins the orb up before it has finished cross-fading, which\n * reads as a lurch.\n *\n * This drives a critically damped spring rather than the exponential ease it\n * used to. An exponential's velocity is highest at the instant the target\n * changes, so every state change began with a jolt — and for params that are\n * spatial frequencies (Corona's warpFreq travels 5.25 -> 19.5 between states)\n * that jolt sweeps the field through its intermediate frequencies at maximum\n * rate, which is what read as the transition \"scrambling\".\n *\n * A spring starts at rest and accelerates, so the sweep is spread across the\n * transition instead of front-loaded. Measured on that warpFreq move it is a\n * 20% lower peak rate of change (20.3/s vs 25.3/s) AND it arrives sooner —\n * 1.50s to within 2% against the exponential's 2.18s, since an exponential\n * only ever asymptotes toward its target.\n */\nconst PARAM_EASE = 4\n\n/*\n  One step of a critically damped spring, implicit (semi-implicit Euler would\n  blow up at the frame times a backgrounded tab produces). Returns nothing and\n  writes through the scratch pair so the hot loop allocates nothing.\n*/\nconst springOut = { x: 0, v: 0 }\nfunction springStep(\n  x: number,\n  v: number,\n  target: number,\n  dt: number,\n  omega: number\n) {\n  const f = 1 + 2 * dt * omega\n  const oo = omega * omega\n  const hoo = dt * oo\n  const hhoo = dt * hoo\n  const detInv = 1 / (f + hhoo)\n  springOut.x = (f * x + dt * v + hhoo * target) * detInv\n  springOut.v = (v + hoo * (target - x)) * detInv\n}\n\nfunction targetVolumes(state: OrbState, t: number): [number, number] {\n  switch (state) {\n    case \"idle\":\n      return [0, 0.3]\n    case \"speaking\":\n      return [\n        clamp01(0.65 + Math.sin(t * 4.8) * 0.22),\n        clamp01(0.75 + Math.sin(t * 3.6) * 0.22),\n      ]\n    case \"thinking\": {\n      const base = 0.38 + 0.07 * Math.sin(t * 0.7)\n      const wander = 0.05 * Math.sin(t * 2.1) * Math.sin(t * 0.37 + 1.2)\n      return [\n        clamp01(base + wander),\n        clamp01(0.48 + 0.12 * Math.sin(t * 1.05 + 0.6)),\n      ]\n    }\n  }\n}\n\n/* ------------------------------ param schema ------------------------------- */\n\nexport interface OrbParamDef {\n  key: string\n  label: string\n  min: number\n  max: number\n  step: number\n  default: number\n  /**\n   * Rate params. The engine integrates them into a clock\n   * (`clock += dt * value * volumeSpeed`) and uploads the clock instead of the\n   * raw value, so changing the rate never jumps the phase — the motion speeds\n   * up or slows down rather than snapping to a new position.\n   */\n  integrate?: boolean\n}\n\nexport interface OrbColorDef {\n  key: string\n  label: string\n  /** hex, e.g. `#ff8b73` */\n  default: string\n}\n\nexport interface OrbVariant {\n  key: string\n  label: string\n  note: string\n  /** GLSL fragment shader body. Uniform declarations are generated for you. */\n  frag: string\n  params: OrbParamDef[]\n  colors: OrbColorDef[]\n  /**\n   * Per-state parameter targets. The engine glides each param toward the\n   * active state's preset. Params passed explicitly via the `params` prop\n   * always win over the preset.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /**\n   * Per-state colour targets, the colour counterpart of `statePresets`.\n   * Kept a separate map because presets are numeric and colours are hex\n   * strings — a union would lose type safety on both. Colours glide in RGB\n   * on the same easing as params, so a state change cross-fades rather\n   * than cutting. Colours passed explicitly via the `colors` prop always\n   * win, exactly as with params.\n   */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n}\n\nexport type OrbParamValues = Partial<Record<string, number>>\nexport type OrbColorValues = Partial<Record<string, string>>\n\n/** Every param and color at its schema default. */\nexport function defaultValuesFor(variant: OrbVariant): {\n  params: Record<string, number>\n  colors: Record<string, string>\n} {\n  return {\n    params: Object.fromEntries(variant.params.map((p) => [p.key, p.default])),\n    colors: Object.fromEntries(variant.colors.map((c) => [c.key, c.default])),\n  }\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace(\"#\", \"\").trim()\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]\n  const n = parseInt(h, 16)\n  if (h.length !== 6 || Number.isNaN(n)) return [1, 1, 1]\n  return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255]\n}\n\n/* ------------------------------- GLSL shared ------------------------------- */\n\nconst VERT = `\nattribute vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\n/**\n * Prelude prepended to every orb fragment shader: uniforms, value noise, fbm,\n * and the centered aspect-corrected UV helper.\n */\nexport const ORB_GLSL_HELPERS = `\nprecision highp float;\nuniform vec2 uRes;\nuniform float uTime;   // slow ambient clock (half real-time)\nuniform float uAnim;   // flow clock — its speed follows the output volume\nuniform float uInput;  // input volume 0..1: user speech energy\nuniform float uOutput; // output volume 0..1: agent speech energy\n\nfloat hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); }\nfloat noise(vec2 p) {\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);\n  return mix(\n    mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),\n    mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x),\n    f.y\n  );\n}\nfloat fbm(vec2 p) {\n  float v = 0.0;\n  float a = 0.5;\n  for (int i = 0; i < 5; i++) {\n    v += a * noise(p);\n    p = p * 2.03 + vec2(11.7, 7.3);\n    a *= 0.5;\n  }\n  return v;\n}\nvec2 orbUV() { return (2.0 * gl_FragCoord.xy - uRes) / min(uRes.x, uRes.y); }\n\n// GLSL ES 1.0 has no tanh() — it arrived in ES 3.0. Shader-golf listings lean\n// on it as a tone-mapper, so it ships here. Clamped against exp() overflow;\n// accurate for the non-negative accumulators those shaders produce.\nvec3 tanh3(vec3 x) {\n  x = clamp(x, -10.0, 10.0);\n  vec3 e = exp(2.0 * x);\n  return (e - 1.0) / (e + 1.0);\n}\n\n`\n\nfunction paramUniformDecls(variant: OrbVariant): string {\n  return [\n    ...variant.params.map((p) => `uniform float uP_${p.key};`),\n    ...variant.colors.map((c) => `uniform vec3 uC_${c.key};`),\n  ].join(\"\\n\")\n}\n\n/* ------------------------------- engine ------------------------------------ */\n\n/**\n * Per-canvas context-lifecycle controller. Created on first mount of a canvas\n * and kept for the element's whole life — the router can hide a page and show\n * the same DOM again, and React re-runs effects on the same canvas, so the\n * lost/restored listeners must outlive any single effect run: an uncanceled\n * webglcontextlost event marks the context permanently unrestorable.\n */\ninterface CanvasContextController {\n  /** Whether a mounted orb currently wants this context alive. */\n  desired: boolean\n  /** Builds a render generation; returns its teardown. Rebound per effect run. */\n  start: (() => () => void) | null\n  /** Teardown of the live generation, if one is running. */\n  stopGen: (() => void) | null\n}\n\nconst canvasControllers = new WeakMap<\n  HTMLCanvasElement,\n  CanvasContextController\n>()\n\nfunction compile(\n  gl: WebGLRenderingContext,\n  type: number,\n  src: string\n): WebGLShader | null {\n  const shader = gl.createShader(type)\n  if (!shader) return null\n  gl.shaderSource(shader, src)\n  gl.compileShader(shader)\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    console.error(\"[orbkit] shader compile error:\", gl.getShaderInfoLog(shader))\n    gl.deleteShader(shader)\n    return null\n  }\n  return shader\n}\n\n/* ----------------------------------------------------------------------------\n   Wrappers — optional decoration drawn around, under and over the orb.\n\n   A wrapper is pure CSS/SVG, never a shader: the orb keeps its own canvas and\n   the decoration is composited on top of it by the browser. That keeps the\n   whole set free for any orb (no per-variant shader work), costs nothing on\n   the GPU budget the shaders are already spending, and means swapping one\n   wrapper for another at runtime never touches the WebGL context. Turning a\n   wrapper on or off does, since that is what moves the canvas into or out of\n   the wrapper element — see the effect's `wrapped` dependency.\n\n   Layout: a wrapped orb becomes a square box, and the canvas is absolutely\n   positioned inside it with the spec's `inset`. The FOOTPRINT is unchanged —\n   `size` is still the outer diameter — so dropping a wrapper onto an existing\n   orb reflows nothing; the orb itself just shrinks to leave the ring room.\n\n   Colour: every layer that isn't physically light or shadow paints in\n   `currentColor`, so a wrapper picks up the surrounding text colour and reads\n   correctly on light and dark pages with no configuration. `wrapperColor`\n   sets that colour when you want something other than the inherited one.\n---------------------------------------------------------------------------- */\n\nexport const ORB_WRAPPERS = [\n  \"none\",\n  \"glass\",\n  \"ring\",\n  \"dotted\",\n  \"ticks\",\n  \"reticle\",\n  \"grid\",\n  \"halftone\",\n  \"scanlines\",\n] as const\n\nexport type OrbWrapper = (typeof ORB_WRAPPERS)[number]\n\n/*\n  Keyframes for the animated wrappers, shipped inside the component so an orb\n  stays a single self-contained file with nothing to add to a global\n  stylesheet. React 19 hoists a <style href precedence> into <head> and\n  de-duplicates it, so a page full of wrapped orbs emits this exactly once;\n  older React renders it inline, which is redundant but harmless.\n\n  Reduced motion parks all of it. The shader runtime already honours the same\n  preference for the orb itself (see the reduce-motion branch in the render\n  loop), and a ring that keeps spinning around a frozen orb would be the worse\n  half of the two still moving.\n*/\nconst WRAPPER_STYLE_HREF = \"orbkit-wrapper\"\nconst WRAPPER_CSS = `\n@keyframes orbkit-w-spin { to { transform: rotate(360deg); } }\n@keyframes orbkit-w-roll { from { transform: translateY(-110%); } to { transform: translateY(360%); } }\n@media (prefers-reduced-motion: reduce) {\n  .orbkit-w-anim { animation: none !important; }\n}\n`\n\ninterface WrapperSpec {\n  /**\n   * How far the canvas sits inside the box, in percent, leaving the\n   * decoration room. Applied as explicit width/height rather than as `inset`:\n   * a canvas is a REPLACED element, so an absolutely positioned one with\n   * `left` and `right` both set does not stretch between them — it keeps its\n   * intrinsic size and the over-constrained edge is dropped. The orb would\n   * then be drawn into a canvas the size of the page.\n   */\n  inset: number\n  /**\n   * Soft circular mask on the canvas. Only the wrappers that read as a\n   * CONTAINER set one — a bubble has to hold the orb, whereas a bezel sits\n   * beside it and clipping the halo there would just amputate the glow.\n   */\n  mask?: string\n  /** Cast by the assembly as a whole, on the outer box. */\n  shadow?: string\n\n  /** True when the spec uses one of the keyframes above. */\n  animated?: boolean\n  /** Painted beneath the canvas. */\n  under?: ReactNode\n  /** Painted over it. */\n  over?: ReactNode\n}\n\nconst DISC: CSSProperties = { borderRadius: \"50%\" }\n\n/** One absolutely-positioned decoration layer, filling the wrapper box. */\nfunction Layer({\n  inset = 0,\n  style,\n  className,\n}: {\n  inset?: number | string\n  style: CSSProperties\n  className?: string\n}) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={className}\n      style={{ position: \"absolute\", inset, pointerEvents: \"none\", ...style }}\n    />\n  )\n}\n\n/**\n * A free-floating highlight — glass's specular and its bounce. These do not go\n * through `Layer` because they are placed with `left`/`top`/`width`, and a\n * style object that sets those on top of `Layer`'s `inset` shorthand is mixing\n * shorthand and longhand for the same property: React warns about it, and the\n * result depends on key order rather than on anything you would want to rely\n * on.\n */\nfunction Highlight({ style }: { style: CSSProperties }) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      style={{\n        position: \"absolute\",\n        borderRadius: \"50%\",\n        pointerEvents: \"none\",\n        ...style,\n      }}\n    />\n  )\n}\n\n/**\n * The mask that makes a wrapper HOLD the orb: cuts the canvas back to the\n * bubble and stops a hairline short of the rim, so the orb never quite touches\n * the glass.\n *\n * The percentage has to be derived rather than written down. `closest-side`\n * measures the CANVAS, and a wrapper with a negative inset draws its canvas\n * LARGER than the bubble — at -7 the canvas is 114% of the box, so the rim\n * sits at 100/1.14 = 87.7% of the canvas's own radius, not at 100%.\n *\n * The gap is real pixels rather than a share of the size: it reads as the same\n * band at 120px and at 900px, which a percentage would not.\n */\nconst RIM_GAP_PX = 4\n\nfunction rimMask(inset: number): string {\n  const rim = (100 / (1 - (2 * inset) / 100)).toFixed(2)\n  // Feathered over the final pixel, so the cut is not a razor edge.\n  const solid = RIM_GAP_PX + 0.5\n  const clear = RIM_GAP_PX - 0.5\n  return `radial-gradient(circle closest-side, #000 calc(${rim}% - ${solid}px), rgba(0,0,0,0) calc(${rim}% - ${clear}px))`\n}\n\n/** Both spellings, since Safari still wants the prefix for mask-image. */\nfunction masked(image: string): CSSProperties {\n  return { WebkitMaskImage: image, maskImage: image }\n}\n\nconst svgLayer: CSSProperties = {\n  position: \"absolute\",\n  inset: 0,\n  width: \"100%\",\n  height: \"100%\",\n  pointerEvents: \"none\",\n  overflow: \"visible\",\n}\n\n/** Glass's overfill, shared by its inset and the mask derived from it. */\nconst GLASS_INSET = -4\n\nconst WRAPPER_SPECS: Record<Exclude<OrbWrapper, \"none\">, WrapperSpec> = {\n  /*\n    glass — a blown bubble with the orb suspended inside it.\n\n    Five layers in the order light actually arrives: the body brightening\n    toward the key light, the Fresnel ring where a sphere's edge turns almost\n    edge-on and reflects nearly everything, the rim itself, the window\n    reflection, and the bounce coming back up off whatever the bubble is\n    sitting on. All of it is white and black rather than `currentColor` —\n    glass has no colour of its own, only the light it moves around.\n  */\n  glass: {\n    /*\n      Negative on purpose. An orb's shader does not necessarily paint to the\n      edge of its canvas — most draw a sphere with transparent margin around\n      it — so a canvas sized to the bubble leaves a dead ring between the orb\n      and the rim, which is not what a thing suspended in glass looks like.\n      Oversizing the canvas by 14% pushes the sphere out to the rim, and\n      `rimMask` cuts whatever overflows — a few pixels short of the glass, so\n      the orb sits just inside it rather than welded to it. Orbs that already fill\n      their canvas lose a few percent off the limb, which is the same crop the\n      reference bubble makes.\n    */\n    inset: GLASS_INSET,\n    mask: rimMask(GLASS_INSET),\n    shadow: \"0 24px 48px -26px rgba(0,0,0,0.55)\",\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(ellipse 80% 70% at 28% 20%, rgba(255,255,255,0.16), rgba(255,255,255,0.03) 45%, rgba(255,255,255,0) 72%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(255,255,255,0) 0%, rgba(255,255,255,0.0) 55%, rgba(255,255,255,0.05) 99.5%, rgba(255,255,255,0) 100%)\",\n            overflow: \"hidden\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow: \"3px 6px 10px #ffffff20 inset\",\n          }}\n        />\n        {/*\n          The shell's own darkening, just inside the rim. Invisible on a dark\n          page — it is black over black — and doing all the work on a light\n          one, where the white highlights below have nothing to stand out\n          against and the bubble would otherwise read as a bare drop shadow.\n        */}\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(0,0,0,0) 78%, rgba(0,0,0,0.05) 93%, rgba(0,0,0,0.02) 100%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow:\n              \"inset 0 6px 12px -7px rgba(255,255,255,0.05), inset 0 -9px 16px -9px rgba(255,255,255,0.1), 0 0 0 1px rgba(0,0,0,0.07)\",\n          }}\n        />\n        <Highlight\n          style={{\n            left: \"15%\",\n            top: \"10%\",\n            width: \"38%\",\n            height: \"22%\",\n            transform: \"rotate(-25deg)\",\n            background:\n              \"radial-gradient(closest-side, rgba(255,255,255,0.9), rgba(255,255,255,0.3) 55%, rgba(255,255,255,0) 100%)\",\n            filter: \"blur(10px)\",\n          }}\n        />\n      </>\n    ),\n  },\n\n  /* ring — two hairlines and nothing else. The restrained one. */\n  ring: {\n    inset: 9,\n    over: (\n      <>\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.22 }}\n        />\n        <Layer\n          inset=\"5%\"\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.1 }}\n        />\n      </>\n    ),\n  },\n\n  /*\n    dotted — evenly spaced dots around the circumference, turning slowly.\n\n    Drawn as one dashed circle with round caps and a near-zero dash length, so\n    each dash collapses to a dot. `pathLength=\"64\"` renormalizes the path to 64\n    units first, which is what makes the count exact: the dash period is\n    literally 1/64th of the circle, so the pattern closes on itself with no\n    seam where the last gap would otherwise be short.\n  */\n  dotted: {\n    inset: 10,\n    animated: true,\n    over: (\n      <svg\n        aria-hidden=\"true\"\n        viewBox=\"0 0 100 100\"\n        className=\"orbkit-w-anim\"\n        style={{ ...svgLayer, animation: \"orbkit-w-spin 48s linear infinite\" }}\n      >\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"47\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.7\"\n          strokeLinecap=\"round\"\n          pathLength={64}\n          strokeDasharray=\"0.0001 0.9999\"\n          opacity={0.45}\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    ticks — an instrument bezel: a fine minor scale every 6 degrees with a\n    longer major tick every 30. Both are one repeating conic gradient masked\n    down to an annulus, so the tick count is set by the gradient's period and\n    the tick LENGTH by how far in the mask reaches.\n  */\n  ticks: {\n    inset: 12,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.32,\n            background:\n              \"repeating-conic-gradient(from -0.5deg, transparent 0deg 0.2deg, currentColor 0.4deg 0.6deg, transparent 0.8deg 6deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 88%, #000 90%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.6,\n            background:\n              \"repeating-conic-gradient(from -0.75deg, transparent 0deg 0.25deg, currentColor 0.5deg 1deg, transparent 1.25deg 30deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 80%, #000 82%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.12 }}\n        />\n      </>\n    ),\n  },\n\n  /* reticle — viewfinder furniture: corner brackets, cardinal ticks, a track. */\n  reticle: {\n    inset: 13,\n    over: (\n      <svg aria-hidden=\"true\" viewBox=\"0 0 100 100\" style={svgLayer}>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" opacity=\"0.5\">\n          <path d=\"M1 13 L1 1 L13 1\" />\n          <path d=\"M87 1 L99 1 L99 13\" />\n          <path d=\"M99 87 L99 99 L87 99\" />\n          <path d=\"M13 99 L1 99 L1 87\" />\n        </g>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.38\">\n          <path d=\"M50 1 L50 9\" />\n          <path d=\"M50 91 L50 99\" />\n          <path d=\"M1 50 L9 50\" />\n          <path d=\"M91 50 L99 50\" />\n        </g>\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"46\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"0.7\"\n          opacity=\"0.22\"\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    grid — a graticule laid over the orb and masked back to the disc, so the\n    mesh appears to be etched on the glass in front of it rather than drawn on\n    the page behind. The lines are 1px whatever the size; the SPACING is a\n    percentage, so the cell count holds from a gallery thumbnail to a\n    full-bleed hero.\n  */\n  grid: {\n    inset: 8,\n    /*\n      The ruling sits UNDER the canvas: graph paper the orb rests on, not a\n      mesh laid over its face. Drawn on top it crosshatched the shader — the\n      one thing the wrapper is meant to frame. The ring stays over, since it\n      only ever meets the transparent margin at the canvas edge.\n    */\n    under: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.18,\n          backgroundImage:\n            \"repeating-linear-gradient(to right, currentColor 0 1px, transparent 1px 12.5%), repeating-linear-gradient(to bottom, currentColor 0 1px, transparent 1px 12.5%)\",\n          ...masked(\n            \"radial-gradient(circle closest-side, #000 86%, rgba(0,0,0,0) 99%)\"\n          ),\n        }}\n      />\n    ),\n    over: (\n      <Layer\n        style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.2 }}\n      />\n    ),\n  },\n\n  /*\n    halftone — a print screen over the outer band of the orb. The mask keeps\n    the middle clear, so the dots read as the image breaking up toward its\n    edge instead of a texture pasted across the whole face.\n  */\n  halftone: {\n    inset: 6,\n    over: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.5,\n          backgroundImage: \"radial-gradient(currentColor 22%, transparent 24%)\",\n          backgroundSize: \"7px 7px\",\n          ...masked(\n            \"radial-gradient(circle closest-side, transparent 40%, #000 80%, #000 94%, rgba(0,0,0,0) 100%)\"\n          ),\n        }}\n      />\n    ),\n  },\n\n  /*\n    scanlines — a phosphor tube. Black lines rather than `currentColor`,\n    because scanlines are the UNLIT gaps between rows and stay dark whatever\n    the page is; the slow bright band rolling down is the vertical hold\n    drifting, which is the part that reads as a CRT rather than as stripes.\n  */\n  scanlines: {\n    inset: 0,\n    animated: true,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            backgroundImage:\n              \"repeating-linear-gradient(to bottom, rgba(0,0,0,0.45) 0 1px, rgba(0,0,0,0) 1px 3px)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, #000 84%, rgba(0,0,0,0) 100%)\"\n            ),\n          }}\n        />\n        <span\n          aria-hidden=\"true\"\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            borderRadius: \"50%\",\n            overflow: \"hidden\",\n            pointerEvents: \"none\",\n          }}\n        >\n          <span\n            className=\"orbkit-w-anim\"\n            style={{\n              position: \"absolute\",\n              left: 0,\n              right: 0,\n              top: 0,\n              height: \"30%\",\n              background:\n                \"linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,0.07) 50%, rgba(255,255,255,0) 100%)\",\n              animation: \"orbkit-w-roll 7s linear infinite\",\n            }}\n          />\n        </span>\n        <Layer\n          style={{ ...DISC, boxShadow: \"inset 0 0 40px -8px rgba(0,0,0,0.5)\" }}\n        />\n      </>\n    ),\n  },\n}\n\nexport interface ShaderOrbProps {\n  /** The orb definition: shader + param schema + state presets. */\n  variant: OrbVariant\n  /** Drives the synthesized volume signals. Defaults to `\"idle\"`. */\n  state?: OrbState\n  /** Rendered size in CSS pixels. Ignored when `className` sizes the canvas. */\n  size?: number\n  /** Explicit param overrides. Any key present here wins over the state preset. */\n  params?: OrbParamValues\n  /** Explicit color overrides, as hex strings. */\n  colors?: OrbColorValues\n  /**\n   * Per-state parameter targets, overriding the variant's own. Merged KEY BY\n   * KEY over what the orb already defines, so `{ thinking: { churn: 1.62 } }`\n   * retouches one param of one state and leaves every other param — and the\n   * other two states — exactly as the orb ships them.\n   *\n   * This is the prop form of the variant's `statePresets`, so you can retune\n   * an orb's states from the outside without forking its file. Values still\n   * glide, so switching states cross-fades into your targets. An explicit\n   * `params` value outranks this, the same way it outranks the variant.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /** The colour counterpart of `statePresets`, merged the same key-by-key way. */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n  /**\n   * Per-state volume drive, the third member of the same family. Use it to\n   * give each state its own energy; use `volumes` below instead when you have\n   * a real signal to feed in, such as live mic level.\n   */\n  stateVolumes?: Partial<Record<OrbState, { input?: number; output?: number }>>\n  /**\n   * Overrides the synthesized volume signals for the active state. The engine\n   * normally derives these from `state` — a slow breath at idle, a restless\n   * wander while thinking, speech-shaped peaks while speaking — and most\n   * shaders read them as their reactivity. Setting either channel here pins\n   * it instead, which is how the playground lets you dial each state's drive\n   * independently. Omit a channel to keep its synthesized motion.\n   */\n  volumes?: { input?: number; output?: number }\n  /** Freeze the animation on the current frame. */\n  paused?: boolean\n  /**\n   * Stop rendering while the orb is scrolled out of view. Defaults to `true` —\n   * a page full of orbs would otherwise run a WebGL loop per card.\n   */\n  pauseOffscreen?: boolean\n  /** Device-pixel-ratio ceiling. Defaults to `2`. */\n  maxDpr?: number\n  /**\n   * Decoration drawn around the orb — a glass bubble, a dotted bezel, a\n   * viewfinder. Defaults to `\"none\"`, which renders the bare canvas exactly as\n   * it always has, with no extra element in the tree.\n   *\n   * A wrapper never changes the orb's footprint: `size` stays the outer\n   * diameter and the canvas is inset inside it, so switching one on reflows\n   * nothing around it.\n   */\n  wrapper?: OrbWrapper\n  /**\n   * The colour a wrapper draws its lines and dots in. Defaults to\n   * `currentColor` — the inherited text colour — which is what makes the\n   * bezels legible on a light and a dark page without being told which one\n   * they are on. `glass` ignores it: glass has no colour of its own.\n   */\n  wrapperColor?: string\n  /** Applied to the outermost element — the wrapper when there is one. */\n  className?: string\n  /** Merged onto the outermost element's style. */\n  style?: CSSProperties\n  /** Accessible label. When omitted the orb is hidden from assistive tech. */\n  ariaLabel?: string\n}\n\nexport function ShaderOrb({\n  variant,\n  state = \"idle\",\n  size,\n  params,\n  colors,\n  statePresets,\n  stateColors,\n  stateVolumes,\n  volumes,\n  paused = false,\n  pauseOffscreen = true,\n  maxDpr = 2,\n  wrapper = \"none\",\n  wrapperColor,\n  className,\n  style,\n  ariaLabel,\n}: ShaderOrbProps) {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const spec = wrapper === \"none\" ? undefined : WRAPPER_SPECS[wrapper]\n  const wrapped = spec !== undefined\n\n  // Live refs: the render loop reads these every frame, so changing a param\n  // never re-runs the GL setup effect (which would drop the context). Synced in\n  // an effect rather than during render — a ref write during render is unsafe\n  // under concurrent rendering, and the loop picks the new value up on the very\n  // next frame anyway.\n  /*\n    Whether the canvas has drawn a frame yet, tracked per variant because a\n    variant swap mounts a brand new canvas (see the `key` below).\n\n    A mounted-but-never-drawn canvas is at the browser's mercy: rather than\n    the transparent rectangle you would expect, a page that mounts a dozen at\n    once gets white boxes — and in some browsers a broken-image placeholder —\n    for as long as the compositor has nothing to raster. That window is not\n    small here: every orb compiles a full fragment shader synchronously in its\n    own mount effect, so on the gallery grid the first canvases sit empty\n    while the last ones are still compiling. Holding each canvas invisible\n    until its own first frame lands is what makes the grid fade in cleanly\n    instead of flashing. One state change per orb, once, on mount.\n  */\n  const [paintedKey, setPaintedKey] = useState<string | null>(null)\n  const painted = paintedKey === variant.key\n\n  const stateRef = useRef<OrbState>(state)\n  const paramsRef = useRef<OrbParamValues | undefined>(params)\n  const colorsRef = useRef<OrbColorValues | undefined>(colors)\n  const statePresetsRef = useRef(statePresets)\n  const stateColorsRef = useRef(stateColors)\n  const stateVolumesRef = useRef(stateVolumes)\n  const volumesRef = useRef(volumes)\n  const pausedRef = useRef(paused)\n\n  useEffect(() => {\n    stateRef.current = state\n    paramsRef.current = params\n    colorsRef.current = colors\n    statePresetsRef.current = statePresets\n    stateColorsRef.current = stateColors\n    stateVolumesRef.current = stateVolumes\n    volumesRef.current = volumes\n    pausedRef.current = paused\n  }, [\n    state,\n    params,\n    colors,\n    statePresets,\n    stateColors,\n    stateVolumes,\n    volumes,\n    paused,\n  ])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    const gl = canvas.getContext(\"webgl\", {\n      alpha: true,\n      // No MSAA: the geometry is a single full-screen triangle, so there are no\n      // primitive edges to antialias — softness comes from the shaders. Leaving\n      // it on costs the multisample buffers plus a resolve every frame.\n      antialias: false,\n      premultipliedAlpha: true,\n    })\n    if (!gl) return\n\n    const loseExt = gl.getExtension(\"WEBGL_lose_context\")\n\n    /*\n      A \"generation\" is everything tied to a live context: program, buffers,\n      observers, render loop. Browsers cap live WebGL contexts per page and\n      evict the oldest past the cap, and an evicted orb's canvas stays blank\n      forever unless the app rebuilds — so generations tear down and rebuild on\n      the lost/restored events instead of assuming the context is immortal.\n    */\n    let announcedPaint = false\n\n    const startGeneration = (): (() => void) => {\n      if (gl.isContextLost()) return () => {}\n      // Every generation announces its own first frame: a context that was\n      // lost and restored has an empty drawing buffer and is hidden again\n      // (below), so it has to earn its reveal back.\n      announcedPaint = false\n\n      const vs = compile(gl, gl.VERTEX_SHADER, VERT)\n      const fs = compile(\n        gl,\n        gl.FRAGMENT_SHADER,\n        ORB_GLSL_HELPERS + paramUniformDecls(variant) + variant.frag\n      )\n      const releaseShaders = () => {\n        if (vs) gl.deleteShader(vs)\n        if (fs) gl.deleteShader(fs)\n      }\n      if (!vs || !fs) return releaseShaders\n\n      const prog = gl.createProgram()\n      if (!prog) return releaseShaders\n      gl.attachShader(prog, vs)\n      gl.attachShader(prog, fs)\n      gl.linkProgram(prog)\n      if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n        console.error(\n          \"[orbkit] program link error:\",\n          gl.getProgramInfoLog(prog)\n        )\n        gl.deleteProgram(prog)\n        return releaseShaders\n      }\n      gl.useProgram(prog)\n\n      const buf = gl.createBuffer()\n      gl.bindBuffer(gl.ARRAY_BUFFER, buf)\n      gl.bufferData(\n        gl.ARRAY_BUFFER,\n        new Float32Array([-1, -1, 3, -1, -1, 3]),\n        gl.STATIC_DRAW\n      )\n      const aPos = gl.getAttribLocation(prog, \"aPos\")\n      gl.enableVertexAttribArray(aPos)\n      gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0)\n\n      gl.enable(gl.BLEND)\n      gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n\n      const uRes = gl.getUniformLocation(prog, \"uRes\")\n      const uTime = gl.getUniformLocation(prog, \"uTime\")\n      const uAnim = gl.getUniformLocation(prog, \"uAnim\")\n      const uInput = gl.getUniformLocation(prog, \"uInput\")\n      const uOutput = gl.getUniformLocation(prog, \"uOutput\")\n\n      const paramLocs = variant.params.map((p) => ({\n        def: p,\n        loc: gl.getUniformLocation(prog, `uP_${p.key}`),\n      }))\n      const colorLocs = variant.colors.map((c) => ({\n        def: c,\n        loc: gl.getUniformLocation(prog, `uC_${c.key}`),\n      }))\n\n      /* --- sizing: track the element box, not a one-shot measurement ------- */\n      // Backing-store scale, stepped down by the adaptive-resolution logic in\n      // the loop when the GPU can't hold frame rate. CSS size never changes —\n      // the browser upscales, which these soft shaders absorb gracefully.\n      let resScale = 1\n      const resize = () => {\n        const dpr = Math.min(window.devicePixelRatio || 1, maxDpr) * resScale\n        const w = Math.max(1, Math.round(canvas.clientWidth * dpr))\n        const h = Math.max(1, Math.round(canvas.clientHeight * dpr))\n        if (canvas.width !== w || canvas.height !== h) {\n          canvas.width = w\n          canvas.height = h\n          gl.viewport(0, 0, w, h)\n        }\n        /*\n          Uploaded UNCONDITIONALLY, outside the size guard. A rebuilt\n          generation (React strict-mode remount, a restored context) links a\n          fresh program whose uRes starts at zero — and the canvas usually\n          already holds the right backing size, so an upload gated behind\n          the resize never ran. With uRes = 0, orbUV() divides by zero and\n          every fragment lands transparent: a healthy context, a bound\n          program, and a permanently blank orb.\n        */\n        gl.uniform2f(uRes, w, h)\n      }\n      resize()\n\n      const resizeObserver =\n        typeof ResizeObserver !== \"undefined\"\n          ? new ResizeObserver(resize)\n          : null\n      resizeObserver?.observe(canvas)\n\n      /* --- visibility: don't burn a render loop on an offscreen orb -------- */\n      let visible = !pauseOffscreen\n      const intersectionObserver =\n        pauseOffscreen && typeof IntersectionObserver !== \"undefined\"\n          ? new IntersectionObserver(\n              (entries) => {\n                visible = Boolean(entries[0]?.isIntersecting)\n                if (visible) {\n                  last = performance.now() / 1000\n                }\n              },\n              { rootMargin: \"150px 0px\", threshold: 0 }\n            )\n          : null\n      if (intersectionObserver) {\n        intersectionObserver.observe(canvas)\n      } else {\n        visible = true\n      }\n\n      const reduceMotion =\n        typeof window.matchMedia === \"function\" &&\n        window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n\n      /* --- driver state ---------------------------------------------------- */\n      let tSec = 0\n      // random phase so two orbs on the same page never look synchronized\n      let anim = Math.random() * 100\n      let speed = 0.1\n      const cur = { in: 0, out: 0.3 }\n      const presets = variant.statePresets\n      const paramCur: Record<string, number> = {}\n      const paramVel: Record<string, number> = {}\n      const paramClocks: Record<string, number> = {}\n      const colorCur: Record<string, [number, number, number]> = {}\n      const colorVel: Record<string, [number, number, number]> = {}\n      let speedVel = 0\n      const [initialIn, initialOut] = targetVolumes(stateRef.current, 0)\n      cur.in = initialIn\n      cur.out = initialOut\n      let last = performance.now() / 1000\n      let raf = 0\n      // smoothed frame time for the adaptive-resolution check\n      let frameEma = 1 / 60\n\n      const uploadAndDraw = (dt: number, snap = false) => {\n        // Synthesized from the state, unless a channel is pinned via\n        // `volumes`. Pinned values still glide on the same easing, so dialing\n        // one in the playground cross-fades rather than jumping.\n        const [tin, tout] = targetVolumes(stateRef.current, tSec)\n        // Same order as params and colours: direct prop, then the per-state\n        // map, then the engine's own synthesis.\n        const liveVolumes = volumesRef.current\n        const stateVolume = stateVolumesRef.current?.[stateRef.current]\n        const targetIn = liveVolumes?.input ?? stateVolume?.input ?? tin\n        const targetOut = liveVolumes?.output ?? stateVolume?.output ?? tout\n        const kVol = 1 - Math.exp(-dt * 12)\n        cur.in += (targetIn - cur.in) * kVol\n        cur.out += (targetOut - cur.out) * kVol\n\n        /*\n          Flow speed follows the output volume. It multiplies every integrated\n          clock's increment, so it is a RATE: easing it quickly makes the orb\n          visibly lurch — a state change would spin the orb up hard before the\n          params had finished gliding.\n\n          It is therefore eased on the same constant as the params below, so a\n          state change ramps its motion over the same half second that its look\n          takes to cross-fade. The steady-state values are unchanged, so a\n          speaking orb still flows faster than an idle one; only the transition\n          into that rate is gradual.\n        */\n        const targetSpeed = 0.1 + (1 - Math.pow(cur.out - 1, 2)) * 0.9\n        if (snap) {\n          speed = targetSpeed\n          speedVel = 0\n        } else {\n          springStep(speed, speedVel, targetSpeed, dt, PARAM_EASE)\n          speed = springOut.x\n          speedVel = springOut.v\n        }\n        anim += dt * speed\n\n        gl.uniform1f(uTime, tSec * 0.5)\n        gl.uniform1f(uAnim, anim)\n        gl.uniform1f(uInput, cur.in)\n        gl.uniform1f(uOutput, cur.out)\n\n        // Resolution order per param: explicit `params` → `statePresets`\n        // prop → the variant's own preset → schema default. The two middle\n        // steps are per-key, so overriding one param of one state leaves the\n        // rest of that state alone. Values glide rather than snap.\n        const liveParams = paramsRef.current\n        const statePreset = presets?.[stateRef.current]\n        const overridePreset = statePresetsRef.current?.[stateRef.current]\n\n        for (const { def, loc } of paramLocs) {\n          const explicit = liveParams?.[def.key]\n          const target =\n            typeof explicit === \"number\"\n              ? explicit\n              : (overridePreset?.[def.key] ??\n                statePreset?.[def.key] ??\n                def.default)\n          const curVal = paramCur[def.key] ?? target\n          let next: number\n          if (snap) {\n            next = target\n            paramVel[def.key] = 0\n          } else {\n            springStep(curVal, paramVel[def.key] ?? 0, target, dt, PARAM_EASE)\n            next = springOut.x\n            paramVel[def.key] = springOut.v\n          }\n          paramCur[def.key] = next\n\n          if (def.integrate) {\n            const clock =\n              (paramClocks[def.key] ??\n                (paramClocks[def.key] = Math.random() * 100)) +\n              dt * speed * next\n            paramClocks[def.key] = clock\n            gl.uniform1f(loc, clock)\n          } else {\n            gl.uniform1f(loc, next)\n          }\n        }\n\n        // Same resolution order and same easing as params, so a state change\n        // cross-fades the palette instead of cutting to it.\n        const liveColors = colorsRef.current\n        const stateColor = variant.stateColors?.[stateRef.current]\n        const overrideColor = stateColorsRef.current?.[stateRef.current]\n        for (const { def, loc } of colorLocs) {\n          const target = hexToRgb(\n            liveColors?.[def.key] ??\n              overrideColor?.[def.key] ??\n              stateColor?.[def.key] ??\n              def.default\n          )\n          const curCol = (colorCur[def.key] ??= [...target] as [\n            number,\n            number,\n            number,\n          ])\n          const velCol = (colorVel[def.key] ??= [0, 0, 0])\n          for (let i = 0; i < 3; i++) {\n            if (snap) {\n              curCol[i] = target[i]\n              velCol[i] = 0\n            } else {\n              springStep(curCol[i], velCol[i], target[i], dt, PARAM_EASE)\n              curCol[i] = springOut.x\n              velCol[i] = springOut.v\n            }\n          }\n          gl.uniform3f(loc, curCol[0], curCol[1], curCol[2])\n        }\n\n        gl.clearColor(0, 0, 0, 0)\n        gl.clear(gl.COLOR_BUFFER_BIT)\n        gl.drawArrays(gl.TRIANGLES, 0, 3)\n        // Deferred a microtask: the first of these draws runs synchronously\n        // inside this effect, and a sync setState there trips the compiler\n        // lint. A microtask still resolves before the browser paints, so the\n        // reveal is not delayed by a frame.\n        if (!announcedPaint) {\n          announcedPaint = true\n          queueMicrotask(() => {\n            /*\n              Re-check: the context can be evicted between this draw and the\n              microtask, and mounting one more orb anywhere on the page is\n              enough to do it — opening the details drawer over a full gallery\n              is exactly that. Revealing on the strength of a frame that has\n              already been thrown away puts a dead canvas on screen, which is\n              what the browser draws its broken-canvas placeholder over. The\n              generation that follows the restore announces again.\n            */\n            if (gl.isContextLost()) return\n            setPaintedKey(variant.key)\n          })\n        }\n      }\n\n      const releaseGL = () => {\n        resizeObserver?.disconnect()\n        intersectionObserver?.disconnect()\n        gl.deleteProgram(prog)\n        gl.deleteShader(vs)\n        gl.deleteShader(fs)\n        gl.deleteBuffer(buf)\n      }\n\n      if (reduceMotion) {\n        // One representative frame, then stop — snapped straight onto the\n        // state's targets, since a spring would only be part-way there.\n        tSec = 1\n        uploadAndDraw(1, true)\n        return releaseGL\n      }\n\n      const loop = () => {\n        raf = requestAnimationFrame(loop)\n        const now = performance.now() / 1000\n        const dt = Math.min(now - last, 0.05)\n        last = now\n        if (!visible || pausedRef.current) return\n        tSec += dt\n\n        /*\n          Adaptive resolution. When the smoothed frame time sits above ~30fps,\n          the GPU is drowning in fragment work (these shaders are pure fill\n          cost), so step the backing store down 20% and re-measure. Steps only\n          go down — never back up — so the resolution can't oscillate. The\n          warm-up guard keeps page-load jank (hydration, first compiles) from\n          triggering a downgrade the GPU never asked for.\n        */\n        /*\n          Only unstalled frames are evidence about GPU fill cost. `dt` above is\n          clamped at 0.05, so a frame that hits the clamp is the main thread\n          having been blocked — a slider drag re-rendering React, a GC pause, a\n          tab regaining focus — and feeding those in made UI jank look\n          identical to a drowning GPU.\n        */\n        if (dt < 0.05) frameEma += (dt - frameEma) * 0.08\n\n        if (tSec > 1.5 && frameEma > 1 / 34 && resScale > 0.5) {\n          resScale = Math.max(0.5, resScale * 0.8)\n          frameEma = 1 / 60 // require fresh evidence before the next step\n          resize()\n        } else if (tSec > 1.5 && frameEma < 1 / 55 && resScale < 1) {\n          /*\n            And step back up once frames are comfortably fast again. This used\n            to be one-way, on the reasoning that it could not then oscillate —\n            but that also meant one transient stall permanently halved the\n            orb's resolution, and at half resolution a high-frequency shader\n            aliases into shimmer that reads as the shader itself misbehaving.\n            The gap between the two thresholds (29ms down, 18ms up) is the\n            hysteresis that stops it hunting.\n          */\n          resScale = Math.min(1, resScale / 0.8)\n          frameEma = 1 / 60\n          resize()\n        }\n\n        uploadAndDraw(dt)\n      }\n      /*\n        First frame synchronously, before entering the rAF loop. rAF does not\n        run at all in hidden documents (background tabs, embedded previews),\n        so a freshly mounted orb would otherwise sit fully transparent until\n        the page next becomes visible — a grid of mounted, healthy, blank\n        canvases. The sync frame guarantees every mount paints: background\n        documents get a static frame, visible ones start animating over it.\n        dt = 1 lands the param glide on its targets, as in the reduce-motion\n        frame above.\n      */\n      uploadAndDraw(1)\n      loop()\n\n      return () => {\n        cancelAnimationFrame(raf)\n        releaseGL()\n      }\n    }\n\n    /*\n      Wire the canvas's lifecycle controller. The listeners are attached ONCE\n      per canvas element and never removed, deliberately: the lost event must\n      be canceled even while no orb is mounted on the canvas — an uncanceled\n      webglcontextlost marks the context permanently unrestorable, and the\n      router can show this exact canvas again later. Whether a loss leads to\n      a revival is decided by `desired`, not by listener presence.\n    */\n    /*\n      A canvas whose context has gone is not simply blank: Chrome paints its\n      broken-image placeholder over the element's whole box — the white square\n      you see on a reloaded grid. Hide the canvas the moment the context is\n      lost, and let the generation that follows a restore reveal it again.\n    */\n    const hideNow = () => {\n      /*\n        Both, deliberately. The style write lands in this tick — the browser\n        paints its placeholder over a dead canvas immediately, and a busy main\n        thread can hold a React update for several frames. The state change is\n        what keeps React's own view in sync, so the reveal that follows a\n        restore clears the inline value again rather than fighting it.\n      */\n      canvas.style.opacity = \"0\"\n      setPaintedKey(null)\n    }\n\n    const onContextLostHide = () => hideNow()\n    canvas.addEventListener(\"webglcontextlost\", onContextLostHide)\n\n    /*\n      Hand the context back before the next document asks for one.\n\n      A hard reload never runs this effect's cleanup — the document is\n      discarded whole — so the outgoing page's contexts are still alive while\n      the incoming page allocates its own. On a grid of orbs that puts the\n      live count past the browser's ~16 cap, and the ones it evicts are\n      exactly the canvases that come back as placeholders until the restore\n      path catches them. `persisted` is a bfcache suspend, where the page is\n      shown again untouched and must keep everything it holds.\n    */\n    const onPageHide = (event: PageTransitionEvent) => {\n      if (event.persisted) return\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Already released — nothing to hand back.\n      }\n    }\n    window.addEventListener(\"pagehide\", onPageHide)\n\n    let ctl = canvasControllers.get(canvas)\n    if (!ctl) {\n      const created: CanvasContextController = {\n        desired: false,\n        start: null,\n        stopGen: null,\n      }\n      canvas.addEventListener(\"webglcontextlost\", (event) => {\n        event.preventDefault() // always cancel — keeps the context restorable\n        created.stopGen?.()\n        created.stopGen = null\n        if (created.desired) {\n          /*\n            Ask for the context back — but in a LATER task. The browser only\n            marks a loss as restorable once the lost event's dispatch has\n            completed and it has seen the canceled flag, so a restoreContext()\n            issued during dispatch (or before it, as the mount path may) is\n            silently refused. This is the path a synchronous cleanup+setup\n            pair hits — React re-running the effect on the same canvas loses\n            the context and wants it right back. For losses we didn't cause\n            (eviction, GPU reset) the call may refuse; the canceled event then\n            lets the browser restore on its own schedule.\n          */\n          setTimeout(() => {\n            if (!created.desired) return\n            try {\n              loseExt?.restoreContext()\n            } catch {\n              // Natural loss — restoration is the browser's call now.\n            }\n          }, 0)\n        }\n      })\n      canvas.addEventListener(\"webglcontextrestored\", () => {\n        if (created.desired && created.start) {\n          created.stopGen = created.start()\n        }\n      })\n      canvasControllers.set(canvas, created)\n      ctl = created\n    }\n    const controller = ctl\n\n    controller.desired = true\n    controller.start = startGeneration\n    if (gl.isContextLost()) {\n      // A previous run on this canvas released the context (effect re-run, or\n      // the router re-showing a kept-alive page). If the lost event already\n      // dispatched this request is honored now; if it is still queued, the\n      // lost handler above re-requests it on dispatch.\n      try {\n        loseExt?.restoreContext()\n      } catch {\n        // No restore path — the orb stays blank rather than throwing.\n      }\n    } else {\n      controller.stopGen = startGeneration()\n    }\n\n    return () => {\n      /*\n        Hide BEFORE tearing the context down.\n\n        This cleanup releases the context deliberately, and the lost event it\n        provokes is dispatched asynchronously — by which point the listener\n        below is unhooked and the replacement effect has not drawn yet. That\n        leaves a revealed canvas with a dead context, which is precisely what\n        the browser paints its broken-canvas placeholder over. The window is\n        not rare: any prop change in this effect's deps re-runs it, so it hits\n        every time the drawer switches preview example (maxDpr differs on the\n        layout one) or a wrapper is toggled.\n      */\n      hideNow()\n      canvas.removeEventListener(\"webglcontextlost\", onContextLostHide)\n      window.removeEventListener(\"pagehide\", onPageHide)\n      controller.desired = false\n      controller.start = null\n      controller.stopGen?.()\n      controller.stopGen = null\n      /*\n        Release the context NOW instead of when the canvas is garbage\n        collected. Browsers cap live WebGL contexts per page (~8–16) and evict\n        the oldest when the cap is hit — client-side navigation that unmounts\n        and remounts a page of orbs otherwise piles up zombie contexts until\n        freshly mounted orbs get evicted and render blank.\n      */\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Context already lost — nothing to release.\n      }\n    }\n    /*\n      `wrapped` is in here because turning a wrapper on or off moves the canvas\n      from being this component's root element to being a child of the wrapper\n      div — React drops the old element and mounts a new one, and the GL\n      context, its observers and its render loop all belong to the old one. Any\n      other prop leaves the element alone, INCLUDING a swap between two\n      wrappers: the canvas keeps its slot among the decoration layers, so\n      glass -> ring reuses the context instead of rebuilding it.\n    */\n  }, [variant, pauseOffscreen, maxDpr, wrapped])\n\n  const sizeStyle: CSSProperties =\n    size === undefined ? {} : { width: size, height: size }\n\n  /*\n    Spread ahead of the caller's `style`, so an orb that wants to own its own\n    opacity still can — it simply opts out of the reveal.\n\n    A hard flip, deliberately: no transition, no fade. A hidden document\n    (background tab, embedded preview) does not advance CSS transitions, so a\n    faded reveal left orbs pinned at zero in exactly the case the synchronous\n    first frame above exists to serve — mounted, healthy, and invisible. The\n    cut is not a pop either way, since it happens on the frame the orb first\n    has something to show.\n  */\n  const revealStyle: CSSProperties = painted ? {} : { opacity: 0 }\n\n  const canvas = (\n    <canvas\n      // A lost WebGL context can't be reused, so each variant gets a fresh canvas.\n      key={variant.key}\n      ref={canvasRef}\n      className={spec ? undefined : className}\n      style={\n        spec\n          ? {\n              display: \"block\",\n              position: \"absolute\",\n              left: `${spec.inset}%`,\n              top: `${spec.inset}%`,\n              width: `${100 - 2 * spec.inset}%`,\n              height: `${100 - 2 * spec.inset}%`,\n              ...revealStyle,\n              ...(spec.mask ? masked(spec.mask) : {}),\n            }\n          : { display: \"block\", ...sizeStyle, ...revealStyle, ...style }\n      }\n      role={!spec && ariaLabel ? \"img\" : undefined}\n      aria-label={spec ? undefined : ariaLabel}\n      aria-hidden={!spec && ariaLabel ? undefined : true}\n    />\n  )\n\n  if (!spec) return canvas\n\n  /*\n    Wrapped: the box becomes the orb's footprint and the canvas is absolutely\n    positioned inside it. `under`, the canvas and `over` are all positioned\n    with an auto z-index, so they paint in DOM order — decoration behind the\n    orb, then the orb, then decoration in front of it.\n\n    `aspectRatio` is the fallback for the sizeless case: `size` is optional\n    (callers may size the orb with a class instead), and an absolutely\n    positioned canvas contributes nothing to its parent's height, so without\n    it a class that only sets a width would collapse the box to zero.\n  */\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"relative\",\n        aspectRatio: \"1 / 1\",\n        ...(spec.shadow ? { borderRadius: \"50%\", boxShadow: spec.shadow } : {}),\n        ...sizeStyle,\n        ...(wrapperColor ? { color: wrapperColor } : {}),\n        ...style,\n      }}\n      role={ariaLabel ? \"img\" : undefined}\n      aria-label={ariaLabel}\n      aria-hidden={ariaLabel ? undefined : true}\n    >\n      {spec.animated ? (\n        <style\n          href={WRAPPER_STYLE_HREF}\n          precedence=\"default\"\n          dangerouslySetInnerHTML={{ __html: WRAPPER_CSS }}\n        />\n      ) : null}\n      {spec.under}\n      {canvas}\n      {spec.over}\n    </div>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE",
          "target": "@components/voice-agents/orbkit/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 zzzzshawn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/orbkit/SOURCE.json",
          "target": "@components/voice-agents/orbkit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"OrbKit\",\n  \"repository\": \"https://github.com/zzzzshawn/orbkit\",\n  \"commit\": \"35e42484560fd35e8502703ba58fa99541d8c686\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 zzzzshawn\",\n  \"core\": \"components/voice-agents/orbkit/core.tsx\",\n  \"credits\": \"components/voice-agents/orbkit/CREDITS.md\",\n  \"shaderLicense\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\",\n  \"changes\": [\n    \"Moved the dependency-free OrbKit runtime and selected variants into the Agents Kit voice collection.\",\n    \"Mapped variant imports to the local shared runtime.\",\n    \"Kept the upstream reduced-motion, offscreen pause, DPR cap, context recovery, and cleanup behavior.\"\n  ],\n  \"exclusions\": [\n    {\n      \"name\": \"shdr-19\",\n      \"reason\": \"Non-commercial XorDev shader; excluded from this distributable MIT collection.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    },\n    {\n      \"name\": \"XorDev shader ports\",\n      \"reason\": \"All variants listed under Shaders by XorDev in CREDITS.md are non-commercial and excluded.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    }\n  ],\n  \"components\": [\n    {\n      \"name\": \"shdr-11\",\n      \"path\": \"shdr-11.tsx\",\n      \"title\": \"Hydrogen\"\n    },\n    {\n      \"name\": \"shdr-13\",\n      \"path\": \"shdr-13.tsx\",\n      \"title\": \"Ion\"\n    },\n    {\n      \"name\": \"shdr-14\",\n      \"path\": \"shdr-14.tsx\",\n      \"title\": \"Dither\"\n    },\n    {\n      \"name\": \"shdr-21\",\n      \"path\": \"shdr-21.tsx\",\n      \"title\": \"Nimbus\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/CREDITS.md",
          "target": "@components/voice-agents/orbkit/CREDITS.md",
          "type": "registry:file",
          "content": "# Credits\n\nOrbkit ships two kinds of orb. Every file says which it is.\n\n## Shaders by XorDev\n\nThese 19 orbs are ported from golfed shaders by [XorDev](https://x.com/XorDev),\nused with his permission (agreed by direct message on 2026-09-06). Terms:\n**non-commercial use only, with attribution to XorDev**. Each file starts with\na notice that must stay with any copy, and the registry marks these items with\na `credit` field. See [LICENSE-SHADERS.md](LICENSE-SHADERS.md).\n\n| Orb     | Shader by | Original             |\n| ------- | --------- | -------------------- |\n| shdr-01 | XorDev    | https://x.com/XorDev |\n| shdr-02 | XorDev    | https://x.com/XorDev |\n| shdr-03 | XorDev    | https://x.com/XorDev |\n| shdr-04 | XorDev    | https://x.com/XorDev |\n| shdr-05 | XorDev    | https://x.com/XorDev |\n| shdr-06 | XorDev    | https://x.com/XorDev |\n| shdr-07 | XorDev    | https://x.com/XorDev |\n| shdr-08 | XorDev    | https://x.com/XorDev |\n| shdr-09 | XorDev    | https://x.com/XorDev |\n| shdr-10 | XorDev    | https://x.com/XorDev |\n| shdr-15 | XorDev    | https://x.com/XorDev |\n| shdr-18 | XorDev    | https://x.com/XorDev |\n| shdr-19 | XorDev    | https://x.com/XorDev |\n| shdr-20 | XorDev    | https://x.com/XorDev |\n| shdr-22 | XorDev    | https://x.com/XorDev |\n| shdr-25 | XorDev    | https://x.com/XorDev |\n| shdr-26 | XorDev    | https://x.com/XorDev |\n| shdr-28 | XorDev    | https://x.com/XorDev |\n| shdr-31 | XorDev    | https://x.com/XorDev |\n\nReplace a profile link with the specific post once it is known.\n\n## Original orbs\n\nThese 14 orbs are Orbkit's own work and are MIT-licensed, like the runtime:\nshdr-11, shdr-12, shdr-13, shdr-14, shdr-16, shdr-17, shdr-21, shdr-23, shdr-24, shdr-27, shdr-29, shdr-30, shdr-32, shdr-33.\n\n## Adding shaders\n\nAsk the original author before porting anything that is not your own. XorDev\nasked to be consulted before any more of his work is included.\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "target": "@components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "type": "registry:file",
          "content": "# Licence for the ported shaders\n\nThe orb files listed under \"Shaders by XorDev\" in [CREDITS.md](CREDITS.md) are\nderived from shaders by XorDev (https://x.com/XorDev) and are used with the\nauthor's permission on these terms:\n\n1. Non-commercial use only.\n2. Attribution to XorDev must be kept with every copy, including the notice at\n   the top of each file.\n3. Any further use of XorDev's work requires asking the author first.\n\nEverything else in this repository, including the runtime\n(`orbkit-core.tsx`), the site, the build scripts, and the original orbs, is\nlicensed under the MIT licence in [LICENSE](LICENSE).\n"
        }
      ],
      "categories": [
        "OrbKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "orbkit-shdr-13",
      "type": "registry:block",
      "title": "Orbkit Shdr 13",
      "description": "Ion",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/orbkit/shdr-13.tsx",
          "target": "@components/voice-agents/orbkit/shdr-13.tsx",
          "type": "registry:component",
          "content": "/*\n * Deliberately not a `\"use client\"` module — see the note in `shdr-11.tsx`.\n *\n * Note for editors: the shader lives in a template literal, so its comments\n * must not contain backticks.\n */\nimport { ShaderOrb, type OrbVariant, type ShaderOrbProps } from \"./core\"\n\n/* ----------------------------------------------------------------------------\n   SHDR-13 — a plasma globe: crawling lightning filaments inside a glass ball.\n\n   The reference is the physical object: a tesla ball with a hot nucleus,\n   pink-to-violet streamers writhing out to the glass, and bright flares\n   where a filament touches the shell.\n\n   How the filaments are built, and why they behave like the real thing:\n\n   - A curve in 3D is the intersection of two level surfaces. Two independent\n     trig fields are evaluated on the DIRECTION of each march point\n     (q = dir * fils, |dir| = 1), so their joint zero set is a set of\n     directions — extruded radially, those are filaments running from the\n     nucleus to the glass, never a floating blob. Filament count rides the\n     angular frequency uP_fils, so a state preset can literally grow more\n     streamers, and because the field morphs smoothly the new ones split off\n     from existing ones instead of popping in.\n   - Each field carries its own additive time phases, so the zero curves\n     drift, merge, and reconnect — the crawl of a real streamer hunting\n     across the glass. The whole array also precesses on an integrated spin\n     clock.\n   - A radial writhe term bends the direction before sampling, gated by\n     smoothstep from the centre so every filament stays ROOTED at the\n     nucleus while its far end wanders on the shell.\n   - Proximity to the curve is measured in field space (f1^2 + f2^2), and\n     brightness is its inverse — the same 1/d accumulation as the other\n     volumetric orbs, so thickness varies naturally along a filament with\n     the field gradient.\n   - The march is bounded to the exact ray/sphere chord (entry to exit), and\n     each step is weighted by its true length, so limb rays integrate short\n     chords and dim correctly; the tip flare (a smoothstep in r near the\n     shell) is what lights the glass from inside where streamers land.\n   - Colour is a radial mix: the inner colour near the nucleus, the arc\n     colour toward the glass, cores whitened by their own intensity — the\n     pink-core / violet-tip gradient of a real discharge.\n\n   House rules followed from the other orbs: per-step clamp before the\n   spikes own the frame, front-to-back transmittance, tanh tone map with an\n   exposure knee, alpha from the brightest channel, and the analytic\n   silhouette cut from each ray's closest approach — colour AND alpha.\n---------------------------------------------------------------------------- */\n\n/*\n * Step count is a `#define`: ES 1.0 requires constant loop bounds.\n */\nconst ION_FRAG = `\n#define STEPS 64\n\n// Volume-reactive values, resolved once per fragment in main().\nfloat ionSharp;\nfloat ionWrithe;\nfloat ionCore;\nfloat ionExposure;\nfloat ionRadius;\n\nmat2 ionRot2(float a) {\n  float c = cos(a);\n  float s = sin(a);\n  return mat2(c, -s, s, c);\n}\n\nvec3 ionRender(vec2 fragCoord) {\n  float t = uP_speed;      // integrated clock: filament crawl\n  float spinAng = uP_spin; // integrated clock: array precession\n\n  vec2 uv = (2.0 * fragCoord - uRes) / min(uRes.x, uRes.y);\n  vec3 ro = vec3(0.0, 0.0, uP_camDist);\n  vec3 rd = normalize(vec3(uv, -uP_focal));\n\n  // exact ray/sphere chord — the march never leaves the globe, so no\n  // envelope fade is needed and every step length is meaningful\n  float proj = dot(-ro, rd);\n  float b2 = dot(ro, ro) - proj * proj;\n  float half_ = sqrt(max(ionRadius * ionRadius - b2, 0.0));\n  float zNear = proj - half_;\n  float stepLen = 2.0 * half_ / float(STEPS);\n  // per-pixel jitter of the march start: a filament grazed at a shallow\n  // angle is crossed periodically by the fixed step grid and renders as a\n  // dotted chain — the jitter decorrelates neighbouring rays and melts the\n  // dots into plasma grain\n  zNear += (hash(fragCoord) - 0.5) * stepLen;\n\n  vec3 acc = vec3(0.0);\n  float T = 1.0;\n\n  for (int i = 0; i < STEPS; i++) {\n    vec3 p = ro + rd * (zNear + (float(i) + 0.5) * stepLen);\n\n    // precess the whole filament array; a static tilt keeps the spin axis\n    // off-vertical so the motion reads in 3D\n    vec3 pr = p;\n    pr.xz = ionRot2(spinAng) * pr.xz;\n    pr.yz = ionRot2(uP_tilt) * pr.yz;\n\n    float r = length(pr);\n    vec3 dir = pr / max(r, 1e-4);\n    float rr = r / max(ionRadius, 1e-3);\n\n    // writhe: bend the sampling direction with radius and time, rooted at\n    // the nucleus by the smoothstep so filaments stay attached\n    float wr = ionWrithe * smoothstep(0.0, ionRadius * 0.35, r);\n    vec3 q = dir * uP_fils;\n    q += wr * vec3(\n      sin(r * uP_writheFreq        - t * 1.2 + q.y * 1.8),\n      sin(r * uP_writheFreq * 0.83 + t * 1.0 + q.z * 1.8),\n      sin(r * uP_writheFreq * 1.19 - t * 0.7 + q.x * 1.8));\n\n    // two independent fields over the direction sphere; their joint zero\n    // set is the filament curves. Time enters as additive phase only.\n    float f1 = sin(q.x + t * 0.70)\n             + sin(q.y * 1.31 - t * 0.50)\n             + sin(q.z * 1.13 + t * 0.90);\n    float f2 = sin(q.y * 1.21 + t * 0.60 + 1.7)\n             + sin(q.z * 1.43 - t * 0.80 + 3.1)\n             + sin(q.x * 0.87 + t * 0.40 + 5.0);\n    float d2 = f1 * f1 + f2 * f2;\n    float g = 1.0 / (d2 * ionSharp + uP_soft);\n\n    // flare where a streamer lands on the glass, and the hot nucleus\n    g *= 1.0 + uP_tipGain * smoothstep(0.55, 0.95, rr);\n    float core = ionCore / (r * r * 8.0 + 0.05);\n\n    // pink near the nucleus, violet-blue at the glass, cores whitened by\n    // their own intensity\n    vec3 fCol = mix(uC_inner, uC_arc, smoothstep(0.1, 0.75, rr));\n    vec3 w = (fCol + vec3(uP_whiten) * g) * g + uC_inner * core + vec3(uP_fill);\n    w = min(w, vec3(uP_stepClamp));\n    w *= stepLen; // length-fair: limb chords are short and dim correctly\n\n    acc += T * w;\n    T *= exp(-dot(w, vec3(0.299, 0.587, 0.114)) * uP_scatter);\n    if (T < 0.004) break;\n  }\n\n  return acc;\n}\n\nvoid main() {\n  // Louder agent output softens and thickens the arcs and quickens the\n  // writhe; user input flares the nucleus — the globe answers being spoken\n  // to the way the real toy answers a fingertip.\n  ionSharp = uP_sharp * (1.0 - 0.25 * uOutput);\n  ionWrithe = uP_writhe * (1.0 + 0.6 * uOutput);\n  ionCore = uP_coreGain * (1.0 + 1.6 * uInput + 0.4 * uOutput);\n  ionExposure = uP_exposure * (1.0 - 0.35 * uOutput);\n  ionRadius = uP_envRadius + uP_swell * uInput;\n\n  vec3 acc = ionRender(gl_FragCoord.xy);\n\n  // tanh tone map with a tunable knee, then the usual finishing chain\n  vec3 col = tanh3(acc / max(ionExposure, 0.01));\n  col = pow(clamp(col, 0.0, 1.0), vec3(uP_contrast));\n\n  float lum = dot(col, vec3(0.299, 0.587, 0.114));\n  col = mix(vec3(lum), col, uP_saturation);\n  col *= uC_tint;\n\n  // alpha from the brightest channel — a saturated violet streamer has low\n  // luminance but must not go transparent\n  float peak = max(col.r, max(col.g, col.b));\n  float a = clamp(peak * uP_alphaGain, 0.0, 1.0);\n\n  // analytic silhouette, identical construction to shdr-01: exact\n  // ray-to-centre distance against the radius, colour AND alpha\n  vec3 mrd = normalize(vec3(orbUV(), -uP_focal));\n  float closest = length(cross(vec3(0.0, 0.0, uP_camDist), mrd));\n  float band = mix(0.35, 0.012, clamp(uP_edge, 0.0, 1.0));\n  float mask = 1.0 - smoothstep(ionRadius * (1.0 - band), ionRadius * 1.005, closest);\n  col *= mask;\n  a *= mask;\n\n  // Emitted light, so rgb is already premultiplied — do NOT scale by alpha\n  // again (see the same note in shdr-31).\n  gl_FragColor = vec4(col, a);\n}\n`\n\nexport const shdr13Orb: OrbVariant = {\n  key: \"shdr-13\",\n  label: \"SHDR-13\",\n  note: \"plasma globe: crawling lightning filaments\",\n  frag: ION_FRAG,\n  params: [\n    {\n      key: \"speed\",\n      label: \"Anim speed\",\n      min: 0.015,\n      max: 10,\n      step: 0.05,\n      default: 1,\n      integrate: true,\n    },\n    {\n      key: \"spin\",\n      label: \"Spin rate\",\n      min: 0,\n      max: 5,\n      step: 0.03,\n      default: 0.2,\n      integrate: true,\n    },\n    {\n      key: \"camDist\",\n      label: \"Camera distance\",\n      min: 1,\n      max: 50,\n      step: 0.3,\n      default: 7,\n    },\n    {\n      key: \"focal\",\n      label: \"Lens\",\n      min: 0.15,\n      max: 15,\n      step: 0.1,\n      default: 2.25,\n    },\n    {\n      key: \"envRadius\",\n      label: \"Globe radius\",\n      min: 0.15,\n      max: 15,\n      step: 0.1,\n      default: 2.6,\n    },\n    {\n      key: \"swell\",\n      label: \"Input swell\",\n      min: 0,\n      max: 1,\n      step: 0.01,\n      default: 0.15,\n    },\n    {\n      key: \"tilt\",\n      label: \"Axis tilt\",\n      min: 0,\n      max: 4,\n      step: 0.02,\n      default: 0.4,\n    },\n    {\n      key: \"fils\",\n      label: \"Filament density\",\n      min: 0.5,\n      max: 12,\n      step: 0.1,\n      default: 6,\n    },\n    {\n      key: \"writhe\",\n      label: \"Writhe\",\n      min: 0,\n      max: 3,\n      step: 0.02,\n      default: 0.9,\n    },\n    {\n      key: \"writheFreq\",\n      label: \"Writhe frequency\",\n      min: 0.2,\n      max: 8,\n      step: 0.05,\n      default: 1.6,\n    },\n    {\n      key: \"sharp\",\n      label: \"Arc sharpness\",\n      min: 0.5,\n      max: 60,\n      step: 0.5,\n      default: 4,\n    },\n    {\n      key: \"soft\",\n      label: \"Arc core softness\",\n      min: 0.002,\n      max: 0.5,\n      step: 0.002,\n      default: 0.06,\n    },\n    {\n      key: \"whiten\",\n      label: \"Core whitening\",\n      min: 0,\n      max: 0.2,\n      step: 0.002,\n      default: 0.008,\n    },\n    {\n      key: \"coreGain\",\n      label: \"Nucleus glow\",\n      min: 0,\n      max: 5,\n      step: 0.05,\n      default: 1.6,\n    },\n    {\n      key: \"tipGain\",\n      label: \"Glass flare\",\n      min: 0,\n      max: 6,\n      step: 0.05,\n      default: 1.8,\n    },\n    {\n      key: \"fill\",\n      label: \"Body haze\",\n      min: 0,\n      max: 2,\n      step: 0.01,\n      default: 0.02,\n    },\n    {\n      key: \"stepClamp\",\n      label: \"Step clamp\",\n      min: 0.3,\n      max: 300,\n      step: 1.5,\n      default: 40,\n    },\n    {\n      key: \"scatter\",\n      label: \"Diffusion\",\n      min: 0,\n      max: 0.5,\n      step: 0.003,\n      default: 0.012,\n    },\n    {\n      key: \"exposure\",\n      label: \"Exposure\",\n      min: 0.1,\n      max: 200,\n      step: 0.5,\n      default: 11,\n    },\n    {\n      key: \"contrast\",\n      label: \"Contrast\",\n      min: 0.15,\n      max: 15,\n      step: 0.1,\n      default: 1,\n    },\n    {\n      key: \"saturation\",\n      label: \"Saturation\",\n      min: 0,\n      max: 4,\n      step: 0.02,\n      default: 1.2,\n    },\n    {\n      key: \"alphaGain\",\n      label: \"Alpha gain\",\n      min: 0.05,\n      max: 15,\n      step: 0.1,\n      default: 2.5,\n    },\n    {\n      key: \"edge\",\n      label: \"Edge sharpness\",\n      min: 0,\n      max: 1,\n      step: 0.01,\n      default: 1,\n    },\n  ],\n  colors: [\n    { key: \"inner\", label: \"Nucleus\", default: \"#ff70d8\" },\n    { key: \"arc\", label: \"Arc\", default: \"#5a5cff\" },\n    { key: \"tint\", label: \"Tint\", default: \"#ffffff\" },\n  ],\n  statePresets: {\n    // a full globe of swooping arcs around a hot nucleus\n    idle: {\n      speed: 1,\n      spin: 0.2,\n      fils: 6,\n      writhe: 0.9,\n      sharp: 4,\n      soft: 0.06,\n      whiten: 0.008,\n      tipGain: 1.8,\n      coreGain: 1.6,\n      exposure: 11,\n    },\n    // hunting: even more filaments, softer and more nebular, restless writhe\n    thinking: {\n      speed: 1.8,\n      spin: 0.45,\n      fils: 7,\n      writhe: 1.2,\n      sharp: 3,\n      soft: 0.08,\n      whiten: 0.012,\n      tipGain: 1.5,\n      coreGain: 1.2,\n      exposure: 10,\n    },\n    // discharge: the densest, brightest state — spiky arcs flaring hard on\n    // the glass around a blazing core\n    speaking: {\n      speed: 2.6,\n      spin: 0.3,\n      fils: 8,\n      writhe: 1.3,\n      sharp: 3.5,\n      soft: 0.05,\n      whiten: 0.012,\n      tipGain: 2.4,\n      coreGain: 2,\n      exposure: 8.5,\n    },\n  },\n}\n\nexport type Shdr13Props = Omit<ShaderOrbProps, \"variant\">\n\nexport function Shdr13({ size = 280, ...rest }: Shdr13Props) {\n  return <ShaderOrb variant={shdr13Orb} size={size} {...rest} />\n}\n\nexport default Shdr13\n"
        },
        {
          "path": "components/voice-agents/orbkit/core.tsx",
          "target": "@components/voice-agents/orbkit/core.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport React, {\n  useEffect,\n  useRef,\n  useState,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/* ----------------------------------------------------------------------------\n   Orbkit core — raw WebGL shader orb runtime. No dependencies.\n\n   An orb is a full-screen triangle rendered into a transparent canvas by a\n   fragment shader. Every orb declares a parameter schema (sliders + colors);\n   the values are uploaded as uniforms each frame from a ref, so a controls\n   panel can tune them live without ever remounting the canvas (a remount would\n   drop the WebGL context).\n\n   Animation model: every state synthesizes two volume signals — input (user\n   speech energy) and output (agent speech energy) — smooths them, and the\n   shaders react to those. The flow clock's speed itself follows the output\n   volume, so orbs visibly quicken when the agent is talking.\n---------------------------------------------------------------------------- */\n\nexport type OrbState = \"idle\" | \"thinking\" | \"speaking\"\n\nexport const ORB_STATES = [\"idle\", \"thinking\", \"speaking\"] as const\n\nfunction clamp01(n: number) {\n  return Math.min(1, Math.max(0, n))\n}\n\n/** Per-state [input, output] volume synthesis. */\n/**\n * Transition rate shared by params, colours and the flow-speed multiplier.\n * They must move together: if the rate multiplier eases faster than the look,\n * a state change spins the orb up before it has finished cross-fading, which\n * reads as a lurch.\n *\n * This drives a critically damped spring rather than the exponential ease it\n * used to. An exponential's velocity is highest at the instant the target\n * changes, so every state change began with a jolt — and for params that are\n * spatial frequencies (Corona's warpFreq travels 5.25 -> 19.5 between states)\n * that jolt sweeps the field through its intermediate frequencies at maximum\n * rate, which is what read as the transition \"scrambling\".\n *\n * A spring starts at rest and accelerates, so the sweep is spread across the\n * transition instead of front-loaded. Measured on that warpFreq move it is a\n * 20% lower peak rate of change (20.3/s vs 25.3/s) AND it arrives sooner —\n * 1.50s to within 2% against the exponential's 2.18s, since an exponential\n * only ever asymptotes toward its target.\n */\nconst PARAM_EASE = 4\n\n/*\n  One step of a critically damped spring, implicit (semi-implicit Euler would\n  blow up at the frame times a backgrounded tab produces). Returns nothing and\n  writes through the scratch pair so the hot loop allocates nothing.\n*/\nconst springOut = { x: 0, v: 0 }\nfunction springStep(\n  x: number,\n  v: number,\n  target: number,\n  dt: number,\n  omega: number\n) {\n  const f = 1 + 2 * dt * omega\n  const oo = omega * omega\n  const hoo = dt * oo\n  const hhoo = dt * hoo\n  const detInv = 1 / (f + hhoo)\n  springOut.x = (f * x + dt * v + hhoo * target) * detInv\n  springOut.v = (v + hoo * (target - x)) * detInv\n}\n\nfunction targetVolumes(state: OrbState, t: number): [number, number] {\n  switch (state) {\n    case \"idle\":\n      return [0, 0.3]\n    case \"speaking\":\n      return [\n        clamp01(0.65 + Math.sin(t * 4.8) * 0.22),\n        clamp01(0.75 + Math.sin(t * 3.6) * 0.22),\n      ]\n    case \"thinking\": {\n      const base = 0.38 + 0.07 * Math.sin(t * 0.7)\n      const wander = 0.05 * Math.sin(t * 2.1) * Math.sin(t * 0.37 + 1.2)\n      return [\n        clamp01(base + wander),\n        clamp01(0.48 + 0.12 * Math.sin(t * 1.05 + 0.6)),\n      ]\n    }\n  }\n}\n\n/* ------------------------------ param schema ------------------------------- */\n\nexport interface OrbParamDef {\n  key: string\n  label: string\n  min: number\n  max: number\n  step: number\n  default: number\n  /**\n   * Rate params. The engine integrates them into a clock\n   * (`clock += dt * value * volumeSpeed`) and uploads the clock instead of the\n   * raw value, so changing the rate never jumps the phase — the motion speeds\n   * up or slows down rather than snapping to a new position.\n   */\n  integrate?: boolean\n}\n\nexport interface OrbColorDef {\n  key: string\n  label: string\n  /** hex, e.g. `#ff8b73` */\n  default: string\n}\n\nexport interface OrbVariant {\n  key: string\n  label: string\n  note: string\n  /** GLSL fragment shader body. Uniform declarations are generated for you. */\n  frag: string\n  params: OrbParamDef[]\n  colors: OrbColorDef[]\n  /**\n   * Per-state parameter targets. The engine glides each param toward the\n   * active state's preset. Params passed explicitly via the `params` prop\n   * always win over the preset.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /**\n   * Per-state colour targets, the colour counterpart of `statePresets`.\n   * Kept a separate map because presets are numeric and colours are hex\n   * strings — a union would lose type safety on both. Colours glide in RGB\n   * on the same easing as params, so a state change cross-fades rather\n   * than cutting. Colours passed explicitly via the `colors` prop always\n   * win, exactly as with params.\n   */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n}\n\nexport type OrbParamValues = Partial<Record<string, number>>\nexport type OrbColorValues = Partial<Record<string, string>>\n\n/** Every param and color at its schema default. */\nexport function defaultValuesFor(variant: OrbVariant): {\n  params: Record<string, number>\n  colors: Record<string, string>\n} {\n  return {\n    params: Object.fromEntries(variant.params.map((p) => [p.key, p.default])),\n    colors: Object.fromEntries(variant.colors.map((c) => [c.key, c.default])),\n  }\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace(\"#\", \"\").trim()\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]\n  const n = parseInt(h, 16)\n  if (h.length !== 6 || Number.isNaN(n)) return [1, 1, 1]\n  return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255]\n}\n\n/* ------------------------------- GLSL shared ------------------------------- */\n\nconst VERT = `\nattribute vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\n/**\n * Prelude prepended to every orb fragment shader: uniforms, value noise, fbm,\n * and the centered aspect-corrected UV helper.\n */\nexport const ORB_GLSL_HELPERS = `\nprecision highp float;\nuniform vec2 uRes;\nuniform float uTime;   // slow ambient clock (half real-time)\nuniform float uAnim;   // flow clock — its speed follows the output volume\nuniform float uInput;  // input volume 0..1: user speech energy\nuniform float uOutput; // output volume 0..1: agent speech energy\n\nfloat hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); }\nfloat noise(vec2 p) {\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);\n  return mix(\n    mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),\n    mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x),\n    f.y\n  );\n}\nfloat fbm(vec2 p) {\n  float v = 0.0;\n  float a = 0.5;\n  for (int i = 0; i < 5; i++) {\n    v += a * noise(p);\n    p = p * 2.03 + vec2(11.7, 7.3);\n    a *= 0.5;\n  }\n  return v;\n}\nvec2 orbUV() { return (2.0 * gl_FragCoord.xy - uRes) / min(uRes.x, uRes.y); }\n\n// GLSL ES 1.0 has no tanh() — it arrived in ES 3.0. Shader-golf listings lean\n// on it as a tone-mapper, so it ships here. Clamped against exp() overflow;\n// accurate for the non-negative accumulators those shaders produce.\nvec3 tanh3(vec3 x) {\n  x = clamp(x, -10.0, 10.0);\n  vec3 e = exp(2.0 * x);\n  return (e - 1.0) / (e + 1.0);\n}\n\n`\n\nfunction paramUniformDecls(variant: OrbVariant): string {\n  return [\n    ...variant.params.map((p) => `uniform float uP_${p.key};`),\n    ...variant.colors.map((c) => `uniform vec3 uC_${c.key};`),\n  ].join(\"\\n\")\n}\n\n/* ------------------------------- engine ------------------------------------ */\n\n/**\n * Per-canvas context-lifecycle controller. Created on first mount of a canvas\n * and kept for the element's whole life — the router can hide a page and show\n * the same DOM again, and React re-runs effects on the same canvas, so the\n * lost/restored listeners must outlive any single effect run: an uncanceled\n * webglcontextlost event marks the context permanently unrestorable.\n */\ninterface CanvasContextController {\n  /** Whether a mounted orb currently wants this context alive. */\n  desired: boolean\n  /** Builds a render generation; returns its teardown. Rebound per effect run. */\n  start: (() => () => void) | null\n  /** Teardown of the live generation, if one is running. */\n  stopGen: (() => void) | null\n}\n\nconst canvasControllers = new WeakMap<\n  HTMLCanvasElement,\n  CanvasContextController\n>()\n\nfunction compile(\n  gl: WebGLRenderingContext,\n  type: number,\n  src: string\n): WebGLShader | null {\n  const shader = gl.createShader(type)\n  if (!shader) return null\n  gl.shaderSource(shader, src)\n  gl.compileShader(shader)\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    console.error(\"[orbkit] shader compile error:\", gl.getShaderInfoLog(shader))\n    gl.deleteShader(shader)\n    return null\n  }\n  return shader\n}\n\n/* ----------------------------------------------------------------------------\n   Wrappers — optional decoration drawn around, under and over the orb.\n\n   A wrapper is pure CSS/SVG, never a shader: the orb keeps its own canvas and\n   the decoration is composited on top of it by the browser. That keeps the\n   whole set free for any orb (no per-variant shader work), costs nothing on\n   the GPU budget the shaders are already spending, and means swapping one\n   wrapper for another at runtime never touches the WebGL context. Turning a\n   wrapper on or off does, since that is what moves the canvas into or out of\n   the wrapper element — see the effect's `wrapped` dependency.\n\n   Layout: a wrapped orb becomes a square box, and the canvas is absolutely\n   positioned inside it with the spec's `inset`. The FOOTPRINT is unchanged —\n   `size` is still the outer diameter — so dropping a wrapper onto an existing\n   orb reflows nothing; the orb itself just shrinks to leave the ring room.\n\n   Colour: every layer that isn't physically light or shadow paints in\n   `currentColor`, so a wrapper picks up the surrounding text colour and reads\n   correctly on light and dark pages with no configuration. `wrapperColor`\n   sets that colour when you want something other than the inherited one.\n---------------------------------------------------------------------------- */\n\nexport const ORB_WRAPPERS = [\n  \"none\",\n  \"glass\",\n  \"ring\",\n  \"dotted\",\n  \"ticks\",\n  \"reticle\",\n  \"grid\",\n  \"halftone\",\n  \"scanlines\",\n] as const\n\nexport type OrbWrapper = (typeof ORB_WRAPPERS)[number]\n\n/*\n  Keyframes for the animated wrappers, shipped inside the component so an orb\n  stays a single self-contained file with nothing to add to a global\n  stylesheet. React 19 hoists a <style href precedence> into <head> and\n  de-duplicates it, so a page full of wrapped orbs emits this exactly once;\n  older React renders it inline, which is redundant but harmless.\n\n  Reduced motion parks all of it. The shader runtime already honours the same\n  preference for the orb itself (see the reduce-motion branch in the render\n  loop), and a ring that keeps spinning around a frozen orb would be the worse\n  half of the two still moving.\n*/\nconst WRAPPER_STYLE_HREF = \"orbkit-wrapper\"\nconst WRAPPER_CSS = `\n@keyframes orbkit-w-spin { to { transform: rotate(360deg); } }\n@keyframes orbkit-w-roll { from { transform: translateY(-110%); } to { transform: translateY(360%); } }\n@media (prefers-reduced-motion: reduce) {\n  .orbkit-w-anim { animation: none !important; }\n}\n`\n\ninterface WrapperSpec {\n  /**\n   * How far the canvas sits inside the box, in percent, leaving the\n   * decoration room. Applied as explicit width/height rather than as `inset`:\n   * a canvas is a REPLACED element, so an absolutely positioned one with\n   * `left` and `right` both set does not stretch between them — it keeps its\n   * intrinsic size and the over-constrained edge is dropped. The orb would\n   * then be drawn into a canvas the size of the page.\n   */\n  inset: number\n  /**\n   * Soft circular mask on the canvas. Only the wrappers that read as a\n   * CONTAINER set one — a bubble has to hold the orb, whereas a bezel sits\n   * beside it and clipping the halo there would just amputate the glow.\n   */\n  mask?: string\n  /** Cast by the assembly as a whole, on the outer box. */\n  shadow?: string\n\n  /** True when the spec uses one of the keyframes above. */\n  animated?: boolean\n  /** Painted beneath the canvas. */\n  under?: ReactNode\n  /** Painted over it. */\n  over?: ReactNode\n}\n\nconst DISC: CSSProperties = { borderRadius: \"50%\" }\n\n/** One absolutely-positioned decoration layer, filling the wrapper box. */\nfunction Layer({\n  inset = 0,\n  style,\n  className,\n}: {\n  inset?: number | string\n  style: CSSProperties\n  className?: string\n}) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={className}\n      style={{ position: \"absolute\", inset, pointerEvents: \"none\", ...style }}\n    />\n  )\n}\n\n/**\n * A free-floating highlight — glass's specular and its bounce. These do not go\n * through `Layer` because they are placed with `left`/`top`/`width`, and a\n * style object that sets those on top of `Layer`'s `inset` shorthand is mixing\n * shorthand and longhand for the same property: React warns about it, and the\n * result depends on key order rather than on anything you would want to rely\n * on.\n */\nfunction Highlight({ style }: { style: CSSProperties }) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      style={{\n        position: \"absolute\",\n        borderRadius: \"50%\",\n        pointerEvents: \"none\",\n        ...style,\n      }}\n    />\n  )\n}\n\n/**\n * The mask that makes a wrapper HOLD the orb: cuts the canvas back to the\n * bubble and stops a hairline short of the rim, so the orb never quite touches\n * the glass.\n *\n * The percentage has to be derived rather than written down. `closest-side`\n * measures the CANVAS, and a wrapper with a negative inset draws its canvas\n * LARGER than the bubble — at -7 the canvas is 114% of the box, so the rim\n * sits at 100/1.14 = 87.7% of the canvas's own radius, not at 100%.\n *\n * The gap is real pixels rather than a share of the size: it reads as the same\n * band at 120px and at 900px, which a percentage would not.\n */\nconst RIM_GAP_PX = 4\n\nfunction rimMask(inset: number): string {\n  const rim = (100 / (1 - (2 * inset) / 100)).toFixed(2)\n  // Feathered over the final pixel, so the cut is not a razor edge.\n  const solid = RIM_GAP_PX + 0.5\n  const clear = RIM_GAP_PX - 0.5\n  return `radial-gradient(circle closest-side, #000 calc(${rim}% - ${solid}px), rgba(0,0,0,0) calc(${rim}% - ${clear}px))`\n}\n\n/** Both spellings, since Safari still wants the prefix for mask-image. */\nfunction masked(image: string): CSSProperties {\n  return { WebkitMaskImage: image, maskImage: image }\n}\n\nconst svgLayer: CSSProperties = {\n  position: \"absolute\",\n  inset: 0,\n  width: \"100%\",\n  height: \"100%\",\n  pointerEvents: \"none\",\n  overflow: \"visible\",\n}\n\n/** Glass's overfill, shared by its inset and the mask derived from it. */\nconst GLASS_INSET = -4\n\nconst WRAPPER_SPECS: Record<Exclude<OrbWrapper, \"none\">, WrapperSpec> = {\n  /*\n    glass — a blown bubble with the orb suspended inside it.\n\n    Five layers in the order light actually arrives: the body brightening\n    toward the key light, the Fresnel ring where a sphere's edge turns almost\n    edge-on and reflects nearly everything, the rim itself, the window\n    reflection, and the bounce coming back up off whatever the bubble is\n    sitting on. All of it is white and black rather than `currentColor` —\n    glass has no colour of its own, only the light it moves around.\n  */\n  glass: {\n    /*\n      Negative on purpose. An orb's shader does not necessarily paint to the\n      edge of its canvas — most draw a sphere with transparent margin around\n      it — so a canvas sized to the bubble leaves a dead ring between the orb\n      and the rim, which is not what a thing suspended in glass looks like.\n      Oversizing the canvas by 14% pushes the sphere out to the rim, and\n      `rimMask` cuts whatever overflows — a few pixels short of the glass, so\n      the orb sits just inside it rather than welded to it. Orbs that already fill\n      their canvas lose a few percent off the limb, which is the same crop the\n      reference bubble makes.\n    */\n    inset: GLASS_INSET,\n    mask: rimMask(GLASS_INSET),\n    shadow: \"0 24px 48px -26px rgba(0,0,0,0.55)\",\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(ellipse 80% 70% at 28% 20%, rgba(255,255,255,0.16), rgba(255,255,255,0.03) 45%, rgba(255,255,255,0) 72%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(255,255,255,0) 0%, rgba(255,255,255,0.0) 55%, rgba(255,255,255,0.05) 99.5%, rgba(255,255,255,0) 100%)\",\n            overflow: \"hidden\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow: \"3px 6px 10px #ffffff20 inset\",\n          }}\n        />\n        {/*\n          The shell's own darkening, just inside the rim. Invisible on a dark\n          page — it is black over black — and doing all the work on a light\n          one, where the white highlights below have nothing to stand out\n          against and the bubble would otherwise read as a bare drop shadow.\n        */}\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(0,0,0,0) 78%, rgba(0,0,0,0.05) 93%, rgba(0,0,0,0.02) 100%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow:\n              \"inset 0 6px 12px -7px rgba(255,255,255,0.05), inset 0 -9px 16px -9px rgba(255,255,255,0.1), 0 0 0 1px rgba(0,0,0,0.07)\",\n          }}\n        />\n        <Highlight\n          style={{\n            left: \"15%\",\n            top: \"10%\",\n            width: \"38%\",\n            height: \"22%\",\n            transform: \"rotate(-25deg)\",\n            background:\n              \"radial-gradient(closest-side, rgba(255,255,255,0.9), rgba(255,255,255,0.3) 55%, rgba(255,255,255,0) 100%)\",\n            filter: \"blur(10px)\",\n          }}\n        />\n      </>\n    ),\n  },\n\n  /* ring — two hairlines and nothing else. The restrained one. */\n  ring: {\n    inset: 9,\n    over: (\n      <>\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.22 }}\n        />\n        <Layer\n          inset=\"5%\"\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.1 }}\n        />\n      </>\n    ),\n  },\n\n  /*\n    dotted — evenly spaced dots around the circumference, turning slowly.\n\n    Drawn as one dashed circle with round caps and a near-zero dash length, so\n    each dash collapses to a dot. `pathLength=\"64\"` renormalizes the path to 64\n    units first, which is what makes the count exact: the dash period is\n    literally 1/64th of the circle, so the pattern closes on itself with no\n    seam where the last gap would otherwise be short.\n  */\n  dotted: {\n    inset: 10,\n    animated: true,\n    over: (\n      <svg\n        aria-hidden=\"true\"\n        viewBox=\"0 0 100 100\"\n        className=\"orbkit-w-anim\"\n        style={{ ...svgLayer, animation: \"orbkit-w-spin 48s linear infinite\" }}\n      >\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"47\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.7\"\n          strokeLinecap=\"round\"\n          pathLength={64}\n          strokeDasharray=\"0.0001 0.9999\"\n          opacity={0.45}\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    ticks — an instrument bezel: a fine minor scale every 6 degrees with a\n    longer major tick every 30. Both are one repeating conic gradient masked\n    down to an annulus, so the tick count is set by the gradient's period and\n    the tick LENGTH by how far in the mask reaches.\n  */\n  ticks: {\n    inset: 12,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.32,\n            background:\n              \"repeating-conic-gradient(from -0.5deg, transparent 0deg 0.2deg, currentColor 0.4deg 0.6deg, transparent 0.8deg 6deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 88%, #000 90%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.6,\n            background:\n              \"repeating-conic-gradient(from -0.75deg, transparent 0deg 0.25deg, currentColor 0.5deg 1deg, transparent 1.25deg 30deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 80%, #000 82%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.12 }}\n        />\n      </>\n    ),\n  },\n\n  /* reticle — viewfinder furniture: corner brackets, cardinal ticks, a track. */\n  reticle: {\n    inset: 13,\n    over: (\n      <svg aria-hidden=\"true\" viewBox=\"0 0 100 100\" style={svgLayer}>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" opacity=\"0.5\">\n          <path d=\"M1 13 L1 1 L13 1\" />\n          <path d=\"M87 1 L99 1 L99 13\" />\n          <path d=\"M99 87 L99 99 L87 99\" />\n          <path d=\"M13 99 L1 99 L1 87\" />\n        </g>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.38\">\n          <path d=\"M50 1 L50 9\" />\n          <path d=\"M50 91 L50 99\" />\n          <path d=\"M1 50 L9 50\" />\n          <path d=\"M91 50 L99 50\" />\n        </g>\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"46\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"0.7\"\n          opacity=\"0.22\"\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    grid — a graticule laid over the orb and masked back to the disc, so the\n    mesh appears to be etched on the glass in front of it rather than drawn on\n    the page behind. The lines are 1px whatever the size; the SPACING is a\n    percentage, so the cell count holds from a gallery thumbnail to a\n    full-bleed hero.\n  */\n  grid: {\n    inset: 8,\n    /*\n      The ruling sits UNDER the canvas: graph paper the orb rests on, not a\n      mesh laid over its face. Drawn on top it crosshatched the shader — the\n      one thing the wrapper is meant to frame. The ring stays over, since it\n      only ever meets the transparent margin at the canvas edge.\n    */\n    under: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.18,\n          backgroundImage:\n            \"repeating-linear-gradient(to right, currentColor 0 1px, transparent 1px 12.5%), repeating-linear-gradient(to bottom, currentColor 0 1px, transparent 1px 12.5%)\",\n          ...masked(\n            \"radial-gradient(circle closest-side, #000 86%, rgba(0,0,0,0) 99%)\"\n          ),\n        }}\n      />\n    ),\n    over: (\n      <Layer\n        style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.2 }}\n      />\n    ),\n  },\n\n  /*\n    halftone — a print screen over the outer band of the orb. The mask keeps\n    the middle clear, so the dots read as the image breaking up toward its\n    edge instead of a texture pasted across the whole face.\n  */\n  halftone: {\n    inset: 6,\n    over: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.5,\n          backgroundImage: \"radial-gradient(currentColor 22%, transparent 24%)\",\n          backgroundSize: \"7px 7px\",\n          ...masked(\n            \"radial-gradient(circle closest-side, transparent 40%, #000 80%, #000 94%, rgba(0,0,0,0) 100%)\"\n          ),\n        }}\n      />\n    ),\n  },\n\n  /*\n    scanlines — a phosphor tube. Black lines rather than `currentColor`,\n    because scanlines are the UNLIT gaps between rows and stay dark whatever\n    the page is; the slow bright band rolling down is the vertical hold\n    drifting, which is the part that reads as a CRT rather than as stripes.\n  */\n  scanlines: {\n    inset: 0,\n    animated: true,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            backgroundImage:\n              \"repeating-linear-gradient(to bottom, rgba(0,0,0,0.45) 0 1px, rgba(0,0,0,0) 1px 3px)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, #000 84%, rgba(0,0,0,0) 100%)\"\n            ),\n          }}\n        />\n        <span\n          aria-hidden=\"true\"\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            borderRadius: \"50%\",\n            overflow: \"hidden\",\n            pointerEvents: \"none\",\n          }}\n        >\n          <span\n            className=\"orbkit-w-anim\"\n            style={{\n              position: \"absolute\",\n              left: 0,\n              right: 0,\n              top: 0,\n              height: \"30%\",\n              background:\n                \"linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,0.07) 50%, rgba(255,255,255,0) 100%)\",\n              animation: \"orbkit-w-roll 7s linear infinite\",\n            }}\n          />\n        </span>\n        <Layer\n          style={{ ...DISC, boxShadow: \"inset 0 0 40px -8px rgba(0,0,0,0.5)\" }}\n        />\n      </>\n    ),\n  },\n}\n\nexport interface ShaderOrbProps {\n  /** The orb definition: shader + param schema + state presets. */\n  variant: OrbVariant\n  /** Drives the synthesized volume signals. Defaults to `\"idle\"`. */\n  state?: OrbState\n  /** Rendered size in CSS pixels. Ignored when `className` sizes the canvas. */\n  size?: number\n  /** Explicit param overrides. Any key present here wins over the state preset. */\n  params?: OrbParamValues\n  /** Explicit color overrides, as hex strings. */\n  colors?: OrbColorValues\n  /**\n   * Per-state parameter targets, overriding the variant's own. Merged KEY BY\n   * KEY over what the orb already defines, so `{ thinking: { churn: 1.62 } }`\n   * retouches one param of one state and leaves every other param — and the\n   * other two states — exactly as the orb ships them.\n   *\n   * This is the prop form of the variant's `statePresets`, so you can retune\n   * an orb's states from the outside without forking its file. Values still\n   * glide, so switching states cross-fades into your targets. An explicit\n   * `params` value outranks this, the same way it outranks the variant.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /** The colour counterpart of `statePresets`, merged the same key-by-key way. */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n  /**\n   * Per-state volume drive, the third member of the same family. Use it to\n   * give each state its own energy; use `volumes` below instead when you have\n   * a real signal to feed in, such as live mic level.\n   */\n  stateVolumes?: Partial<Record<OrbState, { input?: number; output?: number }>>\n  /**\n   * Overrides the synthesized volume signals for the active state. The engine\n   * normally derives these from `state` — a slow breath at idle, a restless\n   * wander while thinking, speech-shaped peaks while speaking — and most\n   * shaders read them as their reactivity. Setting either channel here pins\n   * it instead, which is how the playground lets you dial each state's drive\n   * independently. Omit a channel to keep its synthesized motion.\n   */\n  volumes?: { input?: number; output?: number }\n  /** Freeze the animation on the current frame. */\n  paused?: boolean\n  /**\n   * Stop rendering while the orb is scrolled out of view. Defaults to `true` —\n   * a page full of orbs would otherwise run a WebGL loop per card.\n   */\n  pauseOffscreen?: boolean\n  /** Device-pixel-ratio ceiling. Defaults to `2`. */\n  maxDpr?: number\n  /**\n   * Decoration drawn around the orb — a glass bubble, a dotted bezel, a\n   * viewfinder. Defaults to `\"none\"`, which renders the bare canvas exactly as\n   * it always has, with no extra element in the tree.\n   *\n   * A wrapper never changes the orb's footprint: `size` stays the outer\n   * diameter and the canvas is inset inside it, so switching one on reflows\n   * nothing around it.\n   */\n  wrapper?: OrbWrapper\n  /**\n   * The colour a wrapper draws its lines and dots in. Defaults to\n   * `currentColor` — the inherited text colour — which is what makes the\n   * bezels legible on a light and a dark page without being told which one\n   * they are on. `glass` ignores it: glass has no colour of its own.\n   */\n  wrapperColor?: string\n  /** Applied to the outermost element — the wrapper when there is one. */\n  className?: string\n  /** Merged onto the outermost element's style. */\n  style?: CSSProperties\n  /** Accessible label. When omitted the orb is hidden from assistive tech. */\n  ariaLabel?: string\n}\n\nexport function ShaderOrb({\n  variant,\n  state = \"idle\",\n  size,\n  params,\n  colors,\n  statePresets,\n  stateColors,\n  stateVolumes,\n  volumes,\n  paused = false,\n  pauseOffscreen = true,\n  maxDpr = 2,\n  wrapper = \"none\",\n  wrapperColor,\n  className,\n  style,\n  ariaLabel,\n}: ShaderOrbProps) {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const spec = wrapper === \"none\" ? undefined : WRAPPER_SPECS[wrapper]\n  const wrapped = spec !== undefined\n\n  // Live refs: the render loop reads these every frame, so changing a param\n  // never re-runs the GL setup effect (which would drop the context). Synced in\n  // an effect rather than during render — a ref write during render is unsafe\n  // under concurrent rendering, and the loop picks the new value up on the very\n  // next frame anyway.\n  /*\n    Whether the canvas has drawn a frame yet, tracked per variant because a\n    variant swap mounts a brand new canvas (see the `key` below).\n\n    A mounted-but-never-drawn canvas is at the browser's mercy: rather than\n    the transparent rectangle you would expect, a page that mounts a dozen at\n    once gets white boxes — and in some browsers a broken-image placeholder —\n    for as long as the compositor has nothing to raster. That window is not\n    small here: every orb compiles a full fragment shader synchronously in its\n    own mount effect, so on the gallery grid the first canvases sit empty\n    while the last ones are still compiling. Holding each canvas invisible\n    until its own first frame lands is what makes the grid fade in cleanly\n    instead of flashing. One state change per orb, once, on mount.\n  */\n  const [paintedKey, setPaintedKey] = useState<string | null>(null)\n  const painted = paintedKey === variant.key\n\n  const stateRef = useRef<OrbState>(state)\n  const paramsRef = useRef<OrbParamValues | undefined>(params)\n  const colorsRef = useRef<OrbColorValues | undefined>(colors)\n  const statePresetsRef = useRef(statePresets)\n  const stateColorsRef = useRef(stateColors)\n  const stateVolumesRef = useRef(stateVolumes)\n  const volumesRef = useRef(volumes)\n  const pausedRef = useRef(paused)\n\n  useEffect(() => {\n    stateRef.current = state\n    paramsRef.current = params\n    colorsRef.current = colors\n    statePresetsRef.current = statePresets\n    stateColorsRef.current = stateColors\n    stateVolumesRef.current = stateVolumes\n    volumesRef.current = volumes\n    pausedRef.current = paused\n  }, [\n    state,\n    params,\n    colors,\n    statePresets,\n    stateColors,\n    stateVolumes,\n    volumes,\n    paused,\n  ])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    const gl = canvas.getContext(\"webgl\", {\n      alpha: true,\n      // No MSAA: the geometry is a single full-screen triangle, so there are no\n      // primitive edges to antialias — softness comes from the shaders. Leaving\n      // it on costs the multisample buffers plus a resolve every frame.\n      antialias: false,\n      premultipliedAlpha: true,\n    })\n    if (!gl) return\n\n    const loseExt = gl.getExtension(\"WEBGL_lose_context\")\n\n    /*\n      A \"generation\" is everything tied to a live context: program, buffers,\n      observers, render loop. Browsers cap live WebGL contexts per page and\n      evict the oldest past the cap, and an evicted orb's canvas stays blank\n      forever unless the app rebuilds — so generations tear down and rebuild on\n      the lost/restored events instead of assuming the context is immortal.\n    */\n    let announcedPaint = false\n\n    const startGeneration = (): (() => void) => {\n      if (gl.isContextLost()) return () => {}\n      // Every generation announces its own first frame: a context that was\n      // lost and restored has an empty drawing buffer and is hidden again\n      // (below), so it has to earn its reveal back.\n      announcedPaint = false\n\n      const vs = compile(gl, gl.VERTEX_SHADER, VERT)\n      const fs = compile(\n        gl,\n        gl.FRAGMENT_SHADER,\n        ORB_GLSL_HELPERS + paramUniformDecls(variant) + variant.frag\n      )\n      const releaseShaders = () => {\n        if (vs) gl.deleteShader(vs)\n        if (fs) gl.deleteShader(fs)\n      }\n      if (!vs || !fs) return releaseShaders\n\n      const prog = gl.createProgram()\n      if (!prog) return releaseShaders\n      gl.attachShader(prog, vs)\n      gl.attachShader(prog, fs)\n      gl.linkProgram(prog)\n      if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n        console.error(\n          \"[orbkit] program link error:\",\n          gl.getProgramInfoLog(prog)\n        )\n        gl.deleteProgram(prog)\n        return releaseShaders\n      }\n      gl.useProgram(prog)\n\n      const buf = gl.createBuffer()\n      gl.bindBuffer(gl.ARRAY_BUFFER, buf)\n      gl.bufferData(\n        gl.ARRAY_BUFFER,\n        new Float32Array([-1, -1, 3, -1, -1, 3]),\n        gl.STATIC_DRAW\n      )\n      const aPos = gl.getAttribLocation(prog, \"aPos\")\n      gl.enableVertexAttribArray(aPos)\n      gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0)\n\n      gl.enable(gl.BLEND)\n      gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n\n      const uRes = gl.getUniformLocation(prog, \"uRes\")\n      const uTime = gl.getUniformLocation(prog, \"uTime\")\n      const uAnim = gl.getUniformLocation(prog, \"uAnim\")\n      const uInput = gl.getUniformLocation(prog, \"uInput\")\n      const uOutput = gl.getUniformLocation(prog, \"uOutput\")\n\n      const paramLocs = variant.params.map((p) => ({\n        def: p,\n        loc: gl.getUniformLocation(prog, `uP_${p.key}`),\n      }))\n      const colorLocs = variant.colors.map((c) => ({\n        def: c,\n        loc: gl.getUniformLocation(prog, `uC_${c.key}`),\n      }))\n\n      /* --- sizing: track the element box, not a one-shot measurement ------- */\n      // Backing-store scale, stepped down by the adaptive-resolution logic in\n      // the loop when the GPU can't hold frame rate. CSS size never changes —\n      // the browser upscales, which these soft shaders absorb gracefully.\n      let resScale = 1\n      const resize = () => {\n        const dpr = Math.min(window.devicePixelRatio || 1, maxDpr) * resScale\n        const w = Math.max(1, Math.round(canvas.clientWidth * dpr))\n        const h = Math.max(1, Math.round(canvas.clientHeight * dpr))\n        if (canvas.width !== w || canvas.height !== h) {\n          canvas.width = w\n          canvas.height = h\n          gl.viewport(0, 0, w, h)\n        }\n        /*\n          Uploaded UNCONDITIONALLY, outside the size guard. A rebuilt\n          generation (React strict-mode remount, a restored context) links a\n          fresh program whose uRes starts at zero — and the canvas usually\n          already holds the right backing size, so an upload gated behind\n          the resize never ran. With uRes = 0, orbUV() divides by zero and\n          every fragment lands transparent: a healthy context, a bound\n          program, and a permanently blank orb.\n        */\n        gl.uniform2f(uRes, w, h)\n      }\n      resize()\n\n      const resizeObserver =\n        typeof ResizeObserver !== \"undefined\"\n          ? new ResizeObserver(resize)\n          : null\n      resizeObserver?.observe(canvas)\n\n      /* --- visibility: don't burn a render loop on an offscreen orb -------- */\n      let visible = !pauseOffscreen\n      const intersectionObserver =\n        pauseOffscreen && typeof IntersectionObserver !== \"undefined\"\n          ? new IntersectionObserver(\n              (entries) => {\n                visible = Boolean(entries[0]?.isIntersecting)\n                if (visible) {\n                  last = performance.now() / 1000\n                }\n              },\n              { rootMargin: \"150px 0px\", threshold: 0 }\n            )\n          : null\n      if (intersectionObserver) {\n        intersectionObserver.observe(canvas)\n      } else {\n        visible = true\n      }\n\n      const reduceMotion =\n        typeof window.matchMedia === \"function\" &&\n        window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n\n      /* --- driver state ---------------------------------------------------- */\n      let tSec = 0\n      // random phase so two orbs on the same page never look synchronized\n      let anim = Math.random() * 100\n      let speed = 0.1\n      const cur = { in: 0, out: 0.3 }\n      const presets = variant.statePresets\n      const paramCur: Record<string, number> = {}\n      const paramVel: Record<string, number> = {}\n      const paramClocks: Record<string, number> = {}\n      const colorCur: Record<string, [number, number, number]> = {}\n      const colorVel: Record<string, [number, number, number]> = {}\n      let speedVel = 0\n      const [initialIn, initialOut] = targetVolumes(stateRef.current, 0)\n      cur.in = initialIn\n      cur.out = initialOut\n      let last = performance.now() / 1000\n      let raf = 0\n      // smoothed frame time for the adaptive-resolution check\n      let frameEma = 1 / 60\n\n      const uploadAndDraw = (dt: number, snap = false) => {\n        // Synthesized from the state, unless a channel is pinned via\n        // `volumes`. Pinned values still glide on the same easing, so dialing\n        // one in the playground cross-fades rather than jumping.\n        const [tin, tout] = targetVolumes(stateRef.current, tSec)\n        // Same order as params and colours: direct prop, then the per-state\n        // map, then the engine's own synthesis.\n        const liveVolumes = volumesRef.current\n        const stateVolume = stateVolumesRef.current?.[stateRef.current]\n        const targetIn = liveVolumes?.input ?? stateVolume?.input ?? tin\n        const targetOut = liveVolumes?.output ?? stateVolume?.output ?? tout\n        const kVol = 1 - Math.exp(-dt * 12)\n        cur.in += (targetIn - cur.in) * kVol\n        cur.out += (targetOut - cur.out) * kVol\n\n        /*\n          Flow speed follows the output volume. It multiplies every integrated\n          clock's increment, so it is a RATE: easing it quickly makes the orb\n          visibly lurch — a state change would spin the orb up hard before the\n          params had finished gliding.\n\n          It is therefore eased on the same constant as the params below, so a\n          state change ramps its motion over the same half second that its look\n          takes to cross-fade. The steady-state values are unchanged, so a\n          speaking orb still flows faster than an idle one; only the transition\n          into that rate is gradual.\n        */\n        const targetSpeed = 0.1 + (1 - Math.pow(cur.out - 1, 2)) * 0.9\n        if (snap) {\n          speed = targetSpeed\n          speedVel = 0\n        } else {\n          springStep(speed, speedVel, targetSpeed, dt, PARAM_EASE)\n          speed = springOut.x\n          speedVel = springOut.v\n        }\n        anim += dt * speed\n\n        gl.uniform1f(uTime, tSec * 0.5)\n        gl.uniform1f(uAnim, anim)\n        gl.uniform1f(uInput, cur.in)\n        gl.uniform1f(uOutput, cur.out)\n\n        // Resolution order per param: explicit `params` → `statePresets`\n        // prop → the variant's own preset → schema default. The two middle\n        // steps are per-key, so overriding one param of one state leaves the\n        // rest of that state alone. Values glide rather than snap.\n        const liveParams = paramsRef.current\n        const statePreset = presets?.[stateRef.current]\n        const overridePreset = statePresetsRef.current?.[stateRef.current]\n\n        for (const { def, loc } of paramLocs) {\n          const explicit = liveParams?.[def.key]\n          const target =\n            typeof explicit === \"number\"\n              ? explicit\n              : (overridePreset?.[def.key] ??\n                statePreset?.[def.key] ??\n                def.default)\n          const curVal = paramCur[def.key] ?? target\n          let next: number\n          if (snap) {\n            next = target\n            paramVel[def.key] = 0\n          } else {\n            springStep(curVal, paramVel[def.key] ?? 0, target, dt, PARAM_EASE)\n            next = springOut.x\n            paramVel[def.key] = springOut.v\n          }\n          paramCur[def.key] = next\n\n          if (def.integrate) {\n            const clock =\n              (paramClocks[def.key] ??\n                (paramClocks[def.key] = Math.random() * 100)) +\n              dt * speed * next\n            paramClocks[def.key] = clock\n            gl.uniform1f(loc, clock)\n          } else {\n            gl.uniform1f(loc, next)\n          }\n        }\n\n        // Same resolution order and same easing as params, so a state change\n        // cross-fades the palette instead of cutting to it.\n        const liveColors = colorsRef.current\n        const stateColor = variant.stateColors?.[stateRef.current]\n        const overrideColor = stateColorsRef.current?.[stateRef.current]\n        for (const { def, loc } of colorLocs) {\n          const target = hexToRgb(\n            liveColors?.[def.key] ??\n              overrideColor?.[def.key] ??\n              stateColor?.[def.key] ??\n              def.default\n          )\n          const curCol = (colorCur[def.key] ??= [...target] as [\n            number,\n            number,\n            number,\n          ])\n          const velCol = (colorVel[def.key] ??= [0, 0, 0])\n          for (let i = 0; i < 3; i++) {\n            if (snap) {\n              curCol[i] = target[i]\n              velCol[i] = 0\n            } else {\n              springStep(curCol[i], velCol[i], target[i], dt, PARAM_EASE)\n              curCol[i] = springOut.x\n              velCol[i] = springOut.v\n            }\n          }\n          gl.uniform3f(loc, curCol[0], curCol[1], curCol[2])\n        }\n\n        gl.clearColor(0, 0, 0, 0)\n        gl.clear(gl.COLOR_BUFFER_BIT)\n        gl.drawArrays(gl.TRIANGLES, 0, 3)\n        // Deferred a microtask: the first of these draws runs synchronously\n        // inside this effect, and a sync setState there trips the compiler\n        // lint. A microtask still resolves before the browser paints, so the\n        // reveal is not delayed by a frame.\n        if (!announcedPaint) {\n          announcedPaint = true\n          queueMicrotask(() => {\n            /*\n              Re-check: the context can be evicted between this draw and the\n              microtask, and mounting one more orb anywhere on the page is\n              enough to do it — opening the details drawer over a full gallery\n              is exactly that. Revealing on the strength of a frame that has\n              already been thrown away puts a dead canvas on screen, which is\n              what the browser draws its broken-canvas placeholder over. The\n              generation that follows the restore announces again.\n            */\n            if (gl.isContextLost()) return\n            setPaintedKey(variant.key)\n          })\n        }\n      }\n\n      const releaseGL = () => {\n        resizeObserver?.disconnect()\n        intersectionObserver?.disconnect()\n        gl.deleteProgram(prog)\n        gl.deleteShader(vs)\n        gl.deleteShader(fs)\n        gl.deleteBuffer(buf)\n      }\n\n      if (reduceMotion) {\n        // One representative frame, then stop — snapped straight onto the\n        // state's targets, since a spring would only be part-way there.\n        tSec = 1\n        uploadAndDraw(1, true)\n        return releaseGL\n      }\n\n      const loop = () => {\n        raf = requestAnimationFrame(loop)\n        const now = performance.now() / 1000\n        const dt = Math.min(now - last, 0.05)\n        last = now\n        if (!visible || pausedRef.current) return\n        tSec += dt\n\n        /*\n          Adaptive resolution. When the smoothed frame time sits above ~30fps,\n          the GPU is drowning in fragment work (these shaders are pure fill\n          cost), so step the backing store down 20% and re-measure. Steps only\n          go down — never back up — so the resolution can't oscillate. The\n          warm-up guard keeps page-load jank (hydration, first compiles) from\n          triggering a downgrade the GPU never asked for.\n        */\n        /*\n          Only unstalled frames are evidence about GPU fill cost. `dt` above is\n          clamped at 0.05, so a frame that hits the clamp is the main thread\n          having been blocked — a slider drag re-rendering React, a GC pause, a\n          tab regaining focus — and feeding those in made UI jank look\n          identical to a drowning GPU.\n        */\n        if (dt < 0.05) frameEma += (dt - frameEma) * 0.08\n\n        if (tSec > 1.5 && frameEma > 1 / 34 && resScale > 0.5) {\n          resScale = Math.max(0.5, resScale * 0.8)\n          frameEma = 1 / 60 // require fresh evidence before the next step\n          resize()\n        } else if (tSec > 1.5 && frameEma < 1 / 55 && resScale < 1) {\n          /*\n            And step back up once frames are comfortably fast again. This used\n            to be one-way, on the reasoning that it could not then oscillate —\n            but that also meant one transient stall permanently halved the\n            orb's resolution, and at half resolution a high-frequency shader\n            aliases into shimmer that reads as the shader itself misbehaving.\n            The gap between the two thresholds (29ms down, 18ms up) is the\n            hysteresis that stops it hunting.\n          */\n          resScale = Math.min(1, resScale / 0.8)\n          frameEma = 1 / 60\n          resize()\n        }\n\n        uploadAndDraw(dt)\n      }\n      /*\n        First frame synchronously, before entering the rAF loop. rAF does not\n        run at all in hidden documents (background tabs, embedded previews),\n        so a freshly mounted orb would otherwise sit fully transparent until\n        the page next becomes visible — a grid of mounted, healthy, blank\n        canvases. The sync frame guarantees every mount paints: background\n        documents get a static frame, visible ones start animating over it.\n        dt = 1 lands the param glide on its targets, as in the reduce-motion\n        frame above.\n      */\n      uploadAndDraw(1)\n      loop()\n\n      return () => {\n        cancelAnimationFrame(raf)\n        releaseGL()\n      }\n    }\n\n    /*\n      Wire the canvas's lifecycle controller. The listeners are attached ONCE\n      per canvas element and never removed, deliberately: the lost event must\n      be canceled even while no orb is mounted on the canvas — an uncanceled\n      webglcontextlost marks the context permanently unrestorable, and the\n      router can show this exact canvas again later. Whether a loss leads to\n      a revival is decided by `desired`, not by listener presence.\n    */\n    /*\n      A canvas whose context has gone is not simply blank: Chrome paints its\n      broken-image placeholder over the element's whole box — the white square\n      you see on a reloaded grid. Hide the canvas the moment the context is\n      lost, and let the generation that follows a restore reveal it again.\n    */\n    const hideNow = () => {\n      /*\n        Both, deliberately. The style write lands in this tick — the browser\n        paints its placeholder over a dead canvas immediately, and a busy main\n        thread can hold a React update for several frames. The state change is\n        what keeps React's own view in sync, so the reveal that follows a\n        restore clears the inline value again rather than fighting it.\n      */\n      canvas.style.opacity = \"0\"\n      setPaintedKey(null)\n    }\n\n    const onContextLostHide = () => hideNow()\n    canvas.addEventListener(\"webglcontextlost\", onContextLostHide)\n\n    /*\n      Hand the context back before the next document asks for one.\n\n      A hard reload never runs this effect's cleanup — the document is\n      discarded whole — so the outgoing page's contexts are still alive while\n      the incoming page allocates its own. On a grid of orbs that puts the\n      live count past the browser's ~16 cap, and the ones it evicts are\n      exactly the canvases that come back as placeholders until the restore\n      path catches them. `persisted` is a bfcache suspend, where the page is\n      shown again untouched and must keep everything it holds.\n    */\n    const onPageHide = (event: PageTransitionEvent) => {\n      if (event.persisted) return\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Already released — nothing to hand back.\n      }\n    }\n    window.addEventListener(\"pagehide\", onPageHide)\n\n    let ctl = canvasControllers.get(canvas)\n    if (!ctl) {\n      const created: CanvasContextController = {\n        desired: false,\n        start: null,\n        stopGen: null,\n      }\n      canvas.addEventListener(\"webglcontextlost\", (event) => {\n        event.preventDefault() // always cancel — keeps the context restorable\n        created.stopGen?.()\n        created.stopGen = null\n        if (created.desired) {\n          /*\n            Ask for the context back — but in a LATER task. The browser only\n            marks a loss as restorable once the lost event's dispatch has\n            completed and it has seen the canceled flag, so a restoreContext()\n            issued during dispatch (or before it, as the mount path may) is\n            silently refused. This is the path a synchronous cleanup+setup\n            pair hits — React re-running the effect on the same canvas loses\n            the context and wants it right back. For losses we didn't cause\n            (eviction, GPU reset) the call may refuse; the canceled event then\n            lets the browser restore on its own schedule.\n          */\n          setTimeout(() => {\n            if (!created.desired) return\n            try {\n              loseExt?.restoreContext()\n            } catch {\n              // Natural loss — restoration is the browser's call now.\n            }\n          }, 0)\n        }\n      })\n      canvas.addEventListener(\"webglcontextrestored\", () => {\n        if (created.desired && created.start) {\n          created.stopGen = created.start()\n        }\n      })\n      canvasControllers.set(canvas, created)\n      ctl = created\n    }\n    const controller = ctl\n\n    controller.desired = true\n    controller.start = startGeneration\n    if (gl.isContextLost()) {\n      // A previous run on this canvas released the context (effect re-run, or\n      // the router re-showing a kept-alive page). If the lost event already\n      // dispatched this request is honored now; if it is still queued, the\n      // lost handler above re-requests it on dispatch.\n      try {\n        loseExt?.restoreContext()\n      } catch {\n        // No restore path — the orb stays blank rather than throwing.\n      }\n    } else {\n      controller.stopGen = startGeneration()\n    }\n\n    return () => {\n      /*\n        Hide BEFORE tearing the context down.\n\n        This cleanup releases the context deliberately, and the lost event it\n        provokes is dispatched asynchronously — by which point the listener\n        below is unhooked and the replacement effect has not drawn yet. That\n        leaves a revealed canvas with a dead context, which is precisely what\n        the browser paints its broken-canvas placeholder over. The window is\n        not rare: any prop change in this effect's deps re-runs it, so it hits\n        every time the drawer switches preview example (maxDpr differs on the\n        layout one) or a wrapper is toggled.\n      */\n      hideNow()\n      canvas.removeEventListener(\"webglcontextlost\", onContextLostHide)\n      window.removeEventListener(\"pagehide\", onPageHide)\n      controller.desired = false\n      controller.start = null\n      controller.stopGen?.()\n      controller.stopGen = null\n      /*\n        Release the context NOW instead of when the canvas is garbage\n        collected. Browsers cap live WebGL contexts per page (~8–16) and evict\n        the oldest when the cap is hit — client-side navigation that unmounts\n        and remounts a page of orbs otherwise piles up zombie contexts until\n        freshly mounted orbs get evicted and render blank.\n      */\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Context already lost — nothing to release.\n      }\n    }\n    /*\n      `wrapped` is in here because turning a wrapper on or off moves the canvas\n      from being this component's root element to being a child of the wrapper\n      div — React drops the old element and mounts a new one, and the GL\n      context, its observers and its render loop all belong to the old one. Any\n      other prop leaves the element alone, INCLUDING a swap between two\n      wrappers: the canvas keeps its slot among the decoration layers, so\n      glass -> ring reuses the context instead of rebuilding it.\n    */\n  }, [variant, pauseOffscreen, maxDpr, wrapped])\n\n  const sizeStyle: CSSProperties =\n    size === undefined ? {} : { width: size, height: size }\n\n  /*\n    Spread ahead of the caller's `style`, so an orb that wants to own its own\n    opacity still can — it simply opts out of the reveal.\n\n    A hard flip, deliberately: no transition, no fade. A hidden document\n    (background tab, embedded preview) does not advance CSS transitions, so a\n    faded reveal left orbs pinned at zero in exactly the case the synchronous\n    first frame above exists to serve — mounted, healthy, and invisible. The\n    cut is not a pop either way, since it happens on the frame the orb first\n    has something to show.\n  */\n  const revealStyle: CSSProperties = painted ? {} : { opacity: 0 }\n\n  const canvas = (\n    <canvas\n      // A lost WebGL context can't be reused, so each variant gets a fresh canvas.\n      key={variant.key}\n      ref={canvasRef}\n      className={spec ? undefined : className}\n      style={\n        spec\n          ? {\n              display: \"block\",\n              position: \"absolute\",\n              left: `${spec.inset}%`,\n              top: `${spec.inset}%`,\n              width: `${100 - 2 * spec.inset}%`,\n              height: `${100 - 2 * spec.inset}%`,\n              ...revealStyle,\n              ...(spec.mask ? masked(spec.mask) : {}),\n            }\n          : { display: \"block\", ...sizeStyle, ...revealStyle, ...style }\n      }\n      role={!spec && ariaLabel ? \"img\" : undefined}\n      aria-label={spec ? undefined : ariaLabel}\n      aria-hidden={!spec && ariaLabel ? undefined : true}\n    />\n  )\n\n  if (!spec) return canvas\n\n  /*\n    Wrapped: the box becomes the orb's footprint and the canvas is absolutely\n    positioned inside it. `under`, the canvas and `over` are all positioned\n    with an auto z-index, so they paint in DOM order — decoration behind the\n    orb, then the orb, then decoration in front of it.\n\n    `aspectRatio` is the fallback for the sizeless case: `size` is optional\n    (callers may size the orb with a class instead), and an absolutely\n    positioned canvas contributes nothing to its parent's height, so without\n    it a class that only sets a width would collapse the box to zero.\n  */\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"relative\",\n        aspectRatio: \"1 / 1\",\n        ...(spec.shadow ? { borderRadius: \"50%\", boxShadow: spec.shadow } : {}),\n        ...sizeStyle,\n        ...(wrapperColor ? { color: wrapperColor } : {}),\n        ...style,\n      }}\n      role={ariaLabel ? \"img\" : undefined}\n      aria-label={ariaLabel}\n      aria-hidden={ariaLabel ? undefined : true}\n    >\n      {spec.animated ? (\n        <style\n          href={WRAPPER_STYLE_HREF}\n          precedence=\"default\"\n          dangerouslySetInnerHTML={{ __html: WRAPPER_CSS }}\n        />\n      ) : null}\n      {spec.under}\n      {canvas}\n      {spec.over}\n    </div>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE",
          "target": "@components/voice-agents/orbkit/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 zzzzshawn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/orbkit/SOURCE.json",
          "target": "@components/voice-agents/orbkit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"OrbKit\",\n  \"repository\": \"https://github.com/zzzzshawn/orbkit\",\n  \"commit\": \"35e42484560fd35e8502703ba58fa99541d8c686\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 zzzzshawn\",\n  \"core\": \"components/voice-agents/orbkit/core.tsx\",\n  \"credits\": \"components/voice-agents/orbkit/CREDITS.md\",\n  \"shaderLicense\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\",\n  \"changes\": [\n    \"Moved the dependency-free OrbKit runtime and selected variants into the Agents Kit voice collection.\",\n    \"Mapped variant imports to the local shared runtime.\",\n    \"Kept the upstream reduced-motion, offscreen pause, DPR cap, context recovery, and cleanup behavior.\"\n  ],\n  \"exclusions\": [\n    {\n      \"name\": \"shdr-19\",\n      \"reason\": \"Non-commercial XorDev shader; excluded from this distributable MIT collection.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    },\n    {\n      \"name\": \"XorDev shader ports\",\n      \"reason\": \"All variants listed under Shaders by XorDev in CREDITS.md are non-commercial and excluded.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    }\n  ],\n  \"components\": [\n    {\n      \"name\": \"shdr-11\",\n      \"path\": \"shdr-11.tsx\",\n      \"title\": \"Hydrogen\"\n    },\n    {\n      \"name\": \"shdr-13\",\n      \"path\": \"shdr-13.tsx\",\n      \"title\": \"Ion\"\n    },\n    {\n      \"name\": \"shdr-14\",\n      \"path\": \"shdr-14.tsx\",\n      \"title\": \"Dither\"\n    },\n    {\n      \"name\": \"shdr-21\",\n      \"path\": \"shdr-21.tsx\",\n      \"title\": \"Nimbus\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/CREDITS.md",
          "target": "@components/voice-agents/orbkit/CREDITS.md",
          "type": "registry:file",
          "content": "# Credits\n\nOrbkit ships two kinds of orb. Every file says which it is.\n\n## Shaders by XorDev\n\nThese 19 orbs are ported from golfed shaders by [XorDev](https://x.com/XorDev),\nused with his permission (agreed by direct message on 2026-09-06). Terms:\n**non-commercial use only, with attribution to XorDev**. Each file starts with\na notice that must stay with any copy, and the registry marks these items with\na `credit` field. See [LICENSE-SHADERS.md](LICENSE-SHADERS.md).\n\n| Orb     | Shader by | Original             |\n| ------- | --------- | -------------------- |\n| shdr-01 | XorDev    | https://x.com/XorDev |\n| shdr-02 | XorDev    | https://x.com/XorDev |\n| shdr-03 | XorDev    | https://x.com/XorDev |\n| shdr-04 | XorDev    | https://x.com/XorDev |\n| shdr-05 | XorDev    | https://x.com/XorDev |\n| shdr-06 | XorDev    | https://x.com/XorDev |\n| shdr-07 | XorDev    | https://x.com/XorDev |\n| shdr-08 | XorDev    | https://x.com/XorDev |\n| shdr-09 | XorDev    | https://x.com/XorDev |\n| shdr-10 | XorDev    | https://x.com/XorDev |\n| shdr-15 | XorDev    | https://x.com/XorDev |\n| shdr-18 | XorDev    | https://x.com/XorDev |\n| shdr-19 | XorDev    | https://x.com/XorDev |\n| shdr-20 | XorDev    | https://x.com/XorDev |\n| shdr-22 | XorDev    | https://x.com/XorDev |\n| shdr-25 | XorDev    | https://x.com/XorDev |\n| shdr-26 | XorDev    | https://x.com/XorDev |\n| shdr-28 | XorDev    | https://x.com/XorDev |\n| shdr-31 | XorDev    | https://x.com/XorDev |\n\nReplace a profile link with the specific post once it is known.\n\n## Original orbs\n\nThese 14 orbs are Orbkit's own work and are MIT-licensed, like the runtime:\nshdr-11, shdr-12, shdr-13, shdr-14, shdr-16, shdr-17, shdr-21, shdr-23, shdr-24, shdr-27, shdr-29, shdr-30, shdr-32, shdr-33.\n\n## Adding shaders\n\nAsk the original author before porting anything that is not your own. XorDev\nasked to be consulted before any more of his work is included.\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "target": "@components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "type": "registry:file",
          "content": "# Licence for the ported shaders\n\nThe orb files listed under \"Shaders by XorDev\" in [CREDITS.md](CREDITS.md) are\nderived from shaders by XorDev (https://x.com/XorDev) and are used with the\nauthor's permission on these terms:\n\n1. Non-commercial use only.\n2. Attribution to XorDev must be kept with every copy, including the notice at\n   the top of each file.\n3. Any further use of XorDev's work requires asking the author first.\n\nEverything else in this repository, including the runtime\n(`orbkit-core.tsx`), the site, the build scripts, and the original orbs, is\nlicensed under the MIT licence in [LICENSE](LICENSE).\n"
        }
      ],
      "categories": [
        "OrbKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "orbkit-shdr-14",
      "type": "registry:block",
      "title": "Orbkit Shdr 14",
      "description": "Dither",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/orbkit/shdr-14.tsx",
          "target": "@components/voice-agents/orbkit/shdr-14.tsx",
          "type": "registry:component",
          "content": "/*\n * Deliberately not a `\"use client\"` module — see the note in `shdr-11.tsx`.\n *\n * Note for editors: the shader lives in a template literal, so its comments\n * must not contain backticks.\n */\nimport { ShaderOrb, type OrbVariant, type ShaderOrbProps } from \"./core\"\n\n/* ----------------------------------------------------------------------------\n   SHDR-14 — demoscene sine-plasma on a rolling dome, quantized to chunky\n   two-tone pixels.\n\n   The one retro renderer in the family, and it animates like one: the\n   luminance is the CLASSIC demo plasma — three interfering sine waves —\n   evaluated on the sphere's rotating dome point so the wavefronts roll\n   around the ball, plus a ripple source that orbits the dome and pushes\n   expanding rings through the interference. A lambert term keeps the ball\n   solid and a fresnel rim edges it. All of it collapses into one luminance,\n   and an 8x8 ORDERED BAYER DITHER snaps that onto a short tone ladder\n   between two colours, ink and paper. At 2 tone steps it is the classic\n   1-bit look.\n\n   Construction notes:\n\n   - The Bayer matrix is generated PROCEDURALLY. GLSL ES 1.0 has no array\n     initializer lists and no bitwise operators, so the usual lookup-table\n     and bit-interleave constructions are both unavailable. The fract() form\n     below produces the exact 2x2 base matrix, and the recursion\n     M(2n) = M(n)/4 + M(2) builds 8x8 from it.\n   - The content is sampled at each CELL's centre, not per fragment, so the\n     dots are crisp squares — including the silhouette, which goes blocky at\n     the rim on purpose. Averaging per fragment would anti-alias the grid\n     away and leave gray mush.\n   - The dither threshold is per screen cell and static: ordered dither does\n     not crawl. All motion lives in the content underneath it.\n   - Clocks enter only as additive phase (plasma drift) or through cos/sin\n     (light orbit) — integrated clocks, phase-safe as everywhere here.\n   - Surface-lit and mask-bounded, so alpha IS coverage — premultiplied\n     output, as in shdr-28.\n---------------------------------------------------------------------------- */\n\nconst DITHER_FRAG = `\n// 2x2 Bayer base: floor/fract only. (0,0)=0, (1,0)=.5, (0,1)=.75, (1,1)=.25\n// — the 0,2,3,1 ordering over 4.\nfloat bayer2(vec2 a) {\n  a = floor(a);\n  return fract(a.x / 2.0 + a.y * a.y * 0.75);\n}\n\n// 8x8 by recursion: M8 = M2(a/4)/16 + M2(a/2)/4 + M2(a). No arrays, no\n// bitwise — neither exists in GLSL ES 1.0.\nfloat bayer8(vec2 a) {\n  return bayer2(a * 0.25) * 0.0625 + bayer2(a * 0.5) * 0.25 + bayer2(a);\n}\n\nvoid main() {\n  // Volume coupling: user input deepens the waves, agent output brightens\n  // the whole tone ladder — the dot field visibly blooms while it speaks.\n  float plasmaAmt = uP_plasma * (1.0 + 0.4 * uInput);\n  float gainNow = uP_gain * (0.85 + 0.5 * uOutput);\n\n  /*\n    Chunky pixel grid, RESOLUTION-RELATIVE: uP_cells is how many cells span\n    the canvas, so a 190px gallery card and a 420px playground orb show the\n    same composition — the same wave resolved by the same number of dots.\n    Sized in device pixels instead, small canvases collapse to a few dozen\n    blotches. All content below samples at the cell centre so every dot is\n    one flat square.\n  */\n  float cellPx = max(min(uRes.x, uRes.y) / max(uP_cells, 8.0), 1.0);\n  vec2 pix = floor(gl_FragCoord.xy / cellPx);\n  vec2 cellCentre = (pix + 0.5) * cellPx;\n\n  vec2 suv = (2.0 * cellCentre - uRes) / min(uRes.x, uRes.y);\n  vec2 uv = suv / uP_radius;\n  float r2 = dot(uv, uv);\n\n  // blocky silhouette — cut on the cell grid, deliberately not smoothed\n  float mask = 1.0 - step(1.0, r2);\n\n  float z = sqrt(max(1.0 - r2, 0.0));\n  vec3 n = vec3(uv, z);\n\n  /*\n    The plasma is evaluated in a ROTATING frame: the dome point spins about\n    Y on its own integrated clock, so the wavefronts roll around the ball\n    instead of sliding across a flat disc. The light stays screen-fixed —\n    the form shading holds still while the pattern travels over it.\n  */\n  float rot = uP_spin; // integrated clock\n  float cr = cos(rot);\n  float sr = sin(rot);\n  vec3 sp = vec3(n.x * cr - n.z * sr, n.y, n.x * sr + n.z * cr);\n\n  float t = uP_speed; // integrated clock\n\n  // the classic demoscene plasma: three interfering sine waves, each on its\n  // own direction and rate\n  float f = uP_scale;\n  float v = sin(sp.x * f * 3.1 + t)\n    + sin((sp.y * 0.85 + sp.z * 0.4) * f * 3.6 - t * 1.3)\n    + sin((sp.x + sp.y + sp.z) * f * 2.2 + t * 0.7);\n\n  // a ripple source orbiting the dome — expanding rings pushed through the\n  // interference; the clock enters only as additive phase\n  vec2 src = 0.55 * vec2(cos(t * 0.5), sin(t * 0.5));\n  v += sin(length(uv - src) * f * 5.0 - t * 2.2);\n  v *= 0.25; // four unit waves back to -1..1\n\n  float lambert = clamp(dot(n, normalize(vec3(-0.45, 0.55, 0.7))), 0.0, 1.0);\n  float fres = pow(1.0 - z, 2.0);\n\n  // waves modulated by the dome shading, so the ball stays a ball under\n  // the rolling pattern; everything collapses into one luminance\n  float lum = (0.5 + 0.5 * v * plasmaAmt) * (0.3 + uP_light * lambert)\n    + uP_rim * fres;\n  lum = pow(clamp(lum * gainNow, 0.0, 1.0), uP_contrast);\n\n  // ordered dither onto the tone ladder — levels 2 is the classic 1-bit\n  // look, higher values keep the grain but add mid-tones\n  float steps = max(uP_levels - 1.0, 1.0);\n  float q = clamp(floor(lum * steps + bayer8(pix)) / steps, 0.0, 1.0);\n\n  vec3 col = mix(uC_ink, uC_paper, q);\n\n  // Surface-lit orb bounded by a mask: alpha IS coverage, so premultiply —\n  // the opposite convention from the emissive orbs (see shdr-31).\n  float a = mask;\n  gl_FragColor = vec4(col * a, a);\n}\n`\n\nexport const shdr14Orb: OrbVariant = {\n  key: \"shdr-14\",\n  label: \"SHDR-14\",\n  note: \"a lit plasma dome quantized to chunky two-tone pixels\",\n  frag: DITHER_FRAG,\n  params: [\n    {\n      key: \"speed\",\n      label: \"Wave speed\",\n      min: 0.015,\n      max: 10,\n      step: 0.05,\n      default: 0.5,\n      integrate: true,\n    },\n    {\n      key: \"spin\",\n      label: \"Roll\",\n      min: 0,\n      max: 5,\n      step: 0.03,\n      default: 0.15,\n      integrate: true,\n    },\n    {\n      key: \"radius\",\n      label: \"Radius\",\n      min: 0.15,\n      max: 3,\n      step: 0.015,\n      default: 0.9,\n    },\n    {\n      key: \"cells\",\n      label: \"Grid cells\",\n      min: 32,\n      max: 320,\n      step: 2,\n      default: 140,\n    },\n    { key: \"levels\", label: \"Tone steps\", min: 2, max: 8, step: 1, default: 3 },\n    {\n      key: \"scale\",\n      label: \"Wave scale\",\n      min: 0.3,\n      max: 12,\n      step: 0.1,\n      default: 1.5,\n    },\n    {\n      key: \"plasma\",\n      label: \"Wave amount\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.9,\n    },\n    {\n      key: \"light\",\n      label: \"Key light\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.9,\n    },\n    {\n      key: \"rim\",\n      label: \"Rim light\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.35,\n    },\n    {\n      key: \"gain\",\n      label: \"Brightness\",\n      min: 0.05,\n      max: 5,\n      step: 0.05,\n      default: 1,\n    },\n    {\n      key: \"contrast\",\n      label: \"Contrast\",\n      min: 0.15,\n      max: 10,\n      step: 0.05,\n      default: 1.1,\n    },\n  ],\n  colors: [\n    { key: \"ink\", label: \"Ink\", default: \"#101426\" },\n    { key: \"paper\", label: \"Paper\", default: \"#cfe6ff\" },\n  ],\n  /*\n    Staged in the family language: thinking churns the plasma in place while\n    the light freezes, speaking sweeps the light fast and brightens the\n    ladder. `pixel` and `levels` never move between states — both quantize,\n    and a gliding quantizer pops instead of fading.\n  */\n  statePresets: {\n    // calm: waves rolling slowly, dome barely turning\n    idle: {\n      speed: 0.5,\n      spin: 0.15,\n      plasma: 0.9,\n      gain: 1,\n      contrast: 1.1,\n    },\n    // computing: the interference races IN PLACE — wave clock at three\n    // times idle, deeper waves — while the dome stops turning\n    thinking: {\n      speed: 1.6,\n      spin: 0.05,\n      plasma: 1.15,\n      gain: 0.95,\n      contrast: 1.15,\n    },\n    // answering: the whole dome rolls fast and the tones bloom bright\n    speaking: {\n      speed: 1.3,\n      spin: 0.8,\n      plasma: 1,\n      gain: 1.3,\n      contrast: 1.05,\n    },\n  },\n  // ink/paper carry the at-a-glance read: cool print at rest, violet-blue\n  // while computing, warm amber while answering\n  stateColors: {\n    idle: { ink: \"#101426\", paper: \"#cfe6ff\" },\n    thinking: { ink: \"#140f38\", paper: \"#a9b9ff\" },\n    speaking: { ink: \"#2a1410\", paper: \"#ffd9a4\" },\n  },\n}\n\nexport type Shdr14Props = Omit<ShaderOrbProps, \"variant\">\n\nexport function Shdr14({ size = 280, ...rest }: Shdr14Props) {\n  return <ShaderOrb variant={shdr14Orb} size={size} {...rest} />\n}\n\nexport default Shdr14\n"
        },
        {
          "path": "components/voice-agents/orbkit/core.tsx",
          "target": "@components/voice-agents/orbkit/core.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport React, {\n  useEffect,\n  useRef,\n  useState,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/* ----------------------------------------------------------------------------\n   Orbkit core — raw WebGL shader orb runtime. No dependencies.\n\n   An orb is a full-screen triangle rendered into a transparent canvas by a\n   fragment shader. Every orb declares a parameter schema (sliders + colors);\n   the values are uploaded as uniforms each frame from a ref, so a controls\n   panel can tune them live without ever remounting the canvas (a remount would\n   drop the WebGL context).\n\n   Animation model: every state synthesizes two volume signals — input (user\n   speech energy) and output (agent speech energy) — smooths them, and the\n   shaders react to those. The flow clock's speed itself follows the output\n   volume, so orbs visibly quicken when the agent is talking.\n---------------------------------------------------------------------------- */\n\nexport type OrbState = \"idle\" | \"thinking\" | \"speaking\"\n\nexport const ORB_STATES = [\"idle\", \"thinking\", \"speaking\"] as const\n\nfunction clamp01(n: number) {\n  return Math.min(1, Math.max(0, n))\n}\n\n/** Per-state [input, output] volume synthesis. */\n/**\n * Transition rate shared by params, colours and the flow-speed multiplier.\n * They must move together: if the rate multiplier eases faster than the look,\n * a state change spins the orb up before it has finished cross-fading, which\n * reads as a lurch.\n *\n * This drives a critically damped spring rather than the exponential ease it\n * used to. An exponential's velocity is highest at the instant the target\n * changes, so every state change began with a jolt — and for params that are\n * spatial frequencies (Corona's warpFreq travels 5.25 -> 19.5 between states)\n * that jolt sweeps the field through its intermediate frequencies at maximum\n * rate, which is what read as the transition \"scrambling\".\n *\n * A spring starts at rest and accelerates, so the sweep is spread across the\n * transition instead of front-loaded. Measured on that warpFreq move it is a\n * 20% lower peak rate of change (20.3/s vs 25.3/s) AND it arrives sooner —\n * 1.50s to within 2% against the exponential's 2.18s, since an exponential\n * only ever asymptotes toward its target.\n */\nconst PARAM_EASE = 4\n\n/*\n  One step of a critically damped spring, implicit (semi-implicit Euler would\n  blow up at the frame times a backgrounded tab produces). Returns nothing and\n  writes through the scratch pair so the hot loop allocates nothing.\n*/\nconst springOut = { x: 0, v: 0 }\nfunction springStep(\n  x: number,\n  v: number,\n  target: number,\n  dt: number,\n  omega: number\n) {\n  const f = 1 + 2 * dt * omega\n  const oo = omega * omega\n  const hoo = dt * oo\n  const hhoo = dt * hoo\n  const detInv = 1 / (f + hhoo)\n  springOut.x = (f * x + dt * v + hhoo * target) * detInv\n  springOut.v = (v + hoo * (target - x)) * detInv\n}\n\nfunction targetVolumes(state: OrbState, t: number): [number, number] {\n  switch (state) {\n    case \"idle\":\n      return [0, 0.3]\n    case \"speaking\":\n      return [\n        clamp01(0.65 + Math.sin(t * 4.8) * 0.22),\n        clamp01(0.75 + Math.sin(t * 3.6) * 0.22),\n      ]\n    case \"thinking\": {\n      const base = 0.38 + 0.07 * Math.sin(t * 0.7)\n      const wander = 0.05 * Math.sin(t * 2.1) * Math.sin(t * 0.37 + 1.2)\n      return [\n        clamp01(base + wander),\n        clamp01(0.48 + 0.12 * Math.sin(t * 1.05 + 0.6)),\n      ]\n    }\n  }\n}\n\n/* ------------------------------ param schema ------------------------------- */\n\nexport interface OrbParamDef {\n  key: string\n  label: string\n  min: number\n  max: number\n  step: number\n  default: number\n  /**\n   * Rate params. The engine integrates them into a clock\n   * (`clock += dt * value * volumeSpeed`) and uploads the clock instead of the\n   * raw value, so changing the rate never jumps the phase — the motion speeds\n   * up or slows down rather than snapping to a new position.\n   */\n  integrate?: boolean\n}\n\nexport interface OrbColorDef {\n  key: string\n  label: string\n  /** hex, e.g. `#ff8b73` */\n  default: string\n}\n\nexport interface OrbVariant {\n  key: string\n  label: string\n  note: string\n  /** GLSL fragment shader body. Uniform declarations are generated for you. */\n  frag: string\n  params: OrbParamDef[]\n  colors: OrbColorDef[]\n  /**\n   * Per-state parameter targets. The engine glides each param toward the\n   * active state's preset. Params passed explicitly via the `params` prop\n   * always win over the preset.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /**\n   * Per-state colour targets, the colour counterpart of `statePresets`.\n   * Kept a separate map because presets are numeric and colours are hex\n   * strings — a union would lose type safety on both. Colours glide in RGB\n   * on the same easing as params, so a state change cross-fades rather\n   * than cutting. Colours passed explicitly via the `colors` prop always\n   * win, exactly as with params.\n   */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n}\n\nexport type OrbParamValues = Partial<Record<string, number>>\nexport type OrbColorValues = Partial<Record<string, string>>\n\n/** Every param and color at its schema default. */\nexport function defaultValuesFor(variant: OrbVariant): {\n  params: Record<string, number>\n  colors: Record<string, string>\n} {\n  return {\n    params: Object.fromEntries(variant.params.map((p) => [p.key, p.default])),\n    colors: Object.fromEntries(variant.colors.map((c) => [c.key, c.default])),\n  }\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace(\"#\", \"\").trim()\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]\n  const n = parseInt(h, 16)\n  if (h.length !== 6 || Number.isNaN(n)) return [1, 1, 1]\n  return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255]\n}\n\n/* ------------------------------- GLSL shared ------------------------------- */\n\nconst VERT = `\nattribute vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\n/**\n * Prelude prepended to every orb fragment shader: uniforms, value noise, fbm,\n * and the centered aspect-corrected UV helper.\n */\nexport const ORB_GLSL_HELPERS = `\nprecision highp float;\nuniform vec2 uRes;\nuniform float uTime;   // slow ambient clock (half real-time)\nuniform float uAnim;   // flow clock — its speed follows the output volume\nuniform float uInput;  // input volume 0..1: user speech energy\nuniform float uOutput; // output volume 0..1: agent speech energy\n\nfloat hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); }\nfloat noise(vec2 p) {\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);\n  return mix(\n    mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),\n    mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x),\n    f.y\n  );\n}\nfloat fbm(vec2 p) {\n  float v = 0.0;\n  float a = 0.5;\n  for (int i = 0; i < 5; i++) {\n    v += a * noise(p);\n    p = p * 2.03 + vec2(11.7, 7.3);\n    a *= 0.5;\n  }\n  return v;\n}\nvec2 orbUV() { return (2.0 * gl_FragCoord.xy - uRes) / min(uRes.x, uRes.y); }\n\n// GLSL ES 1.0 has no tanh() — it arrived in ES 3.0. Shader-golf listings lean\n// on it as a tone-mapper, so it ships here. Clamped against exp() overflow;\n// accurate for the non-negative accumulators those shaders produce.\nvec3 tanh3(vec3 x) {\n  x = clamp(x, -10.0, 10.0);\n  vec3 e = exp(2.0 * x);\n  return (e - 1.0) / (e + 1.0);\n}\n\n`\n\nfunction paramUniformDecls(variant: OrbVariant): string {\n  return [\n    ...variant.params.map((p) => `uniform float uP_${p.key};`),\n    ...variant.colors.map((c) => `uniform vec3 uC_${c.key};`),\n  ].join(\"\\n\")\n}\n\n/* ------------------------------- engine ------------------------------------ */\n\n/**\n * Per-canvas context-lifecycle controller. Created on first mount of a canvas\n * and kept for the element's whole life — the router can hide a page and show\n * the same DOM again, and React re-runs effects on the same canvas, so the\n * lost/restored listeners must outlive any single effect run: an uncanceled\n * webglcontextlost event marks the context permanently unrestorable.\n */\ninterface CanvasContextController {\n  /** Whether a mounted orb currently wants this context alive. */\n  desired: boolean\n  /** Builds a render generation; returns its teardown. Rebound per effect run. */\n  start: (() => () => void) | null\n  /** Teardown of the live generation, if one is running. */\n  stopGen: (() => void) | null\n}\n\nconst canvasControllers = new WeakMap<\n  HTMLCanvasElement,\n  CanvasContextController\n>()\n\nfunction compile(\n  gl: WebGLRenderingContext,\n  type: number,\n  src: string\n): WebGLShader | null {\n  const shader = gl.createShader(type)\n  if (!shader) return null\n  gl.shaderSource(shader, src)\n  gl.compileShader(shader)\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    console.error(\"[orbkit] shader compile error:\", gl.getShaderInfoLog(shader))\n    gl.deleteShader(shader)\n    return null\n  }\n  return shader\n}\n\n/* ----------------------------------------------------------------------------\n   Wrappers — optional decoration drawn around, under and over the orb.\n\n   A wrapper is pure CSS/SVG, never a shader: the orb keeps its own canvas and\n   the decoration is composited on top of it by the browser. That keeps the\n   whole set free for any orb (no per-variant shader work), costs nothing on\n   the GPU budget the shaders are already spending, and means swapping one\n   wrapper for another at runtime never touches the WebGL context. Turning a\n   wrapper on or off does, since that is what moves the canvas into or out of\n   the wrapper element — see the effect's `wrapped` dependency.\n\n   Layout: a wrapped orb becomes a square box, and the canvas is absolutely\n   positioned inside it with the spec's `inset`. The FOOTPRINT is unchanged —\n   `size` is still the outer diameter — so dropping a wrapper onto an existing\n   orb reflows nothing; the orb itself just shrinks to leave the ring room.\n\n   Colour: every layer that isn't physically light or shadow paints in\n   `currentColor`, so a wrapper picks up the surrounding text colour and reads\n   correctly on light and dark pages with no configuration. `wrapperColor`\n   sets that colour when you want something other than the inherited one.\n---------------------------------------------------------------------------- */\n\nexport const ORB_WRAPPERS = [\n  \"none\",\n  \"glass\",\n  \"ring\",\n  \"dotted\",\n  \"ticks\",\n  \"reticle\",\n  \"grid\",\n  \"halftone\",\n  \"scanlines\",\n] as const\n\nexport type OrbWrapper = (typeof ORB_WRAPPERS)[number]\n\n/*\n  Keyframes for the animated wrappers, shipped inside the component so an orb\n  stays a single self-contained file with nothing to add to a global\n  stylesheet. React 19 hoists a <style href precedence> into <head> and\n  de-duplicates it, so a page full of wrapped orbs emits this exactly once;\n  older React renders it inline, which is redundant but harmless.\n\n  Reduced motion parks all of it. The shader runtime already honours the same\n  preference for the orb itself (see the reduce-motion branch in the render\n  loop), and a ring that keeps spinning around a frozen orb would be the worse\n  half of the two still moving.\n*/\nconst WRAPPER_STYLE_HREF = \"orbkit-wrapper\"\nconst WRAPPER_CSS = `\n@keyframes orbkit-w-spin { to { transform: rotate(360deg); } }\n@keyframes orbkit-w-roll { from { transform: translateY(-110%); } to { transform: translateY(360%); } }\n@media (prefers-reduced-motion: reduce) {\n  .orbkit-w-anim { animation: none !important; }\n}\n`\n\ninterface WrapperSpec {\n  /**\n   * How far the canvas sits inside the box, in percent, leaving the\n   * decoration room. Applied as explicit width/height rather than as `inset`:\n   * a canvas is a REPLACED element, so an absolutely positioned one with\n   * `left` and `right` both set does not stretch between them — it keeps its\n   * intrinsic size and the over-constrained edge is dropped. The orb would\n   * then be drawn into a canvas the size of the page.\n   */\n  inset: number\n  /**\n   * Soft circular mask on the canvas. Only the wrappers that read as a\n   * CONTAINER set one — a bubble has to hold the orb, whereas a bezel sits\n   * beside it and clipping the halo there would just amputate the glow.\n   */\n  mask?: string\n  /** Cast by the assembly as a whole, on the outer box. */\n  shadow?: string\n\n  /** True when the spec uses one of the keyframes above. */\n  animated?: boolean\n  /** Painted beneath the canvas. */\n  under?: ReactNode\n  /** Painted over it. */\n  over?: ReactNode\n}\n\nconst DISC: CSSProperties = { borderRadius: \"50%\" }\n\n/** One absolutely-positioned decoration layer, filling the wrapper box. */\nfunction Layer({\n  inset = 0,\n  style,\n  className,\n}: {\n  inset?: number | string\n  style: CSSProperties\n  className?: string\n}) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={className}\n      style={{ position: \"absolute\", inset, pointerEvents: \"none\", ...style }}\n    />\n  )\n}\n\n/**\n * A free-floating highlight — glass's specular and its bounce. These do not go\n * through `Layer` because they are placed with `left`/`top`/`width`, and a\n * style object that sets those on top of `Layer`'s `inset` shorthand is mixing\n * shorthand and longhand for the same property: React warns about it, and the\n * result depends on key order rather than on anything you would want to rely\n * on.\n */\nfunction Highlight({ style }: { style: CSSProperties }) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      style={{\n        position: \"absolute\",\n        borderRadius: \"50%\",\n        pointerEvents: \"none\",\n        ...style,\n      }}\n    />\n  )\n}\n\n/**\n * The mask that makes a wrapper HOLD the orb: cuts the canvas back to the\n * bubble and stops a hairline short of the rim, so the orb never quite touches\n * the glass.\n *\n * The percentage has to be derived rather than written down. `closest-side`\n * measures the CANVAS, and a wrapper with a negative inset draws its canvas\n * LARGER than the bubble — at -7 the canvas is 114% of the box, so the rim\n * sits at 100/1.14 = 87.7% of the canvas's own radius, not at 100%.\n *\n * The gap is real pixels rather than a share of the size: it reads as the same\n * band at 120px and at 900px, which a percentage would not.\n */\nconst RIM_GAP_PX = 4\n\nfunction rimMask(inset: number): string {\n  const rim = (100 / (1 - (2 * inset) / 100)).toFixed(2)\n  // Feathered over the final pixel, so the cut is not a razor edge.\n  const solid = RIM_GAP_PX + 0.5\n  const clear = RIM_GAP_PX - 0.5\n  return `radial-gradient(circle closest-side, #000 calc(${rim}% - ${solid}px), rgba(0,0,0,0) calc(${rim}% - ${clear}px))`\n}\n\n/** Both spellings, since Safari still wants the prefix for mask-image. */\nfunction masked(image: string): CSSProperties {\n  return { WebkitMaskImage: image, maskImage: image }\n}\n\nconst svgLayer: CSSProperties = {\n  position: \"absolute\",\n  inset: 0,\n  width: \"100%\",\n  height: \"100%\",\n  pointerEvents: \"none\",\n  overflow: \"visible\",\n}\n\n/** Glass's overfill, shared by its inset and the mask derived from it. */\nconst GLASS_INSET = -4\n\nconst WRAPPER_SPECS: Record<Exclude<OrbWrapper, \"none\">, WrapperSpec> = {\n  /*\n    glass — a blown bubble with the orb suspended inside it.\n\n    Five layers in the order light actually arrives: the body brightening\n    toward the key light, the Fresnel ring where a sphere's edge turns almost\n    edge-on and reflects nearly everything, the rim itself, the window\n    reflection, and the bounce coming back up off whatever the bubble is\n    sitting on. All of it is white and black rather than `currentColor` —\n    glass has no colour of its own, only the light it moves around.\n  */\n  glass: {\n    /*\n      Negative on purpose. An orb's shader does not necessarily paint to the\n      edge of its canvas — most draw a sphere with transparent margin around\n      it — so a canvas sized to the bubble leaves a dead ring between the orb\n      and the rim, which is not what a thing suspended in glass looks like.\n      Oversizing the canvas by 14% pushes the sphere out to the rim, and\n      `rimMask` cuts whatever overflows — a few pixels short of the glass, so\n      the orb sits just inside it rather than welded to it. Orbs that already fill\n      their canvas lose a few percent off the limb, which is the same crop the\n      reference bubble makes.\n    */\n    inset: GLASS_INSET,\n    mask: rimMask(GLASS_INSET),\n    shadow: \"0 24px 48px -26px rgba(0,0,0,0.55)\",\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(ellipse 80% 70% at 28% 20%, rgba(255,255,255,0.16), rgba(255,255,255,0.03) 45%, rgba(255,255,255,0) 72%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(255,255,255,0) 0%, rgba(255,255,255,0.0) 55%, rgba(255,255,255,0.05) 99.5%, rgba(255,255,255,0) 100%)\",\n            overflow: \"hidden\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow: \"3px 6px 10px #ffffff20 inset\",\n          }}\n        />\n        {/*\n          The shell's own darkening, just inside the rim. Invisible on a dark\n          page — it is black over black — and doing all the work on a light\n          one, where the white highlights below have nothing to stand out\n          against and the bubble would otherwise read as a bare drop shadow.\n        */}\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(0,0,0,0) 78%, rgba(0,0,0,0.05) 93%, rgba(0,0,0,0.02) 100%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow:\n              \"inset 0 6px 12px -7px rgba(255,255,255,0.05), inset 0 -9px 16px -9px rgba(255,255,255,0.1), 0 0 0 1px rgba(0,0,0,0.07)\",\n          }}\n        />\n        <Highlight\n          style={{\n            left: \"15%\",\n            top: \"10%\",\n            width: \"38%\",\n            height: \"22%\",\n            transform: \"rotate(-25deg)\",\n            background:\n              \"radial-gradient(closest-side, rgba(255,255,255,0.9), rgba(255,255,255,0.3) 55%, rgba(255,255,255,0) 100%)\",\n            filter: \"blur(10px)\",\n          }}\n        />\n      </>\n    ),\n  },\n\n  /* ring — two hairlines and nothing else. The restrained one. */\n  ring: {\n    inset: 9,\n    over: (\n      <>\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.22 }}\n        />\n        <Layer\n          inset=\"5%\"\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.1 }}\n        />\n      </>\n    ),\n  },\n\n  /*\n    dotted — evenly spaced dots around the circumference, turning slowly.\n\n    Drawn as one dashed circle with round caps and a near-zero dash length, so\n    each dash collapses to a dot. `pathLength=\"64\"` renormalizes the path to 64\n    units first, which is what makes the count exact: the dash period is\n    literally 1/64th of the circle, so the pattern closes on itself with no\n    seam where the last gap would otherwise be short.\n  */\n  dotted: {\n    inset: 10,\n    animated: true,\n    over: (\n      <svg\n        aria-hidden=\"true\"\n        viewBox=\"0 0 100 100\"\n        className=\"orbkit-w-anim\"\n        style={{ ...svgLayer, animation: \"orbkit-w-spin 48s linear infinite\" }}\n      >\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"47\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.7\"\n          strokeLinecap=\"round\"\n          pathLength={64}\n          strokeDasharray=\"0.0001 0.9999\"\n          opacity={0.45}\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    ticks — an instrument bezel: a fine minor scale every 6 degrees with a\n    longer major tick every 30. Both are one repeating conic gradient masked\n    down to an annulus, so the tick count is set by the gradient's period and\n    the tick LENGTH by how far in the mask reaches.\n  */\n  ticks: {\n    inset: 12,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.32,\n            background:\n              \"repeating-conic-gradient(from -0.5deg, transparent 0deg 0.2deg, currentColor 0.4deg 0.6deg, transparent 0.8deg 6deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 88%, #000 90%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.6,\n            background:\n              \"repeating-conic-gradient(from -0.75deg, transparent 0deg 0.25deg, currentColor 0.5deg 1deg, transparent 1.25deg 30deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 80%, #000 82%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.12 }}\n        />\n      </>\n    ),\n  },\n\n  /* reticle — viewfinder furniture: corner brackets, cardinal ticks, a track. */\n  reticle: {\n    inset: 13,\n    over: (\n      <svg aria-hidden=\"true\" viewBox=\"0 0 100 100\" style={svgLayer}>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" opacity=\"0.5\">\n          <path d=\"M1 13 L1 1 L13 1\" />\n          <path d=\"M87 1 L99 1 L99 13\" />\n          <path d=\"M99 87 L99 99 L87 99\" />\n          <path d=\"M13 99 L1 99 L1 87\" />\n        </g>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.38\">\n          <path d=\"M50 1 L50 9\" />\n          <path d=\"M50 91 L50 99\" />\n          <path d=\"M1 50 L9 50\" />\n          <path d=\"M91 50 L99 50\" />\n        </g>\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"46\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"0.7\"\n          opacity=\"0.22\"\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    grid — a graticule laid over the orb and masked back to the disc, so the\n    mesh appears to be etched on the glass in front of it rather than drawn on\n    the page behind. The lines are 1px whatever the size; the SPACING is a\n    percentage, so the cell count holds from a gallery thumbnail to a\n    full-bleed hero.\n  */\n  grid: {\n    inset: 8,\n    /*\n      The ruling sits UNDER the canvas: graph paper the orb rests on, not a\n      mesh laid over its face. Drawn on top it crosshatched the shader — the\n      one thing the wrapper is meant to frame. The ring stays over, since it\n      only ever meets the transparent margin at the canvas edge.\n    */\n    under: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.18,\n          backgroundImage:\n            \"repeating-linear-gradient(to right, currentColor 0 1px, transparent 1px 12.5%), repeating-linear-gradient(to bottom, currentColor 0 1px, transparent 1px 12.5%)\",\n          ...masked(\n            \"radial-gradient(circle closest-side, #000 86%, rgba(0,0,0,0) 99%)\"\n          ),\n        }}\n      />\n    ),\n    over: (\n      <Layer\n        style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.2 }}\n      />\n    ),\n  },\n\n  /*\n    halftone — a print screen over the outer band of the orb. The mask keeps\n    the middle clear, so the dots read as the image breaking up toward its\n    edge instead of a texture pasted across the whole face.\n  */\n  halftone: {\n    inset: 6,\n    over: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.5,\n          backgroundImage: \"radial-gradient(currentColor 22%, transparent 24%)\",\n          backgroundSize: \"7px 7px\",\n          ...masked(\n            \"radial-gradient(circle closest-side, transparent 40%, #000 80%, #000 94%, rgba(0,0,0,0) 100%)\"\n          ),\n        }}\n      />\n    ),\n  },\n\n  /*\n    scanlines — a phosphor tube. Black lines rather than `currentColor`,\n    because scanlines are the UNLIT gaps between rows and stay dark whatever\n    the page is; the slow bright band rolling down is the vertical hold\n    drifting, which is the part that reads as a CRT rather than as stripes.\n  */\n  scanlines: {\n    inset: 0,\n    animated: true,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            backgroundImage:\n              \"repeating-linear-gradient(to bottom, rgba(0,0,0,0.45) 0 1px, rgba(0,0,0,0) 1px 3px)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, #000 84%, rgba(0,0,0,0) 100%)\"\n            ),\n          }}\n        />\n        <span\n          aria-hidden=\"true\"\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            borderRadius: \"50%\",\n            overflow: \"hidden\",\n            pointerEvents: \"none\",\n          }}\n        >\n          <span\n            className=\"orbkit-w-anim\"\n            style={{\n              position: \"absolute\",\n              left: 0,\n              right: 0,\n              top: 0,\n              height: \"30%\",\n              background:\n                \"linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,0.07) 50%, rgba(255,255,255,0) 100%)\",\n              animation: \"orbkit-w-roll 7s linear infinite\",\n            }}\n          />\n        </span>\n        <Layer\n          style={{ ...DISC, boxShadow: \"inset 0 0 40px -8px rgba(0,0,0,0.5)\" }}\n        />\n      </>\n    ),\n  },\n}\n\nexport interface ShaderOrbProps {\n  /** The orb definition: shader + param schema + state presets. */\n  variant: OrbVariant\n  /** Drives the synthesized volume signals. Defaults to `\"idle\"`. */\n  state?: OrbState\n  /** Rendered size in CSS pixels. Ignored when `className` sizes the canvas. */\n  size?: number\n  /** Explicit param overrides. Any key present here wins over the state preset. */\n  params?: OrbParamValues\n  /** Explicit color overrides, as hex strings. */\n  colors?: OrbColorValues\n  /**\n   * Per-state parameter targets, overriding the variant's own. Merged KEY BY\n   * KEY over what the orb already defines, so `{ thinking: { churn: 1.62 } }`\n   * retouches one param of one state and leaves every other param — and the\n   * other two states — exactly as the orb ships them.\n   *\n   * This is the prop form of the variant's `statePresets`, so you can retune\n   * an orb's states from the outside without forking its file. Values still\n   * glide, so switching states cross-fades into your targets. An explicit\n   * `params` value outranks this, the same way it outranks the variant.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /** The colour counterpart of `statePresets`, merged the same key-by-key way. */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n  /**\n   * Per-state volume drive, the third member of the same family. Use it to\n   * give each state its own energy; use `volumes` below instead when you have\n   * a real signal to feed in, such as live mic level.\n   */\n  stateVolumes?: Partial<Record<OrbState, { input?: number; output?: number }>>\n  /**\n   * Overrides the synthesized volume signals for the active state. The engine\n   * normally derives these from `state` — a slow breath at idle, a restless\n   * wander while thinking, speech-shaped peaks while speaking — and most\n   * shaders read them as their reactivity. Setting either channel here pins\n   * it instead, which is how the playground lets you dial each state's drive\n   * independently. Omit a channel to keep its synthesized motion.\n   */\n  volumes?: { input?: number; output?: number }\n  /** Freeze the animation on the current frame. */\n  paused?: boolean\n  /**\n   * Stop rendering while the orb is scrolled out of view. Defaults to `true` —\n   * a page full of orbs would otherwise run a WebGL loop per card.\n   */\n  pauseOffscreen?: boolean\n  /** Device-pixel-ratio ceiling. Defaults to `2`. */\n  maxDpr?: number\n  /**\n   * Decoration drawn around the orb — a glass bubble, a dotted bezel, a\n   * viewfinder. Defaults to `\"none\"`, which renders the bare canvas exactly as\n   * it always has, with no extra element in the tree.\n   *\n   * A wrapper never changes the orb's footprint: `size` stays the outer\n   * diameter and the canvas is inset inside it, so switching one on reflows\n   * nothing around it.\n   */\n  wrapper?: OrbWrapper\n  /**\n   * The colour a wrapper draws its lines and dots in. Defaults to\n   * `currentColor` — the inherited text colour — which is what makes the\n   * bezels legible on a light and a dark page without being told which one\n   * they are on. `glass` ignores it: glass has no colour of its own.\n   */\n  wrapperColor?: string\n  /** Applied to the outermost element — the wrapper when there is one. */\n  className?: string\n  /** Merged onto the outermost element's style. */\n  style?: CSSProperties\n  /** Accessible label. When omitted the orb is hidden from assistive tech. */\n  ariaLabel?: string\n}\n\nexport function ShaderOrb({\n  variant,\n  state = \"idle\",\n  size,\n  params,\n  colors,\n  statePresets,\n  stateColors,\n  stateVolumes,\n  volumes,\n  paused = false,\n  pauseOffscreen = true,\n  maxDpr = 2,\n  wrapper = \"none\",\n  wrapperColor,\n  className,\n  style,\n  ariaLabel,\n}: ShaderOrbProps) {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const spec = wrapper === \"none\" ? undefined : WRAPPER_SPECS[wrapper]\n  const wrapped = spec !== undefined\n\n  // Live refs: the render loop reads these every frame, so changing a param\n  // never re-runs the GL setup effect (which would drop the context). Synced in\n  // an effect rather than during render — a ref write during render is unsafe\n  // under concurrent rendering, and the loop picks the new value up on the very\n  // next frame anyway.\n  /*\n    Whether the canvas has drawn a frame yet, tracked per variant because a\n    variant swap mounts a brand new canvas (see the `key` below).\n\n    A mounted-but-never-drawn canvas is at the browser's mercy: rather than\n    the transparent rectangle you would expect, a page that mounts a dozen at\n    once gets white boxes — and in some browsers a broken-image placeholder —\n    for as long as the compositor has nothing to raster. That window is not\n    small here: every orb compiles a full fragment shader synchronously in its\n    own mount effect, so on the gallery grid the first canvases sit empty\n    while the last ones are still compiling. Holding each canvas invisible\n    until its own first frame lands is what makes the grid fade in cleanly\n    instead of flashing. One state change per orb, once, on mount.\n  */\n  const [paintedKey, setPaintedKey] = useState<string | null>(null)\n  const painted = paintedKey === variant.key\n\n  const stateRef = useRef<OrbState>(state)\n  const paramsRef = useRef<OrbParamValues | undefined>(params)\n  const colorsRef = useRef<OrbColorValues | undefined>(colors)\n  const statePresetsRef = useRef(statePresets)\n  const stateColorsRef = useRef(stateColors)\n  const stateVolumesRef = useRef(stateVolumes)\n  const volumesRef = useRef(volumes)\n  const pausedRef = useRef(paused)\n\n  useEffect(() => {\n    stateRef.current = state\n    paramsRef.current = params\n    colorsRef.current = colors\n    statePresetsRef.current = statePresets\n    stateColorsRef.current = stateColors\n    stateVolumesRef.current = stateVolumes\n    volumesRef.current = volumes\n    pausedRef.current = paused\n  }, [\n    state,\n    params,\n    colors,\n    statePresets,\n    stateColors,\n    stateVolumes,\n    volumes,\n    paused,\n  ])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    const gl = canvas.getContext(\"webgl\", {\n      alpha: true,\n      // No MSAA: the geometry is a single full-screen triangle, so there are no\n      // primitive edges to antialias — softness comes from the shaders. Leaving\n      // it on costs the multisample buffers plus a resolve every frame.\n      antialias: false,\n      premultipliedAlpha: true,\n    })\n    if (!gl) return\n\n    const loseExt = gl.getExtension(\"WEBGL_lose_context\")\n\n    /*\n      A \"generation\" is everything tied to a live context: program, buffers,\n      observers, render loop. Browsers cap live WebGL contexts per page and\n      evict the oldest past the cap, and an evicted orb's canvas stays blank\n      forever unless the app rebuilds — so generations tear down and rebuild on\n      the lost/restored events instead of assuming the context is immortal.\n    */\n    let announcedPaint = false\n\n    const startGeneration = (): (() => void) => {\n      if (gl.isContextLost()) return () => {}\n      // Every generation announces its own first frame: a context that was\n      // lost and restored has an empty drawing buffer and is hidden again\n      // (below), so it has to earn its reveal back.\n      announcedPaint = false\n\n      const vs = compile(gl, gl.VERTEX_SHADER, VERT)\n      const fs = compile(\n        gl,\n        gl.FRAGMENT_SHADER,\n        ORB_GLSL_HELPERS + paramUniformDecls(variant) + variant.frag\n      )\n      const releaseShaders = () => {\n        if (vs) gl.deleteShader(vs)\n        if (fs) gl.deleteShader(fs)\n      }\n      if (!vs || !fs) return releaseShaders\n\n      const prog = gl.createProgram()\n      if (!prog) return releaseShaders\n      gl.attachShader(prog, vs)\n      gl.attachShader(prog, fs)\n      gl.linkProgram(prog)\n      if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n        console.error(\n          \"[orbkit] program link error:\",\n          gl.getProgramInfoLog(prog)\n        )\n        gl.deleteProgram(prog)\n        return releaseShaders\n      }\n      gl.useProgram(prog)\n\n      const buf = gl.createBuffer()\n      gl.bindBuffer(gl.ARRAY_BUFFER, buf)\n      gl.bufferData(\n        gl.ARRAY_BUFFER,\n        new Float32Array([-1, -1, 3, -1, -1, 3]),\n        gl.STATIC_DRAW\n      )\n      const aPos = gl.getAttribLocation(prog, \"aPos\")\n      gl.enableVertexAttribArray(aPos)\n      gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0)\n\n      gl.enable(gl.BLEND)\n      gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n\n      const uRes = gl.getUniformLocation(prog, \"uRes\")\n      const uTime = gl.getUniformLocation(prog, \"uTime\")\n      const uAnim = gl.getUniformLocation(prog, \"uAnim\")\n      const uInput = gl.getUniformLocation(prog, \"uInput\")\n      const uOutput = gl.getUniformLocation(prog, \"uOutput\")\n\n      const paramLocs = variant.params.map((p) => ({\n        def: p,\n        loc: gl.getUniformLocation(prog, `uP_${p.key}`),\n      }))\n      const colorLocs = variant.colors.map((c) => ({\n        def: c,\n        loc: gl.getUniformLocation(prog, `uC_${c.key}`),\n      }))\n\n      /* --- sizing: track the element box, not a one-shot measurement ------- */\n      // Backing-store scale, stepped down by the adaptive-resolution logic in\n      // the loop when the GPU can't hold frame rate. CSS size never changes —\n      // the browser upscales, which these soft shaders absorb gracefully.\n      let resScale = 1\n      const resize = () => {\n        const dpr = Math.min(window.devicePixelRatio || 1, maxDpr) * resScale\n        const w = Math.max(1, Math.round(canvas.clientWidth * dpr))\n        const h = Math.max(1, Math.round(canvas.clientHeight * dpr))\n        if (canvas.width !== w || canvas.height !== h) {\n          canvas.width = w\n          canvas.height = h\n          gl.viewport(0, 0, w, h)\n        }\n        /*\n          Uploaded UNCONDITIONALLY, outside the size guard. A rebuilt\n          generation (React strict-mode remount, a restored context) links a\n          fresh program whose uRes starts at zero — and the canvas usually\n          already holds the right backing size, so an upload gated behind\n          the resize never ran. With uRes = 0, orbUV() divides by zero and\n          every fragment lands transparent: a healthy context, a bound\n          program, and a permanently blank orb.\n        */\n        gl.uniform2f(uRes, w, h)\n      }\n      resize()\n\n      const resizeObserver =\n        typeof ResizeObserver !== \"undefined\"\n          ? new ResizeObserver(resize)\n          : null\n      resizeObserver?.observe(canvas)\n\n      /* --- visibility: don't burn a render loop on an offscreen orb -------- */\n      let visible = !pauseOffscreen\n      const intersectionObserver =\n        pauseOffscreen && typeof IntersectionObserver !== \"undefined\"\n          ? new IntersectionObserver(\n              (entries) => {\n                visible = Boolean(entries[0]?.isIntersecting)\n                if (visible) {\n                  last = performance.now() / 1000\n                }\n              },\n              { rootMargin: \"150px 0px\", threshold: 0 }\n            )\n          : null\n      if (intersectionObserver) {\n        intersectionObserver.observe(canvas)\n      } else {\n        visible = true\n      }\n\n      const reduceMotion =\n        typeof window.matchMedia === \"function\" &&\n        window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n\n      /* --- driver state ---------------------------------------------------- */\n      let tSec = 0\n      // random phase so two orbs on the same page never look synchronized\n      let anim = Math.random() * 100\n      let speed = 0.1\n      const cur = { in: 0, out: 0.3 }\n      const presets = variant.statePresets\n      const paramCur: Record<string, number> = {}\n      const paramVel: Record<string, number> = {}\n      const paramClocks: Record<string, number> = {}\n      const colorCur: Record<string, [number, number, number]> = {}\n      const colorVel: Record<string, [number, number, number]> = {}\n      let speedVel = 0\n      const [initialIn, initialOut] = targetVolumes(stateRef.current, 0)\n      cur.in = initialIn\n      cur.out = initialOut\n      let last = performance.now() / 1000\n      let raf = 0\n      // smoothed frame time for the adaptive-resolution check\n      let frameEma = 1 / 60\n\n      const uploadAndDraw = (dt: number, snap = false) => {\n        // Synthesized from the state, unless a channel is pinned via\n        // `volumes`. Pinned values still glide on the same easing, so dialing\n        // one in the playground cross-fades rather than jumping.\n        const [tin, tout] = targetVolumes(stateRef.current, tSec)\n        // Same order as params and colours: direct prop, then the per-state\n        // map, then the engine's own synthesis.\n        const liveVolumes = volumesRef.current\n        const stateVolume = stateVolumesRef.current?.[stateRef.current]\n        const targetIn = liveVolumes?.input ?? stateVolume?.input ?? tin\n        const targetOut = liveVolumes?.output ?? stateVolume?.output ?? tout\n        const kVol = 1 - Math.exp(-dt * 12)\n        cur.in += (targetIn - cur.in) * kVol\n        cur.out += (targetOut - cur.out) * kVol\n\n        /*\n          Flow speed follows the output volume. It multiplies every integrated\n          clock's increment, so it is a RATE: easing it quickly makes the orb\n          visibly lurch — a state change would spin the orb up hard before the\n          params had finished gliding.\n\n          It is therefore eased on the same constant as the params below, so a\n          state change ramps its motion over the same half second that its look\n          takes to cross-fade. The steady-state values are unchanged, so a\n          speaking orb still flows faster than an idle one; only the transition\n          into that rate is gradual.\n        */\n        const targetSpeed = 0.1 + (1 - Math.pow(cur.out - 1, 2)) * 0.9\n        if (snap) {\n          speed = targetSpeed\n          speedVel = 0\n        } else {\n          springStep(speed, speedVel, targetSpeed, dt, PARAM_EASE)\n          speed = springOut.x\n          speedVel = springOut.v\n        }\n        anim += dt * speed\n\n        gl.uniform1f(uTime, tSec * 0.5)\n        gl.uniform1f(uAnim, anim)\n        gl.uniform1f(uInput, cur.in)\n        gl.uniform1f(uOutput, cur.out)\n\n        // Resolution order per param: explicit `params` → `statePresets`\n        // prop → the variant's own preset → schema default. The two middle\n        // steps are per-key, so overriding one param of one state leaves the\n        // rest of that state alone. Values glide rather than snap.\n        const liveParams = paramsRef.current\n        const statePreset = presets?.[stateRef.current]\n        const overridePreset = statePresetsRef.current?.[stateRef.current]\n\n        for (const { def, loc } of paramLocs) {\n          const explicit = liveParams?.[def.key]\n          const target =\n            typeof explicit === \"number\"\n              ? explicit\n              : (overridePreset?.[def.key] ??\n                statePreset?.[def.key] ??\n                def.default)\n          const curVal = paramCur[def.key] ?? target\n          let next: number\n          if (snap) {\n            next = target\n            paramVel[def.key] = 0\n          } else {\n            springStep(curVal, paramVel[def.key] ?? 0, target, dt, PARAM_EASE)\n            next = springOut.x\n            paramVel[def.key] = springOut.v\n          }\n          paramCur[def.key] = next\n\n          if (def.integrate) {\n            const clock =\n              (paramClocks[def.key] ??\n                (paramClocks[def.key] = Math.random() * 100)) +\n              dt * speed * next\n            paramClocks[def.key] = clock\n            gl.uniform1f(loc, clock)\n          } else {\n            gl.uniform1f(loc, next)\n          }\n        }\n\n        // Same resolution order and same easing as params, so a state change\n        // cross-fades the palette instead of cutting to it.\n        const liveColors = colorsRef.current\n        const stateColor = variant.stateColors?.[stateRef.current]\n        const overrideColor = stateColorsRef.current?.[stateRef.current]\n        for (const { def, loc } of colorLocs) {\n          const target = hexToRgb(\n            liveColors?.[def.key] ??\n              overrideColor?.[def.key] ??\n              stateColor?.[def.key] ??\n              def.default\n          )\n          const curCol = (colorCur[def.key] ??= [...target] as [\n            number,\n            number,\n            number,\n          ])\n          const velCol = (colorVel[def.key] ??= [0, 0, 0])\n          for (let i = 0; i < 3; i++) {\n            if (snap) {\n              curCol[i] = target[i]\n              velCol[i] = 0\n            } else {\n              springStep(curCol[i], velCol[i], target[i], dt, PARAM_EASE)\n              curCol[i] = springOut.x\n              velCol[i] = springOut.v\n            }\n          }\n          gl.uniform3f(loc, curCol[0], curCol[1], curCol[2])\n        }\n\n        gl.clearColor(0, 0, 0, 0)\n        gl.clear(gl.COLOR_BUFFER_BIT)\n        gl.drawArrays(gl.TRIANGLES, 0, 3)\n        // Deferred a microtask: the first of these draws runs synchronously\n        // inside this effect, and a sync setState there trips the compiler\n        // lint. A microtask still resolves before the browser paints, so the\n        // reveal is not delayed by a frame.\n        if (!announcedPaint) {\n          announcedPaint = true\n          queueMicrotask(() => {\n            /*\n              Re-check: the context can be evicted between this draw and the\n              microtask, and mounting one more orb anywhere on the page is\n              enough to do it — opening the details drawer over a full gallery\n              is exactly that. Revealing on the strength of a frame that has\n              already been thrown away puts a dead canvas on screen, which is\n              what the browser draws its broken-canvas placeholder over. The\n              generation that follows the restore announces again.\n            */\n            if (gl.isContextLost()) return\n            setPaintedKey(variant.key)\n          })\n        }\n      }\n\n      const releaseGL = () => {\n        resizeObserver?.disconnect()\n        intersectionObserver?.disconnect()\n        gl.deleteProgram(prog)\n        gl.deleteShader(vs)\n        gl.deleteShader(fs)\n        gl.deleteBuffer(buf)\n      }\n\n      if (reduceMotion) {\n        // One representative frame, then stop — snapped straight onto the\n        // state's targets, since a spring would only be part-way there.\n        tSec = 1\n        uploadAndDraw(1, true)\n        return releaseGL\n      }\n\n      const loop = () => {\n        raf = requestAnimationFrame(loop)\n        const now = performance.now() / 1000\n        const dt = Math.min(now - last, 0.05)\n        last = now\n        if (!visible || pausedRef.current) return\n        tSec += dt\n\n        /*\n          Adaptive resolution. When the smoothed frame time sits above ~30fps,\n          the GPU is drowning in fragment work (these shaders are pure fill\n          cost), so step the backing store down 20% and re-measure. Steps only\n          go down — never back up — so the resolution can't oscillate. The\n          warm-up guard keeps page-load jank (hydration, first compiles) from\n          triggering a downgrade the GPU never asked for.\n        */\n        /*\n          Only unstalled frames are evidence about GPU fill cost. `dt` above is\n          clamped at 0.05, so a frame that hits the clamp is the main thread\n          having been blocked — a slider drag re-rendering React, a GC pause, a\n          tab regaining focus — and feeding those in made UI jank look\n          identical to a drowning GPU.\n        */\n        if (dt < 0.05) frameEma += (dt - frameEma) * 0.08\n\n        if (tSec > 1.5 && frameEma > 1 / 34 && resScale > 0.5) {\n          resScale = Math.max(0.5, resScale * 0.8)\n          frameEma = 1 / 60 // require fresh evidence before the next step\n          resize()\n        } else if (tSec > 1.5 && frameEma < 1 / 55 && resScale < 1) {\n          /*\n            And step back up once frames are comfortably fast again. This used\n            to be one-way, on the reasoning that it could not then oscillate —\n            but that also meant one transient stall permanently halved the\n            orb's resolution, and at half resolution a high-frequency shader\n            aliases into shimmer that reads as the shader itself misbehaving.\n            The gap between the two thresholds (29ms down, 18ms up) is the\n            hysteresis that stops it hunting.\n          */\n          resScale = Math.min(1, resScale / 0.8)\n          frameEma = 1 / 60\n          resize()\n        }\n\n        uploadAndDraw(dt)\n      }\n      /*\n        First frame synchronously, before entering the rAF loop. rAF does not\n        run at all in hidden documents (background tabs, embedded previews),\n        so a freshly mounted orb would otherwise sit fully transparent until\n        the page next becomes visible — a grid of mounted, healthy, blank\n        canvases. The sync frame guarantees every mount paints: background\n        documents get a static frame, visible ones start animating over it.\n        dt = 1 lands the param glide on its targets, as in the reduce-motion\n        frame above.\n      */\n      uploadAndDraw(1)\n      loop()\n\n      return () => {\n        cancelAnimationFrame(raf)\n        releaseGL()\n      }\n    }\n\n    /*\n      Wire the canvas's lifecycle controller. The listeners are attached ONCE\n      per canvas element and never removed, deliberately: the lost event must\n      be canceled even while no orb is mounted on the canvas — an uncanceled\n      webglcontextlost marks the context permanently unrestorable, and the\n      router can show this exact canvas again later. Whether a loss leads to\n      a revival is decided by `desired`, not by listener presence.\n    */\n    /*\n      A canvas whose context has gone is not simply blank: Chrome paints its\n      broken-image placeholder over the element's whole box — the white square\n      you see on a reloaded grid. Hide the canvas the moment the context is\n      lost, and let the generation that follows a restore reveal it again.\n    */\n    const hideNow = () => {\n      /*\n        Both, deliberately. The style write lands in this tick — the browser\n        paints its placeholder over a dead canvas immediately, and a busy main\n        thread can hold a React update for several frames. The state change is\n        what keeps React's own view in sync, so the reveal that follows a\n        restore clears the inline value again rather than fighting it.\n      */\n      canvas.style.opacity = \"0\"\n      setPaintedKey(null)\n    }\n\n    const onContextLostHide = () => hideNow()\n    canvas.addEventListener(\"webglcontextlost\", onContextLostHide)\n\n    /*\n      Hand the context back before the next document asks for one.\n\n      A hard reload never runs this effect's cleanup — the document is\n      discarded whole — so the outgoing page's contexts are still alive while\n      the incoming page allocates its own. On a grid of orbs that puts the\n      live count past the browser's ~16 cap, and the ones it evicts are\n      exactly the canvases that come back as placeholders until the restore\n      path catches them. `persisted` is a bfcache suspend, where the page is\n      shown again untouched and must keep everything it holds.\n    */\n    const onPageHide = (event: PageTransitionEvent) => {\n      if (event.persisted) return\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Already released — nothing to hand back.\n      }\n    }\n    window.addEventListener(\"pagehide\", onPageHide)\n\n    let ctl = canvasControllers.get(canvas)\n    if (!ctl) {\n      const created: CanvasContextController = {\n        desired: false,\n        start: null,\n        stopGen: null,\n      }\n      canvas.addEventListener(\"webglcontextlost\", (event) => {\n        event.preventDefault() // always cancel — keeps the context restorable\n        created.stopGen?.()\n        created.stopGen = null\n        if (created.desired) {\n          /*\n            Ask for the context back — but in a LATER task. The browser only\n            marks a loss as restorable once the lost event's dispatch has\n            completed and it has seen the canceled flag, so a restoreContext()\n            issued during dispatch (or before it, as the mount path may) is\n            silently refused. This is the path a synchronous cleanup+setup\n            pair hits — React re-running the effect on the same canvas loses\n            the context and wants it right back. For losses we didn't cause\n            (eviction, GPU reset) the call may refuse; the canceled event then\n            lets the browser restore on its own schedule.\n          */\n          setTimeout(() => {\n            if (!created.desired) return\n            try {\n              loseExt?.restoreContext()\n            } catch {\n              // Natural loss — restoration is the browser's call now.\n            }\n          }, 0)\n        }\n      })\n      canvas.addEventListener(\"webglcontextrestored\", () => {\n        if (created.desired && created.start) {\n          created.stopGen = created.start()\n        }\n      })\n      canvasControllers.set(canvas, created)\n      ctl = created\n    }\n    const controller = ctl\n\n    controller.desired = true\n    controller.start = startGeneration\n    if (gl.isContextLost()) {\n      // A previous run on this canvas released the context (effect re-run, or\n      // the router re-showing a kept-alive page). If the lost event already\n      // dispatched this request is honored now; if it is still queued, the\n      // lost handler above re-requests it on dispatch.\n      try {\n        loseExt?.restoreContext()\n      } catch {\n        // No restore path — the orb stays blank rather than throwing.\n      }\n    } else {\n      controller.stopGen = startGeneration()\n    }\n\n    return () => {\n      /*\n        Hide BEFORE tearing the context down.\n\n        This cleanup releases the context deliberately, and the lost event it\n        provokes is dispatched asynchronously — by which point the listener\n        below is unhooked and the replacement effect has not drawn yet. That\n        leaves a revealed canvas with a dead context, which is precisely what\n        the browser paints its broken-canvas placeholder over. The window is\n        not rare: any prop change in this effect's deps re-runs it, so it hits\n        every time the drawer switches preview example (maxDpr differs on the\n        layout one) or a wrapper is toggled.\n      */\n      hideNow()\n      canvas.removeEventListener(\"webglcontextlost\", onContextLostHide)\n      window.removeEventListener(\"pagehide\", onPageHide)\n      controller.desired = false\n      controller.start = null\n      controller.stopGen?.()\n      controller.stopGen = null\n      /*\n        Release the context NOW instead of when the canvas is garbage\n        collected. Browsers cap live WebGL contexts per page (~8–16) and evict\n        the oldest when the cap is hit — client-side navigation that unmounts\n        and remounts a page of orbs otherwise piles up zombie contexts until\n        freshly mounted orbs get evicted and render blank.\n      */\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Context already lost — nothing to release.\n      }\n    }\n    /*\n      `wrapped` is in here because turning a wrapper on or off moves the canvas\n      from being this component's root element to being a child of the wrapper\n      div — React drops the old element and mounts a new one, and the GL\n      context, its observers and its render loop all belong to the old one. Any\n      other prop leaves the element alone, INCLUDING a swap between two\n      wrappers: the canvas keeps its slot among the decoration layers, so\n      glass -> ring reuses the context instead of rebuilding it.\n    */\n  }, [variant, pauseOffscreen, maxDpr, wrapped])\n\n  const sizeStyle: CSSProperties =\n    size === undefined ? {} : { width: size, height: size }\n\n  /*\n    Spread ahead of the caller's `style`, so an orb that wants to own its own\n    opacity still can — it simply opts out of the reveal.\n\n    A hard flip, deliberately: no transition, no fade. A hidden document\n    (background tab, embedded preview) does not advance CSS transitions, so a\n    faded reveal left orbs pinned at zero in exactly the case the synchronous\n    first frame above exists to serve — mounted, healthy, and invisible. The\n    cut is not a pop either way, since it happens on the frame the orb first\n    has something to show.\n  */\n  const revealStyle: CSSProperties = painted ? {} : { opacity: 0 }\n\n  const canvas = (\n    <canvas\n      // A lost WebGL context can't be reused, so each variant gets a fresh canvas.\n      key={variant.key}\n      ref={canvasRef}\n      className={spec ? undefined : className}\n      style={\n        spec\n          ? {\n              display: \"block\",\n              position: \"absolute\",\n              left: `${spec.inset}%`,\n              top: `${spec.inset}%`,\n              width: `${100 - 2 * spec.inset}%`,\n              height: `${100 - 2 * spec.inset}%`,\n              ...revealStyle,\n              ...(spec.mask ? masked(spec.mask) : {}),\n            }\n          : { display: \"block\", ...sizeStyle, ...revealStyle, ...style }\n      }\n      role={!spec && ariaLabel ? \"img\" : undefined}\n      aria-label={spec ? undefined : ariaLabel}\n      aria-hidden={!spec && ariaLabel ? undefined : true}\n    />\n  )\n\n  if (!spec) return canvas\n\n  /*\n    Wrapped: the box becomes the orb's footprint and the canvas is absolutely\n    positioned inside it. `under`, the canvas and `over` are all positioned\n    with an auto z-index, so they paint in DOM order — decoration behind the\n    orb, then the orb, then decoration in front of it.\n\n    `aspectRatio` is the fallback for the sizeless case: `size` is optional\n    (callers may size the orb with a class instead), and an absolutely\n    positioned canvas contributes nothing to its parent's height, so without\n    it a class that only sets a width would collapse the box to zero.\n  */\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"relative\",\n        aspectRatio: \"1 / 1\",\n        ...(spec.shadow ? { borderRadius: \"50%\", boxShadow: spec.shadow } : {}),\n        ...sizeStyle,\n        ...(wrapperColor ? { color: wrapperColor } : {}),\n        ...style,\n      }}\n      role={ariaLabel ? \"img\" : undefined}\n      aria-label={ariaLabel}\n      aria-hidden={ariaLabel ? undefined : true}\n    >\n      {spec.animated ? (\n        <style\n          href={WRAPPER_STYLE_HREF}\n          precedence=\"default\"\n          dangerouslySetInnerHTML={{ __html: WRAPPER_CSS }}\n        />\n      ) : null}\n      {spec.under}\n      {canvas}\n      {spec.over}\n    </div>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE",
          "target": "@components/voice-agents/orbkit/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 zzzzshawn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/orbkit/SOURCE.json",
          "target": "@components/voice-agents/orbkit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"OrbKit\",\n  \"repository\": \"https://github.com/zzzzshawn/orbkit\",\n  \"commit\": \"35e42484560fd35e8502703ba58fa99541d8c686\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 zzzzshawn\",\n  \"core\": \"components/voice-agents/orbkit/core.tsx\",\n  \"credits\": \"components/voice-agents/orbkit/CREDITS.md\",\n  \"shaderLicense\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\",\n  \"changes\": [\n    \"Moved the dependency-free OrbKit runtime and selected variants into the Agents Kit voice collection.\",\n    \"Mapped variant imports to the local shared runtime.\",\n    \"Kept the upstream reduced-motion, offscreen pause, DPR cap, context recovery, and cleanup behavior.\"\n  ],\n  \"exclusions\": [\n    {\n      \"name\": \"shdr-19\",\n      \"reason\": \"Non-commercial XorDev shader; excluded from this distributable MIT collection.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    },\n    {\n      \"name\": \"XorDev shader ports\",\n      \"reason\": \"All variants listed under Shaders by XorDev in CREDITS.md are non-commercial and excluded.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    }\n  ],\n  \"components\": [\n    {\n      \"name\": \"shdr-11\",\n      \"path\": \"shdr-11.tsx\",\n      \"title\": \"Hydrogen\"\n    },\n    {\n      \"name\": \"shdr-13\",\n      \"path\": \"shdr-13.tsx\",\n      \"title\": \"Ion\"\n    },\n    {\n      \"name\": \"shdr-14\",\n      \"path\": \"shdr-14.tsx\",\n      \"title\": \"Dither\"\n    },\n    {\n      \"name\": \"shdr-21\",\n      \"path\": \"shdr-21.tsx\",\n      \"title\": \"Nimbus\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/CREDITS.md",
          "target": "@components/voice-agents/orbkit/CREDITS.md",
          "type": "registry:file",
          "content": "# Credits\n\nOrbkit ships two kinds of orb. Every file says which it is.\n\n## Shaders by XorDev\n\nThese 19 orbs are ported from golfed shaders by [XorDev](https://x.com/XorDev),\nused with his permission (agreed by direct message on 2026-09-06). Terms:\n**non-commercial use only, with attribution to XorDev**. Each file starts with\na notice that must stay with any copy, and the registry marks these items with\na `credit` field. See [LICENSE-SHADERS.md](LICENSE-SHADERS.md).\n\n| Orb     | Shader by | Original             |\n| ------- | --------- | -------------------- |\n| shdr-01 | XorDev    | https://x.com/XorDev |\n| shdr-02 | XorDev    | https://x.com/XorDev |\n| shdr-03 | XorDev    | https://x.com/XorDev |\n| shdr-04 | XorDev    | https://x.com/XorDev |\n| shdr-05 | XorDev    | https://x.com/XorDev |\n| shdr-06 | XorDev    | https://x.com/XorDev |\n| shdr-07 | XorDev    | https://x.com/XorDev |\n| shdr-08 | XorDev    | https://x.com/XorDev |\n| shdr-09 | XorDev    | https://x.com/XorDev |\n| shdr-10 | XorDev    | https://x.com/XorDev |\n| shdr-15 | XorDev    | https://x.com/XorDev |\n| shdr-18 | XorDev    | https://x.com/XorDev |\n| shdr-19 | XorDev    | https://x.com/XorDev |\n| shdr-20 | XorDev    | https://x.com/XorDev |\n| shdr-22 | XorDev    | https://x.com/XorDev |\n| shdr-25 | XorDev    | https://x.com/XorDev |\n| shdr-26 | XorDev    | https://x.com/XorDev |\n| shdr-28 | XorDev    | https://x.com/XorDev |\n| shdr-31 | XorDev    | https://x.com/XorDev |\n\nReplace a profile link with the specific post once it is known.\n\n## Original orbs\n\nThese 14 orbs are Orbkit's own work and are MIT-licensed, like the runtime:\nshdr-11, shdr-12, shdr-13, shdr-14, shdr-16, shdr-17, shdr-21, shdr-23, shdr-24, shdr-27, shdr-29, shdr-30, shdr-32, shdr-33.\n\n## Adding shaders\n\nAsk the original author before porting anything that is not your own. XorDev\nasked to be consulted before any more of his work is included.\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "target": "@components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "type": "registry:file",
          "content": "# Licence for the ported shaders\n\nThe orb files listed under \"Shaders by XorDev\" in [CREDITS.md](CREDITS.md) are\nderived from shaders by XorDev (https://x.com/XorDev) and are used with the\nauthor's permission on these terms:\n\n1. Non-commercial use only.\n2. Attribution to XorDev must be kept with every copy, including the notice at\n   the top of each file.\n3. Any further use of XorDev's work requires asking the author first.\n\nEverything else in this repository, including the runtime\n(`orbkit-core.tsx`), the site, the build scripts, and the original orbs, is\nlicensed under the MIT licence in [LICENSE](LICENSE).\n"
        }
      ],
      "categories": [
        "OrbKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "orbkit-shdr-21",
      "type": "registry:block",
      "title": "Orbkit Shdr 21",
      "description": "Nimbus",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/voice-agents/orbkit/shdr-21.tsx",
          "target": "@components/voice-agents/orbkit/shdr-21.tsx",
          "type": "registry:component",
          "content": "/*\n * Deliberately not a `\"use client\"` module — see the note in `shdr-11.tsx`.\n *\n * Note for editors: the shader lives in a template literal, so its comments\n * must not contain backticks.\n */\nimport { ShaderOrb, type OrbVariant, type ShaderOrbProps } from \"./core\"\n\n/* ----------------------------------------------------------------------------\n   SHDR-21 — light diffusing through a cloud.\n\n   A real volumetric integration rather than a surface. The march walks a\n   density field bounded by a sphere and, at every step, does three things:\n\n     TRANSMITTANCE  how much of the background still gets through, tracked as\n                    T *= exp(-density * dt * absorb). Beer-Lambert.\n     SHADOW         a short second march toward the light, so the far side of a\n                    dense clump is dimmer than the lit side. This is the whole\n                    reason the orb reads as volume and not as a flat glow.\n     IN-SCATTER     light added at this step, weighted by density, by the shadow\n                    term, and by a Henyey-Greenstein phase function.\n\n   The phase function is what makes it feel like light rather than paint. It\n   biases scattering forward, so the limb facing the light blooms and the rest\n   stays soft — the same reason a cloud is blinding when you look toward the sun\n   through it and merely bright otherwise.\n\n   Alpha is 1 - T, which is exactly what the volume occludes, so this one needs\n   no radial fade to hide the canvas edge: density falls to zero at the sphere\n   boundary and the alpha goes with it.\n---------------------------------------------------------------------------- */\n\n/*\n * Step counts are `#define`s: ES 1.0 requires constant loop bounds. The march\n * is STEPS * (1 + LIGHT_STEPS) density evaluations, so LIGHT_STEPS is the\n * expensive knob — 4 is enough for readable self-shadowing.\n */\nconst NIMBUS_FRAG = `\n#define STEPS 56\n#define LIGHT_STEPS 4\n#define DENSITY_OCT 4\n#define AA 1\n\nconst float PI = 3.14159265359;\n\n// Volume-reactive values, resolved once per fragment in main().\nfloat nimbusPower;\nfloat nimbusDensity;\n\n/*\n  Density inside the sphere.\n\n  The radial term falls to zero at the boundary, which both bounds the volume\n  and gives the soft edge for free. The cos-warp folds the sample point a few\n  times — the same cheap turbulence the other orbs use — and the threshold\n  carves that into clumps rather than an even fog.\n*/\nfloat density(vec3 p, float animTime) {\n  float shell = 1.0 - length(p) / uP_radius;\n  if (shell <= 0.0) return 0.0;\n\n  vec3 q = p * uP_scale;\n  float f = 1.0;\n  for (int k = 0; k < DENSITY_OCT; k++) {\n    q += cos(q.yzx * f + animTime * uP_churn) / f;\n    f *= 1.8;\n  }\n\n  float n = (sin(q.x) + sin(q.y) + sin(q.z)) / 3.0 * 0.5 + 0.5;\n  // smoothstep against the threshold is the clump control: high threshold\n  // leaves sparse wisps, low fills the sphere with even fog\n  float clump = smoothstep(uP_threshold, 1.0, n);\n  return clump * pow(shell, uP_edgeSoft) * nimbusDensity;\n}\n\n/*\n  Henyey-Greenstein: g > 0 biases scattering forward, which is what gives the\n  bloom on the limb facing the light.\n\n  The physical form carries a 1/(4*PI) normalisation. It is dropped here and\n  folded into uP_power instead — kept in, the whole term sits around 0.02 and\n  the orb renders black unless power is pushed into the hundreds, which makes\n  the slider useless.\n*/\nfloat phaseHG(float c, float g) {\n  float g2 = g * g;\n  return (1.0 - g2) / pow(max(1.0 + g2 - 2.0 * g * c, 0.0001), 1.5);\n}\n\nvec4 nimbusRender(vec2 fragCoord) {\n  float animTime = uP_speed; // integrated clock\n\n  vec2 uv = (2.0 * fragCoord - uRes) / min(uRes.x, uRes.y);\n  vec3 ro = vec3(0.0, 0.0, -uP_camDist);\n  vec3 rd = normalize(vec3(uv, uP_focal));\n\n  /*\n    Light direction, slowly orbiting so the shading is never static.\n\n    The z term is kept POSITIVE — the camera looks along +z, so a light also\n    pointing along +z sits behind the cloud. That is the back-lit case, where\n    dot(rd, L) approaches 1 and the forward-scattering phase blooms. Put the\n    light on the camera's side instead and every ray samples the phase function\n    on its back-scatter tail, where it is roughly ten times smaller, and the orb\n    goes muddy.\n  */\n  vec3 L = normalize(vec3(\n    cos(animTime * uP_lightSpin) * 0.7,\n    0.45,\n    sin(animTime * uP_lightSpin) * 0.35 + 0.65\n  ));\n\n  float phase = phaseHG(dot(rd, L), uP_aniso);\n\n  // Start the march at the sphere's front face instead of the camera — every\n  // step before that contributes nothing, and at 56 steps they are expensive.\n  float toCentre = uP_camDist;\n  float tStart = max(toCentre - uP_radius, 0.0);\n  float span = 2.0 * uP_radius;\n  float dt = span / float(STEPS);\n\n  float T = 1.0;\n  vec3 scattered = vec3(0.0);\n\n  for (int i = 0; i < STEPS; i++) {\n    float t = tStart + (float(i) + 0.5) * dt;\n    vec3 p = ro + rd * t;\n\n    float dn = density(p, animTime);\n    if (dn > 0.001) {\n      // short march toward the light for self-shadowing\n      float shadow = 1.0;\n      float lstep = uP_radius / float(LIGHT_STEPS);\n      for (int k = 1; k <= LIGHT_STEPS; k++) {\n        vec3 lp = p + L * (float(k) - 0.5) * lstep;\n        shadow *= exp(-density(lp, animTime) * lstep * uP_shadowAbsorb);\n      }\n\n      /*\n        In-scattered light: warm where lit, cool where the volume shadows\n        itself.\n\n        The shadow term appears ONCE, inside the mix. Multiplying by it again\n        as a factor — the obvious-looking thing to write — scales the shadowed\n        end of the mix toward zero, so the cool colour is always multiplied\n        away and the cloud comes out monochrome beige however it is tinted.\n        uP_shadowLift is how much light still reaches the shadowed side.\n      */\n      vec3 lit = mix(uC_shadow * uP_shadowLift, uC_light, shadow);\n      scattered += T * dn * dt * lit * phase * nimbusPower;\n\n      T *= exp(-dn * dt * uP_absorb);\n      if (T < 0.01) break;\n    }\n  }\n\n  // a soft ambient body so the unlit side is not pure black\n  float body = 1.0 - T;\n  scattered += uC_shadow * body * uP_ambient;\n\n  return vec4(scattered, body);\n}\n\nvoid main() {\n  /*\n    Agent output turns the light up; user input thickens the cloud. Both are\n    AMPLITUDES. Churn is deliberately NOT volume-scaled: it multiplies the\n    accumulated clock into a phase (animTime * churn), so scaling it by the\n    live volume would turn every volume wobble into a phase jump the size of\n    the whole clock — the cloud scrambles chaotically on each state change\n    instead of gliding, and gets worse the longer the page is open.\n  */\n  nimbusPower = uP_power * (0.7 + 0.9 * uOutput);\n  nimbusDensity = uP_density * (1.0 + 0.35 * uInput);\n\n  vec4 acc = vec4(0.0);\n#if AA > 1\n  for (int mx = 0; mx < AA; mx++) {\n    for (int my = 0; my < AA; my++) {\n      vec2 offset = vec2(float(mx), float(my)) / float(AA) - 0.5;\n      acc += nimbusRender(gl_FragCoord.xy + offset);\n    }\n  }\n  acc /= float(AA * AA);\n#else\n  acc = nimbusRender(gl_FragCoord.xy);\n#endif\n\n  vec3 col = tanh3(acc.rgb * uP_exposure);\n  float a = clamp(acc.a * uP_alphaGain, 0.0, 1.0);\n\n  // Emitted/scattered light, so rgb is already premultiplied — do NOT multiply\n  // by alpha again (see the same note in shdr-31).\n  gl_FragColor = vec4(col, a);\n}\n`\n\nexport const shdr21Orb: OrbVariant = {\n  key: \"shdr-21\",\n  label: \"SHDR-21\",\n  note: \"light diffusing through a cloud\",\n  frag: NIMBUS_FRAG,\n  params: [\n    {\n      key: \"speed\",\n      label: \"Anim speed\",\n      min: 0.015,\n      max: 10,\n      step: 0.05,\n      default: 10,\n      integrate: true,\n    },\n    {\n      key: \"camDist\",\n      label: \"Camera distance\",\n      min: 0.5,\n      max: 40,\n      step: 0.2,\n      default: 4.4,\n    },\n    { key: \"focal\", label: \"Lens\", min: 0.3, max: 15, step: 0.1, default: 1.8 },\n    {\n      key: \"radius\",\n      label: \"Cloud radius\",\n      min: 0.15,\n      max: 10,\n      step: 0.05,\n      default: 2,\n    },\n    {\n      key: \"scale\",\n      label: \"Cloud scale\",\n      min: 0.1,\n      max: 15,\n      step: 0.1,\n      default: 0.8,\n    },\n    { key: \"churn\", label: \"Churn\", min: 0, max: 5, step: 0.03, default: 0.3 },\n    {\n      key: \"threshold\",\n      label: \"Clumping\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.075,\n    },\n    {\n      key: \"edgeSoft\",\n      label: \"Edge softness\",\n      min: 0.1,\n      max: 10,\n      step: 0.05,\n      default: 0.8,\n    },\n    {\n      key: \"density\",\n      label: \"Density\",\n      min: 0.03,\n      max: 20,\n      step: 0.1,\n      default: 3.2,\n    },\n    {\n      key: \"absorb\",\n      label: \"Absorption\",\n      min: 0.03,\n      max: 15,\n      step: 0.1,\n      default: 1.4,\n    },\n    {\n      key: \"shadowAbsorb\",\n      label: \"Shadow depth\",\n      min: 0,\n      max: 20,\n      step: 0.1,\n      default: 2.4,\n    },\n    {\n      key: \"shadowLift\",\n      label: \"Shadow lift\",\n      min: 0,\n      max: 5,\n      step: 0.03,\n      default: 0.55,\n    },\n    {\n      key: \"aniso\",\n      label: \"Forward scatter\",\n      min: -0.9,\n      max: 0.9,\n      step: 0.01,\n      default: 0.45,\n    },\n    {\n      key: \"lightSpin\",\n      label: \"Light orbit\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.12,\n    },\n    {\n      key: \"power\",\n      label: \"Light power\",\n      min: 0.03,\n      max: 40,\n      step: 0.2,\n      default: 1.9,\n    },\n    {\n      key: \"ambient\",\n      label: \"Ambient\",\n      min: 0,\n      max: 3,\n      step: 0.015,\n      default: 0.12,\n    },\n    {\n      key: \"exposure\",\n      label: \"Exposure\",\n      min: 0.03,\n      max: 10,\n      step: 0.05,\n      default: 1,\n    },\n    {\n      key: \"alphaGain\",\n      label: \"Alpha gain\",\n      min: 0.05,\n      max: 10,\n      step: 0.05,\n      default: 1.5,\n    },\n  ],\n  /*\n   * The engine uploads these as uC_<key> vec3 uniforms. Warm light against a\n   * cool shadow is what reads as depth — a single-hue cloud looks flat however\n   * well it is shadowed.\n   */\n  colors: [\n    { key: \"light\", label: \"Light\", default: \"#ffd7a3\" },\n    { key: \"shadow\", label: \"Shadow\", default: \"#3a4a8c\" },\n  ],\n  statePresets: {\n    /*\n      Every state shares the same speed, geometry and cloud shape — only the\n      AMBIENCE and the palette move, so switching state relights the cloud\n      instead of restaging it. The engine glides params and cross-fades\n      colours on one shared easing, so the change reads as a mood shift.\n    */\n    idle: {\n      ambient: 0.12,\n      power: 1.9,\n      shadowLift: 0.55,\n    },\n    thinking: {\n      ambient: 0.22,\n      power: 2.15,\n      shadowLift: 0.65,\n    },\n    speaking: {\n      ambient: 0.46,\n      power: 3.1,\n      shadowLift: 0.95,\n    },\n  },\n  /*\n    The palette carries the rest of the state read: a warm lamp over cool\n    shadow at rest, shifting violet while it thinks, and burning hot while\n    speaking.\n  */\n  stateColors: {\n    idle: { light: \"#ffd7a3\", shadow: \"#3a4a8c\" },\n    thinking: { light: \"#e6d4ff\", shadow: \"#3b3f96\" },\n    speaking: { light: \"#ffb066\", shadow: \"#7a2f6e\" },\n  },\n}\n\nexport type Shdr21Props = Omit<ShaderOrbProps, \"variant\">\n\nexport function Shdr21({ size = 280, ...rest }: Shdr21Props) {\n  return <ShaderOrb variant={shdr21Orb} size={size} {...rest} />\n}\n\nexport default Shdr21\n"
        },
        {
          "path": "components/voice-agents/orbkit/core.tsx",
          "target": "@components/voice-agents/orbkit/core.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport React, {\n  useEffect,\n  useRef,\n  useState,\n  type CSSProperties,\n  type ReactNode,\n} from \"react\"\n\n/* ----------------------------------------------------------------------------\n   Orbkit core — raw WebGL shader orb runtime. No dependencies.\n\n   An orb is a full-screen triangle rendered into a transparent canvas by a\n   fragment shader. Every orb declares a parameter schema (sliders + colors);\n   the values are uploaded as uniforms each frame from a ref, so a controls\n   panel can tune them live without ever remounting the canvas (a remount would\n   drop the WebGL context).\n\n   Animation model: every state synthesizes two volume signals — input (user\n   speech energy) and output (agent speech energy) — smooths them, and the\n   shaders react to those. The flow clock's speed itself follows the output\n   volume, so orbs visibly quicken when the agent is talking.\n---------------------------------------------------------------------------- */\n\nexport type OrbState = \"idle\" | \"thinking\" | \"speaking\"\n\nexport const ORB_STATES = [\"idle\", \"thinking\", \"speaking\"] as const\n\nfunction clamp01(n: number) {\n  return Math.min(1, Math.max(0, n))\n}\n\n/** Per-state [input, output] volume synthesis. */\n/**\n * Transition rate shared by params, colours and the flow-speed multiplier.\n * They must move together: if the rate multiplier eases faster than the look,\n * a state change spins the orb up before it has finished cross-fading, which\n * reads as a lurch.\n *\n * This drives a critically damped spring rather than the exponential ease it\n * used to. An exponential's velocity is highest at the instant the target\n * changes, so every state change began with a jolt — and for params that are\n * spatial frequencies (Corona's warpFreq travels 5.25 -> 19.5 between states)\n * that jolt sweeps the field through its intermediate frequencies at maximum\n * rate, which is what read as the transition \"scrambling\".\n *\n * A spring starts at rest and accelerates, so the sweep is spread across the\n * transition instead of front-loaded. Measured on that warpFreq move it is a\n * 20% lower peak rate of change (20.3/s vs 25.3/s) AND it arrives sooner —\n * 1.50s to within 2% against the exponential's 2.18s, since an exponential\n * only ever asymptotes toward its target.\n */\nconst PARAM_EASE = 4\n\n/*\n  One step of a critically damped spring, implicit (semi-implicit Euler would\n  blow up at the frame times a backgrounded tab produces). Returns nothing and\n  writes through the scratch pair so the hot loop allocates nothing.\n*/\nconst springOut = { x: 0, v: 0 }\nfunction springStep(\n  x: number,\n  v: number,\n  target: number,\n  dt: number,\n  omega: number\n) {\n  const f = 1 + 2 * dt * omega\n  const oo = omega * omega\n  const hoo = dt * oo\n  const hhoo = dt * hoo\n  const detInv = 1 / (f + hhoo)\n  springOut.x = (f * x + dt * v + hhoo * target) * detInv\n  springOut.v = (v + hoo * (target - x)) * detInv\n}\n\nfunction targetVolumes(state: OrbState, t: number): [number, number] {\n  switch (state) {\n    case \"idle\":\n      return [0, 0.3]\n    case \"speaking\":\n      return [\n        clamp01(0.65 + Math.sin(t * 4.8) * 0.22),\n        clamp01(0.75 + Math.sin(t * 3.6) * 0.22),\n      ]\n    case \"thinking\": {\n      const base = 0.38 + 0.07 * Math.sin(t * 0.7)\n      const wander = 0.05 * Math.sin(t * 2.1) * Math.sin(t * 0.37 + 1.2)\n      return [\n        clamp01(base + wander),\n        clamp01(0.48 + 0.12 * Math.sin(t * 1.05 + 0.6)),\n      ]\n    }\n  }\n}\n\n/* ------------------------------ param schema ------------------------------- */\n\nexport interface OrbParamDef {\n  key: string\n  label: string\n  min: number\n  max: number\n  step: number\n  default: number\n  /**\n   * Rate params. The engine integrates them into a clock\n   * (`clock += dt * value * volumeSpeed`) and uploads the clock instead of the\n   * raw value, so changing the rate never jumps the phase — the motion speeds\n   * up or slows down rather than snapping to a new position.\n   */\n  integrate?: boolean\n}\n\nexport interface OrbColorDef {\n  key: string\n  label: string\n  /** hex, e.g. `#ff8b73` */\n  default: string\n}\n\nexport interface OrbVariant {\n  key: string\n  label: string\n  note: string\n  /** GLSL fragment shader body. Uniform declarations are generated for you. */\n  frag: string\n  params: OrbParamDef[]\n  colors: OrbColorDef[]\n  /**\n   * Per-state parameter targets. The engine glides each param toward the\n   * active state's preset. Params passed explicitly via the `params` prop\n   * always win over the preset.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /**\n   * Per-state colour targets, the colour counterpart of `statePresets`.\n   * Kept a separate map because presets are numeric and colours are hex\n   * strings — a union would lose type safety on both. Colours glide in RGB\n   * on the same easing as params, so a state change cross-fades rather\n   * than cutting. Colours passed explicitly via the `colors` prop always\n   * win, exactly as with params.\n   */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n}\n\nexport type OrbParamValues = Partial<Record<string, number>>\nexport type OrbColorValues = Partial<Record<string, string>>\n\n/** Every param and color at its schema default. */\nexport function defaultValuesFor(variant: OrbVariant): {\n  params: Record<string, number>\n  colors: Record<string, string>\n} {\n  return {\n    params: Object.fromEntries(variant.params.map((p) => [p.key, p.default])),\n    colors: Object.fromEntries(variant.colors.map((c) => [c.key, c.default])),\n  }\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace(\"#\", \"\").trim()\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]\n  const n = parseInt(h, 16)\n  if (h.length !== 6 || Number.isNaN(n)) return [1, 1, 1]\n  return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255]\n}\n\n/* ------------------------------- GLSL shared ------------------------------- */\n\nconst VERT = `\nattribute vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\n/**\n * Prelude prepended to every orb fragment shader: uniforms, value noise, fbm,\n * and the centered aspect-corrected UV helper.\n */\nexport const ORB_GLSL_HELPERS = `\nprecision highp float;\nuniform vec2 uRes;\nuniform float uTime;   // slow ambient clock (half real-time)\nuniform float uAnim;   // flow clock — its speed follows the output volume\nuniform float uInput;  // input volume 0..1: user speech energy\nuniform float uOutput; // output volume 0..1: agent speech energy\n\nfloat hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123); }\nfloat noise(vec2 p) {\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);\n  return mix(\n    mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x),\n    mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x),\n    f.y\n  );\n}\nfloat fbm(vec2 p) {\n  float v = 0.0;\n  float a = 0.5;\n  for (int i = 0; i < 5; i++) {\n    v += a * noise(p);\n    p = p * 2.03 + vec2(11.7, 7.3);\n    a *= 0.5;\n  }\n  return v;\n}\nvec2 orbUV() { return (2.0 * gl_FragCoord.xy - uRes) / min(uRes.x, uRes.y); }\n\n// GLSL ES 1.0 has no tanh() — it arrived in ES 3.0. Shader-golf listings lean\n// on it as a tone-mapper, so it ships here. Clamped against exp() overflow;\n// accurate for the non-negative accumulators those shaders produce.\nvec3 tanh3(vec3 x) {\n  x = clamp(x, -10.0, 10.0);\n  vec3 e = exp(2.0 * x);\n  return (e - 1.0) / (e + 1.0);\n}\n\n`\n\nfunction paramUniformDecls(variant: OrbVariant): string {\n  return [\n    ...variant.params.map((p) => `uniform float uP_${p.key};`),\n    ...variant.colors.map((c) => `uniform vec3 uC_${c.key};`),\n  ].join(\"\\n\")\n}\n\n/* ------------------------------- engine ------------------------------------ */\n\n/**\n * Per-canvas context-lifecycle controller. Created on first mount of a canvas\n * and kept for the element's whole life — the router can hide a page and show\n * the same DOM again, and React re-runs effects on the same canvas, so the\n * lost/restored listeners must outlive any single effect run: an uncanceled\n * webglcontextlost event marks the context permanently unrestorable.\n */\ninterface CanvasContextController {\n  /** Whether a mounted orb currently wants this context alive. */\n  desired: boolean\n  /** Builds a render generation; returns its teardown. Rebound per effect run. */\n  start: (() => () => void) | null\n  /** Teardown of the live generation, if one is running. */\n  stopGen: (() => void) | null\n}\n\nconst canvasControllers = new WeakMap<\n  HTMLCanvasElement,\n  CanvasContextController\n>()\n\nfunction compile(\n  gl: WebGLRenderingContext,\n  type: number,\n  src: string\n): WebGLShader | null {\n  const shader = gl.createShader(type)\n  if (!shader) return null\n  gl.shaderSource(shader, src)\n  gl.compileShader(shader)\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    console.error(\"[orbkit] shader compile error:\", gl.getShaderInfoLog(shader))\n    gl.deleteShader(shader)\n    return null\n  }\n  return shader\n}\n\n/* ----------------------------------------------------------------------------\n   Wrappers — optional decoration drawn around, under and over the orb.\n\n   A wrapper is pure CSS/SVG, never a shader: the orb keeps its own canvas and\n   the decoration is composited on top of it by the browser. That keeps the\n   whole set free for any orb (no per-variant shader work), costs nothing on\n   the GPU budget the shaders are already spending, and means swapping one\n   wrapper for another at runtime never touches the WebGL context. Turning a\n   wrapper on or off does, since that is what moves the canvas into or out of\n   the wrapper element — see the effect's `wrapped` dependency.\n\n   Layout: a wrapped orb becomes a square box, and the canvas is absolutely\n   positioned inside it with the spec's `inset`. The FOOTPRINT is unchanged —\n   `size` is still the outer diameter — so dropping a wrapper onto an existing\n   orb reflows nothing; the orb itself just shrinks to leave the ring room.\n\n   Colour: every layer that isn't physically light or shadow paints in\n   `currentColor`, so a wrapper picks up the surrounding text colour and reads\n   correctly on light and dark pages with no configuration. `wrapperColor`\n   sets that colour when you want something other than the inherited one.\n---------------------------------------------------------------------------- */\n\nexport const ORB_WRAPPERS = [\n  \"none\",\n  \"glass\",\n  \"ring\",\n  \"dotted\",\n  \"ticks\",\n  \"reticle\",\n  \"grid\",\n  \"halftone\",\n  \"scanlines\",\n] as const\n\nexport type OrbWrapper = (typeof ORB_WRAPPERS)[number]\n\n/*\n  Keyframes for the animated wrappers, shipped inside the component so an orb\n  stays a single self-contained file with nothing to add to a global\n  stylesheet. React 19 hoists a <style href precedence> into <head> and\n  de-duplicates it, so a page full of wrapped orbs emits this exactly once;\n  older React renders it inline, which is redundant but harmless.\n\n  Reduced motion parks all of it. The shader runtime already honours the same\n  preference for the orb itself (see the reduce-motion branch in the render\n  loop), and a ring that keeps spinning around a frozen orb would be the worse\n  half of the two still moving.\n*/\nconst WRAPPER_STYLE_HREF = \"orbkit-wrapper\"\nconst WRAPPER_CSS = `\n@keyframes orbkit-w-spin { to { transform: rotate(360deg); } }\n@keyframes orbkit-w-roll { from { transform: translateY(-110%); } to { transform: translateY(360%); } }\n@media (prefers-reduced-motion: reduce) {\n  .orbkit-w-anim { animation: none !important; }\n}\n`\n\ninterface WrapperSpec {\n  /**\n   * How far the canvas sits inside the box, in percent, leaving the\n   * decoration room. Applied as explicit width/height rather than as `inset`:\n   * a canvas is a REPLACED element, so an absolutely positioned one with\n   * `left` and `right` both set does not stretch between them — it keeps its\n   * intrinsic size and the over-constrained edge is dropped. The orb would\n   * then be drawn into a canvas the size of the page.\n   */\n  inset: number\n  /**\n   * Soft circular mask on the canvas. Only the wrappers that read as a\n   * CONTAINER set one — a bubble has to hold the orb, whereas a bezel sits\n   * beside it and clipping the halo there would just amputate the glow.\n   */\n  mask?: string\n  /** Cast by the assembly as a whole, on the outer box. */\n  shadow?: string\n\n  /** True when the spec uses one of the keyframes above. */\n  animated?: boolean\n  /** Painted beneath the canvas. */\n  under?: ReactNode\n  /** Painted over it. */\n  over?: ReactNode\n}\n\nconst DISC: CSSProperties = { borderRadius: \"50%\" }\n\n/** One absolutely-positioned decoration layer, filling the wrapper box. */\nfunction Layer({\n  inset = 0,\n  style,\n  className,\n}: {\n  inset?: number | string\n  style: CSSProperties\n  className?: string\n}) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={className}\n      style={{ position: \"absolute\", inset, pointerEvents: \"none\", ...style }}\n    />\n  )\n}\n\n/**\n * A free-floating highlight — glass's specular and its bounce. These do not go\n * through `Layer` because they are placed with `left`/`top`/`width`, and a\n * style object that sets those on top of `Layer`'s `inset` shorthand is mixing\n * shorthand and longhand for the same property: React warns about it, and the\n * result depends on key order rather than on anything you would want to rely\n * on.\n */\nfunction Highlight({ style }: { style: CSSProperties }) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      style={{\n        position: \"absolute\",\n        borderRadius: \"50%\",\n        pointerEvents: \"none\",\n        ...style,\n      }}\n    />\n  )\n}\n\n/**\n * The mask that makes a wrapper HOLD the orb: cuts the canvas back to the\n * bubble and stops a hairline short of the rim, so the orb never quite touches\n * the glass.\n *\n * The percentage has to be derived rather than written down. `closest-side`\n * measures the CANVAS, and a wrapper with a negative inset draws its canvas\n * LARGER than the bubble — at -7 the canvas is 114% of the box, so the rim\n * sits at 100/1.14 = 87.7% of the canvas's own radius, not at 100%.\n *\n * The gap is real pixels rather than a share of the size: it reads as the same\n * band at 120px and at 900px, which a percentage would not.\n */\nconst RIM_GAP_PX = 4\n\nfunction rimMask(inset: number): string {\n  const rim = (100 / (1 - (2 * inset) / 100)).toFixed(2)\n  // Feathered over the final pixel, so the cut is not a razor edge.\n  const solid = RIM_GAP_PX + 0.5\n  const clear = RIM_GAP_PX - 0.5\n  return `radial-gradient(circle closest-side, #000 calc(${rim}% - ${solid}px), rgba(0,0,0,0) calc(${rim}% - ${clear}px))`\n}\n\n/** Both spellings, since Safari still wants the prefix for mask-image. */\nfunction masked(image: string): CSSProperties {\n  return { WebkitMaskImage: image, maskImage: image }\n}\n\nconst svgLayer: CSSProperties = {\n  position: \"absolute\",\n  inset: 0,\n  width: \"100%\",\n  height: \"100%\",\n  pointerEvents: \"none\",\n  overflow: \"visible\",\n}\n\n/** Glass's overfill, shared by its inset and the mask derived from it. */\nconst GLASS_INSET = -4\n\nconst WRAPPER_SPECS: Record<Exclude<OrbWrapper, \"none\">, WrapperSpec> = {\n  /*\n    glass — a blown bubble with the orb suspended inside it.\n\n    Five layers in the order light actually arrives: the body brightening\n    toward the key light, the Fresnel ring where a sphere's edge turns almost\n    edge-on and reflects nearly everything, the rim itself, the window\n    reflection, and the bounce coming back up off whatever the bubble is\n    sitting on. All of it is white and black rather than `currentColor` —\n    glass has no colour of its own, only the light it moves around.\n  */\n  glass: {\n    /*\n      Negative on purpose. An orb's shader does not necessarily paint to the\n      edge of its canvas — most draw a sphere with transparent margin around\n      it — so a canvas sized to the bubble leaves a dead ring between the orb\n      and the rim, which is not what a thing suspended in glass looks like.\n      Oversizing the canvas by 14% pushes the sphere out to the rim, and\n      `rimMask` cuts whatever overflows — a few pixels short of the glass, so\n      the orb sits just inside it rather than welded to it. Orbs that already fill\n      their canvas lose a few percent off the limb, which is the same crop the\n      reference bubble makes.\n    */\n    inset: GLASS_INSET,\n    mask: rimMask(GLASS_INSET),\n    shadow: \"0 24px 48px -26px rgba(0,0,0,0.55)\",\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(ellipse 80% 70% at 28% 20%, rgba(255,255,255,0.16), rgba(255,255,255,0.03) 45%, rgba(255,255,255,0) 72%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(255,255,255,0) 0%, rgba(255,255,255,0.0) 55%, rgba(255,255,255,0.05) 99.5%, rgba(255,255,255,0) 100%)\",\n            overflow: \"hidden\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow: \"3px 6px 10px #ffffff20 inset\",\n          }}\n        />\n        {/*\n          The shell's own darkening, just inside the rim. Invisible on a dark\n          page — it is black over black — and doing all the work on a light\n          one, where the white highlights below have nothing to stand out\n          against and the bubble would otherwise read as a bare drop shadow.\n        */}\n        <Layer\n          style={{\n            ...DISC,\n            background:\n              \"radial-gradient(circle closest-side, rgba(0,0,0,0) 78%, rgba(0,0,0,0.05) 93%, rgba(0,0,0,0.02) 100%)\",\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            boxShadow:\n              \"inset 0 6px 12px -7px rgba(255,255,255,0.05), inset 0 -9px 16px -9px rgba(255,255,255,0.1), 0 0 0 1px rgba(0,0,0,0.07)\",\n          }}\n        />\n        <Highlight\n          style={{\n            left: \"15%\",\n            top: \"10%\",\n            width: \"38%\",\n            height: \"22%\",\n            transform: \"rotate(-25deg)\",\n            background:\n              \"radial-gradient(closest-side, rgba(255,255,255,0.9), rgba(255,255,255,0.3) 55%, rgba(255,255,255,0) 100%)\",\n            filter: \"blur(10px)\",\n          }}\n        />\n      </>\n    ),\n  },\n\n  /* ring — two hairlines and nothing else. The restrained one. */\n  ring: {\n    inset: 9,\n    over: (\n      <>\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.22 }}\n        />\n        <Layer\n          inset=\"5%\"\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.1 }}\n        />\n      </>\n    ),\n  },\n\n  /*\n    dotted — evenly spaced dots around the circumference, turning slowly.\n\n    Drawn as one dashed circle with round caps and a near-zero dash length, so\n    each dash collapses to a dot. `pathLength=\"64\"` renormalizes the path to 64\n    units first, which is what makes the count exact: the dash period is\n    literally 1/64th of the circle, so the pattern closes on itself with no\n    seam where the last gap would otherwise be short.\n  */\n  dotted: {\n    inset: 10,\n    animated: true,\n    over: (\n      <svg\n        aria-hidden=\"true\"\n        viewBox=\"0 0 100 100\"\n        className=\"orbkit-w-anim\"\n        style={{ ...svgLayer, animation: \"orbkit-w-spin 48s linear infinite\" }}\n      >\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"47\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.7\"\n          strokeLinecap=\"round\"\n          pathLength={64}\n          strokeDasharray=\"0.0001 0.9999\"\n          opacity={0.45}\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    ticks — an instrument bezel: a fine minor scale every 6 degrees with a\n    longer major tick every 30. Both are one repeating conic gradient masked\n    down to an annulus, so the tick count is set by the gradient's period and\n    the tick LENGTH by how far in the mask reaches.\n  */\n  ticks: {\n    inset: 12,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.32,\n            background:\n              \"repeating-conic-gradient(from -0.5deg, transparent 0deg 0.2deg, currentColor 0.4deg 0.6deg, transparent 0.8deg 6deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 88%, #000 90%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{\n            ...DISC,\n            opacity: 0.6,\n            background:\n              \"repeating-conic-gradient(from -0.75deg, transparent 0deg 0.25deg, currentColor 0.5deg 1deg, transparent 1.25deg 30deg)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, transparent 80%, #000 82%, #000 97%, transparent 99%)\"\n            ),\n          }}\n        />\n        <Layer\n          style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.12 }}\n        />\n      </>\n    ),\n  },\n\n  /* reticle — viewfinder furniture: corner brackets, cardinal ticks, a track. */\n  reticle: {\n    inset: 13,\n    over: (\n      <svg aria-hidden=\"true\" viewBox=\"0 0 100 100\" style={svgLayer}>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" opacity=\"0.5\">\n          <path d=\"M1 13 L1 1 L13 1\" />\n          <path d=\"M87 1 L99 1 L99 13\" />\n          <path d=\"M99 87 L99 99 L87 99\" />\n          <path d=\"M13 99 L1 99 L1 87\" />\n        </g>\n        <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.38\">\n          <path d=\"M50 1 L50 9\" />\n          <path d=\"M50 91 L50 99\" />\n          <path d=\"M1 50 L9 50\" />\n          <path d=\"M91 50 L99 50\" />\n        </g>\n        <circle\n          cx=\"50\"\n          cy=\"50\"\n          r=\"46\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"0.7\"\n          opacity=\"0.22\"\n        />\n      </svg>\n    ),\n  },\n\n  /*\n    grid — a graticule laid over the orb and masked back to the disc, so the\n    mesh appears to be etched on the glass in front of it rather than drawn on\n    the page behind. The lines are 1px whatever the size; the SPACING is a\n    percentage, so the cell count holds from a gallery thumbnail to a\n    full-bleed hero.\n  */\n  grid: {\n    inset: 8,\n    /*\n      The ruling sits UNDER the canvas: graph paper the orb rests on, not a\n      mesh laid over its face. Drawn on top it crosshatched the shader — the\n      one thing the wrapper is meant to frame. The ring stays over, since it\n      only ever meets the transparent margin at the canvas edge.\n    */\n    under: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.18,\n          backgroundImage:\n            \"repeating-linear-gradient(to right, currentColor 0 1px, transparent 1px 12.5%), repeating-linear-gradient(to bottom, currentColor 0 1px, transparent 1px 12.5%)\",\n          ...masked(\n            \"radial-gradient(circle closest-side, #000 86%, rgba(0,0,0,0) 99%)\"\n          ),\n        }}\n      />\n    ),\n    over: (\n      <Layer\n        style={{ ...DISC, border: \"1px solid currentColor\", opacity: 0.2 }}\n      />\n    ),\n  },\n\n  /*\n    halftone — a print screen over the outer band of the orb. The mask keeps\n    the middle clear, so the dots read as the image breaking up toward its\n    edge instead of a texture pasted across the whole face.\n  */\n  halftone: {\n    inset: 6,\n    over: (\n      <Layer\n        style={{\n          ...DISC,\n          opacity: 0.5,\n          backgroundImage: \"radial-gradient(currentColor 22%, transparent 24%)\",\n          backgroundSize: \"7px 7px\",\n          ...masked(\n            \"radial-gradient(circle closest-side, transparent 40%, #000 80%, #000 94%, rgba(0,0,0,0) 100%)\"\n          ),\n        }}\n      />\n    ),\n  },\n\n  /*\n    scanlines — a phosphor tube. Black lines rather than `currentColor`,\n    because scanlines are the UNLIT gaps between rows and stay dark whatever\n    the page is; the slow bright band rolling down is the vertical hold\n    drifting, which is the part that reads as a CRT rather than as stripes.\n  */\n  scanlines: {\n    inset: 0,\n    animated: true,\n    over: (\n      <>\n        <Layer\n          style={{\n            ...DISC,\n            backgroundImage:\n              \"repeating-linear-gradient(to bottom, rgba(0,0,0,0.45) 0 1px, rgba(0,0,0,0) 1px 3px)\",\n            ...masked(\n              \"radial-gradient(circle closest-side, #000 84%, rgba(0,0,0,0) 100%)\"\n            ),\n          }}\n        />\n        <span\n          aria-hidden=\"true\"\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            borderRadius: \"50%\",\n            overflow: \"hidden\",\n            pointerEvents: \"none\",\n          }}\n        >\n          <span\n            className=\"orbkit-w-anim\"\n            style={{\n              position: \"absolute\",\n              left: 0,\n              right: 0,\n              top: 0,\n              height: \"30%\",\n              background:\n                \"linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,0.07) 50%, rgba(255,255,255,0) 100%)\",\n              animation: \"orbkit-w-roll 7s linear infinite\",\n            }}\n          />\n        </span>\n        <Layer\n          style={{ ...DISC, boxShadow: \"inset 0 0 40px -8px rgba(0,0,0,0.5)\" }}\n        />\n      </>\n    ),\n  },\n}\n\nexport interface ShaderOrbProps {\n  /** The orb definition: shader + param schema + state presets. */\n  variant: OrbVariant\n  /** Drives the synthesized volume signals. Defaults to `\"idle\"`. */\n  state?: OrbState\n  /** Rendered size in CSS pixels. Ignored when `className` sizes the canvas. */\n  size?: number\n  /** Explicit param overrides. Any key present here wins over the state preset. */\n  params?: OrbParamValues\n  /** Explicit color overrides, as hex strings. */\n  colors?: OrbColorValues\n  /**\n   * Per-state parameter targets, overriding the variant's own. Merged KEY BY\n   * KEY over what the orb already defines, so `{ thinking: { churn: 1.62 } }`\n   * retouches one param of one state and leaves every other param — and the\n   * other two states — exactly as the orb ships them.\n   *\n   * This is the prop form of the variant's `statePresets`, so you can retune\n   * an orb's states from the outside without forking its file. Values still\n   * glide, so switching states cross-fades into your targets. An explicit\n   * `params` value outranks this, the same way it outranks the variant.\n   */\n  statePresets?: Partial<Record<OrbState, Record<string, number>>>\n  /** The colour counterpart of `statePresets`, merged the same key-by-key way. */\n  stateColors?: Partial<Record<OrbState, Record<string, string>>>\n  /**\n   * Per-state volume drive, the third member of the same family. Use it to\n   * give each state its own energy; use `volumes` below instead when you have\n   * a real signal to feed in, such as live mic level.\n   */\n  stateVolumes?: Partial<Record<OrbState, { input?: number; output?: number }>>\n  /**\n   * Overrides the synthesized volume signals for the active state. The engine\n   * normally derives these from `state` — a slow breath at idle, a restless\n   * wander while thinking, speech-shaped peaks while speaking — and most\n   * shaders read them as their reactivity. Setting either channel here pins\n   * it instead, which is how the playground lets you dial each state's drive\n   * independently. Omit a channel to keep its synthesized motion.\n   */\n  volumes?: { input?: number; output?: number }\n  /** Freeze the animation on the current frame. */\n  paused?: boolean\n  /**\n   * Stop rendering while the orb is scrolled out of view. Defaults to `true` —\n   * a page full of orbs would otherwise run a WebGL loop per card.\n   */\n  pauseOffscreen?: boolean\n  /** Device-pixel-ratio ceiling. Defaults to `2`. */\n  maxDpr?: number\n  /**\n   * Decoration drawn around the orb — a glass bubble, a dotted bezel, a\n   * viewfinder. Defaults to `\"none\"`, which renders the bare canvas exactly as\n   * it always has, with no extra element in the tree.\n   *\n   * A wrapper never changes the orb's footprint: `size` stays the outer\n   * diameter and the canvas is inset inside it, so switching one on reflows\n   * nothing around it.\n   */\n  wrapper?: OrbWrapper\n  /**\n   * The colour a wrapper draws its lines and dots in. Defaults to\n   * `currentColor` — the inherited text colour — which is what makes the\n   * bezels legible on a light and a dark page without being told which one\n   * they are on. `glass` ignores it: glass has no colour of its own.\n   */\n  wrapperColor?: string\n  /** Applied to the outermost element — the wrapper when there is one. */\n  className?: string\n  /** Merged onto the outermost element's style. */\n  style?: CSSProperties\n  /** Accessible label. When omitted the orb is hidden from assistive tech. */\n  ariaLabel?: string\n}\n\nexport function ShaderOrb({\n  variant,\n  state = \"idle\",\n  size,\n  params,\n  colors,\n  statePresets,\n  stateColors,\n  stateVolumes,\n  volumes,\n  paused = false,\n  pauseOffscreen = true,\n  maxDpr = 2,\n  wrapper = \"none\",\n  wrapperColor,\n  className,\n  style,\n  ariaLabel,\n}: ShaderOrbProps) {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n  const spec = wrapper === \"none\" ? undefined : WRAPPER_SPECS[wrapper]\n  const wrapped = spec !== undefined\n\n  // Live refs: the render loop reads these every frame, so changing a param\n  // never re-runs the GL setup effect (which would drop the context). Synced in\n  // an effect rather than during render — a ref write during render is unsafe\n  // under concurrent rendering, and the loop picks the new value up on the very\n  // next frame anyway.\n  /*\n    Whether the canvas has drawn a frame yet, tracked per variant because a\n    variant swap mounts a brand new canvas (see the `key` below).\n\n    A mounted-but-never-drawn canvas is at the browser's mercy: rather than\n    the transparent rectangle you would expect, a page that mounts a dozen at\n    once gets white boxes — and in some browsers a broken-image placeholder —\n    for as long as the compositor has nothing to raster. That window is not\n    small here: every orb compiles a full fragment shader synchronously in its\n    own mount effect, so on the gallery grid the first canvases sit empty\n    while the last ones are still compiling. Holding each canvas invisible\n    until its own first frame lands is what makes the grid fade in cleanly\n    instead of flashing. One state change per orb, once, on mount.\n  */\n  const [paintedKey, setPaintedKey] = useState<string | null>(null)\n  const painted = paintedKey === variant.key\n\n  const stateRef = useRef<OrbState>(state)\n  const paramsRef = useRef<OrbParamValues | undefined>(params)\n  const colorsRef = useRef<OrbColorValues | undefined>(colors)\n  const statePresetsRef = useRef(statePresets)\n  const stateColorsRef = useRef(stateColors)\n  const stateVolumesRef = useRef(stateVolumes)\n  const volumesRef = useRef(volumes)\n  const pausedRef = useRef(paused)\n\n  useEffect(() => {\n    stateRef.current = state\n    paramsRef.current = params\n    colorsRef.current = colors\n    statePresetsRef.current = statePresets\n    stateColorsRef.current = stateColors\n    stateVolumesRef.current = stateVolumes\n    volumesRef.current = volumes\n    pausedRef.current = paused\n  }, [\n    state,\n    params,\n    colors,\n    statePresets,\n    stateColors,\n    stateVolumes,\n    volumes,\n    paused,\n  ])\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    const gl = canvas.getContext(\"webgl\", {\n      alpha: true,\n      // No MSAA: the geometry is a single full-screen triangle, so there are no\n      // primitive edges to antialias — softness comes from the shaders. Leaving\n      // it on costs the multisample buffers plus a resolve every frame.\n      antialias: false,\n      premultipliedAlpha: true,\n    })\n    if (!gl) return\n\n    const loseExt = gl.getExtension(\"WEBGL_lose_context\")\n\n    /*\n      A \"generation\" is everything tied to a live context: program, buffers,\n      observers, render loop. Browsers cap live WebGL contexts per page and\n      evict the oldest past the cap, and an evicted orb's canvas stays blank\n      forever unless the app rebuilds — so generations tear down and rebuild on\n      the lost/restored events instead of assuming the context is immortal.\n    */\n    let announcedPaint = false\n\n    const startGeneration = (): (() => void) => {\n      if (gl.isContextLost()) return () => {}\n      // Every generation announces its own first frame: a context that was\n      // lost and restored has an empty drawing buffer and is hidden again\n      // (below), so it has to earn its reveal back.\n      announcedPaint = false\n\n      const vs = compile(gl, gl.VERTEX_SHADER, VERT)\n      const fs = compile(\n        gl,\n        gl.FRAGMENT_SHADER,\n        ORB_GLSL_HELPERS + paramUniformDecls(variant) + variant.frag\n      )\n      const releaseShaders = () => {\n        if (vs) gl.deleteShader(vs)\n        if (fs) gl.deleteShader(fs)\n      }\n      if (!vs || !fs) return releaseShaders\n\n      const prog = gl.createProgram()\n      if (!prog) return releaseShaders\n      gl.attachShader(prog, vs)\n      gl.attachShader(prog, fs)\n      gl.linkProgram(prog)\n      if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n        console.error(\n          \"[orbkit] program link error:\",\n          gl.getProgramInfoLog(prog)\n        )\n        gl.deleteProgram(prog)\n        return releaseShaders\n      }\n      gl.useProgram(prog)\n\n      const buf = gl.createBuffer()\n      gl.bindBuffer(gl.ARRAY_BUFFER, buf)\n      gl.bufferData(\n        gl.ARRAY_BUFFER,\n        new Float32Array([-1, -1, 3, -1, -1, 3]),\n        gl.STATIC_DRAW\n      )\n      const aPos = gl.getAttribLocation(prog, \"aPos\")\n      gl.enableVertexAttribArray(aPos)\n      gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0)\n\n      gl.enable(gl.BLEND)\n      gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)\n\n      const uRes = gl.getUniformLocation(prog, \"uRes\")\n      const uTime = gl.getUniformLocation(prog, \"uTime\")\n      const uAnim = gl.getUniformLocation(prog, \"uAnim\")\n      const uInput = gl.getUniformLocation(prog, \"uInput\")\n      const uOutput = gl.getUniformLocation(prog, \"uOutput\")\n\n      const paramLocs = variant.params.map((p) => ({\n        def: p,\n        loc: gl.getUniformLocation(prog, `uP_${p.key}`),\n      }))\n      const colorLocs = variant.colors.map((c) => ({\n        def: c,\n        loc: gl.getUniformLocation(prog, `uC_${c.key}`),\n      }))\n\n      /* --- sizing: track the element box, not a one-shot measurement ------- */\n      // Backing-store scale, stepped down by the adaptive-resolution logic in\n      // the loop when the GPU can't hold frame rate. CSS size never changes —\n      // the browser upscales, which these soft shaders absorb gracefully.\n      let resScale = 1\n      const resize = () => {\n        const dpr = Math.min(window.devicePixelRatio || 1, maxDpr) * resScale\n        const w = Math.max(1, Math.round(canvas.clientWidth * dpr))\n        const h = Math.max(1, Math.round(canvas.clientHeight * dpr))\n        if (canvas.width !== w || canvas.height !== h) {\n          canvas.width = w\n          canvas.height = h\n          gl.viewport(0, 0, w, h)\n        }\n        /*\n          Uploaded UNCONDITIONALLY, outside the size guard. A rebuilt\n          generation (React strict-mode remount, a restored context) links a\n          fresh program whose uRes starts at zero — and the canvas usually\n          already holds the right backing size, so an upload gated behind\n          the resize never ran. With uRes = 0, orbUV() divides by zero and\n          every fragment lands transparent: a healthy context, a bound\n          program, and a permanently blank orb.\n        */\n        gl.uniform2f(uRes, w, h)\n      }\n      resize()\n\n      const resizeObserver =\n        typeof ResizeObserver !== \"undefined\"\n          ? new ResizeObserver(resize)\n          : null\n      resizeObserver?.observe(canvas)\n\n      /* --- visibility: don't burn a render loop on an offscreen orb -------- */\n      let visible = !pauseOffscreen\n      const intersectionObserver =\n        pauseOffscreen && typeof IntersectionObserver !== \"undefined\"\n          ? new IntersectionObserver(\n              (entries) => {\n                visible = Boolean(entries[0]?.isIntersecting)\n                if (visible) {\n                  last = performance.now() / 1000\n                }\n              },\n              { rootMargin: \"150px 0px\", threshold: 0 }\n            )\n          : null\n      if (intersectionObserver) {\n        intersectionObserver.observe(canvas)\n      } else {\n        visible = true\n      }\n\n      const reduceMotion =\n        typeof window.matchMedia === \"function\" &&\n        window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n\n      /* --- driver state ---------------------------------------------------- */\n      let tSec = 0\n      // random phase so two orbs on the same page never look synchronized\n      let anim = Math.random() * 100\n      let speed = 0.1\n      const cur = { in: 0, out: 0.3 }\n      const presets = variant.statePresets\n      const paramCur: Record<string, number> = {}\n      const paramVel: Record<string, number> = {}\n      const paramClocks: Record<string, number> = {}\n      const colorCur: Record<string, [number, number, number]> = {}\n      const colorVel: Record<string, [number, number, number]> = {}\n      let speedVel = 0\n      const [initialIn, initialOut] = targetVolumes(stateRef.current, 0)\n      cur.in = initialIn\n      cur.out = initialOut\n      let last = performance.now() / 1000\n      let raf = 0\n      // smoothed frame time for the adaptive-resolution check\n      let frameEma = 1 / 60\n\n      const uploadAndDraw = (dt: number, snap = false) => {\n        // Synthesized from the state, unless a channel is pinned via\n        // `volumes`. Pinned values still glide on the same easing, so dialing\n        // one in the playground cross-fades rather than jumping.\n        const [tin, tout] = targetVolumes(stateRef.current, tSec)\n        // Same order as params and colours: direct prop, then the per-state\n        // map, then the engine's own synthesis.\n        const liveVolumes = volumesRef.current\n        const stateVolume = stateVolumesRef.current?.[stateRef.current]\n        const targetIn = liveVolumes?.input ?? stateVolume?.input ?? tin\n        const targetOut = liveVolumes?.output ?? stateVolume?.output ?? tout\n        const kVol = 1 - Math.exp(-dt * 12)\n        cur.in += (targetIn - cur.in) * kVol\n        cur.out += (targetOut - cur.out) * kVol\n\n        /*\n          Flow speed follows the output volume. It multiplies every integrated\n          clock's increment, so it is a RATE: easing it quickly makes the orb\n          visibly lurch — a state change would spin the orb up hard before the\n          params had finished gliding.\n\n          It is therefore eased on the same constant as the params below, so a\n          state change ramps its motion over the same half second that its look\n          takes to cross-fade. The steady-state values are unchanged, so a\n          speaking orb still flows faster than an idle one; only the transition\n          into that rate is gradual.\n        */\n        const targetSpeed = 0.1 + (1 - Math.pow(cur.out - 1, 2)) * 0.9\n        if (snap) {\n          speed = targetSpeed\n          speedVel = 0\n        } else {\n          springStep(speed, speedVel, targetSpeed, dt, PARAM_EASE)\n          speed = springOut.x\n          speedVel = springOut.v\n        }\n        anim += dt * speed\n\n        gl.uniform1f(uTime, tSec * 0.5)\n        gl.uniform1f(uAnim, anim)\n        gl.uniform1f(uInput, cur.in)\n        gl.uniform1f(uOutput, cur.out)\n\n        // Resolution order per param: explicit `params` → `statePresets`\n        // prop → the variant's own preset → schema default. The two middle\n        // steps are per-key, so overriding one param of one state leaves the\n        // rest of that state alone. Values glide rather than snap.\n        const liveParams = paramsRef.current\n        const statePreset = presets?.[stateRef.current]\n        const overridePreset = statePresetsRef.current?.[stateRef.current]\n\n        for (const { def, loc } of paramLocs) {\n          const explicit = liveParams?.[def.key]\n          const target =\n            typeof explicit === \"number\"\n              ? explicit\n              : (overridePreset?.[def.key] ??\n                statePreset?.[def.key] ??\n                def.default)\n          const curVal = paramCur[def.key] ?? target\n          let next: number\n          if (snap) {\n            next = target\n            paramVel[def.key] = 0\n          } else {\n            springStep(curVal, paramVel[def.key] ?? 0, target, dt, PARAM_EASE)\n            next = springOut.x\n            paramVel[def.key] = springOut.v\n          }\n          paramCur[def.key] = next\n\n          if (def.integrate) {\n            const clock =\n              (paramClocks[def.key] ??\n                (paramClocks[def.key] = Math.random() * 100)) +\n              dt * speed * next\n            paramClocks[def.key] = clock\n            gl.uniform1f(loc, clock)\n          } else {\n            gl.uniform1f(loc, next)\n          }\n        }\n\n        // Same resolution order and same easing as params, so a state change\n        // cross-fades the palette instead of cutting to it.\n        const liveColors = colorsRef.current\n        const stateColor = variant.stateColors?.[stateRef.current]\n        const overrideColor = stateColorsRef.current?.[stateRef.current]\n        for (const { def, loc } of colorLocs) {\n          const target = hexToRgb(\n            liveColors?.[def.key] ??\n              overrideColor?.[def.key] ??\n              stateColor?.[def.key] ??\n              def.default\n          )\n          const curCol = (colorCur[def.key] ??= [...target] as [\n            number,\n            number,\n            number,\n          ])\n          const velCol = (colorVel[def.key] ??= [0, 0, 0])\n          for (let i = 0; i < 3; i++) {\n            if (snap) {\n              curCol[i] = target[i]\n              velCol[i] = 0\n            } else {\n              springStep(curCol[i], velCol[i], target[i], dt, PARAM_EASE)\n              curCol[i] = springOut.x\n              velCol[i] = springOut.v\n            }\n          }\n          gl.uniform3f(loc, curCol[0], curCol[1], curCol[2])\n        }\n\n        gl.clearColor(0, 0, 0, 0)\n        gl.clear(gl.COLOR_BUFFER_BIT)\n        gl.drawArrays(gl.TRIANGLES, 0, 3)\n        // Deferred a microtask: the first of these draws runs synchronously\n        // inside this effect, and a sync setState there trips the compiler\n        // lint. A microtask still resolves before the browser paints, so the\n        // reveal is not delayed by a frame.\n        if (!announcedPaint) {\n          announcedPaint = true\n          queueMicrotask(() => {\n            /*\n              Re-check: the context can be evicted between this draw and the\n              microtask, and mounting one more orb anywhere on the page is\n              enough to do it — opening the details drawer over a full gallery\n              is exactly that. Revealing on the strength of a frame that has\n              already been thrown away puts a dead canvas on screen, which is\n              what the browser draws its broken-canvas placeholder over. The\n              generation that follows the restore announces again.\n            */\n            if (gl.isContextLost()) return\n            setPaintedKey(variant.key)\n          })\n        }\n      }\n\n      const releaseGL = () => {\n        resizeObserver?.disconnect()\n        intersectionObserver?.disconnect()\n        gl.deleteProgram(prog)\n        gl.deleteShader(vs)\n        gl.deleteShader(fs)\n        gl.deleteBuffer(buf)\n      }\n\n      if (reduceMotion) {\n        // One representative frame, then stop — snapped straight onto the\n        // state's targets, since a spring would only be part-way there.\n        tSec = 1\n        uploadAndDraw(1, true)\n        return releaseGL\n      }\n\n      const loop = () => {\n        raf = requestAnimationFrame(loop)\n        const now = performance.now() / 1000\n        const dt = Math.min(now - last, 0.05)\n        last = now\n        if (!visible || pausedRef.current) return\n        tSec += dt\n\n        /*\n          Adaptive resolution. When the smoothed frame time sits above ~30fps,\n          the GPU is drowning in fragment work (these shaders are pure fill\n          cost), so step the backing store down 20% and re-measure. Steps only\n          go down — never back up — so the resolution can't oscillate. The\n          warm-up guard keeps page-load jank (hydration, first compiles) from\n          triggering a downgrade the GPU never asked for.\n        */\n        /*\n          Only unstalled frames are evidence about GPU fill cost. `dt` above is\n          clamped at 0.05, so a frame that hits the clamp is the main thread\n          having been blocked — a slider drag re-rendering React, a GC pause, a\n          tab regaining focus — and feeding those in made UI jank look\n          identical to a drowning GPU.\n        */\n        if (dt < 0.05) frameEma += (dt - frameEma) * 0.08\n\n        if (tSec > 1.5 && frameEma > 1 / 34 && resScale > 0.5) {\n          resScale = Math.max(0.5, resScale * 0.8)\n          frameEma = 1 / 60 // require fresh evidence before the next step\n          resize()\n        } else if (tSec > 1.5 && frameEma < 1 / 55 && resScale < 1) {\n          /*\n            And step back up once frames are comfortably fast again. This used\n            to be one-way, on the reasoning that it could not then oscillate —\n            but that also meant one transient stall permanently halved the\n            orb's resolution, and at half resolution a high-frequency shader\n            aliases into shimmer that reads as the shader itself misbehaving.\n            The gap between the two thresholds (29ms down, 18ms up) is the\n            hysteresis that stops it hunting.\n          */\n          resScale = Math.min(1, resScale / 0.8)\n          frameEma = 1 / 60\n          resize()\n        }\n\n        uploadAndDraw(dt)\n      }\n      /*\n        First frame synchronously, before entering the rAF loop. rAF does not\n        run at all in hidden documents (background tabs, embedded previews),\n        so a freshly mounted orb would otherwise sit fully transparent until\n        the page next becomes visible — a grid of mounted, healthy, blank\n        canvases. The sync frame guarantees every mount paints: background\n        documents get a static frame, visible ones start animating over it.\n        dt = 1 lands the param glide on its targets, as in the reduce-motion\n        frame above.\n      */\n      uploadAndDraw(1)\n      loop()\n\n      return () => {\n        cancelAnimationFrame(raf)\n        releaseGL()\n      }\n    }\n\n    /*\n      Wire the canvas's lifecycle controller. The listeners are attached ONCE\n      per canvas element and never removed, deliberately: the lost event must\n      be canceled even while no orb is mounted on the canvas — an uncanceled\n      webglcontextlost marks the context permanently unrestorable, and the\n      router can show this exact canvas again later. Whether a loss leads to\n      a revival is decided by `desired`, not by listener presence.\n    */\n    /*\n      A canvas whose context has gone is not simply blank: Chrome paints its\n      broken-image placeholder over the element's whole box — the white square\n      you see on a reloaded grid. Hide the canvas the moment the context is\n      lost, and let the generation that follows a restore reveal it again.\n    */\n    const hideNow = () => {\n      /*\n        Both, deliberately. The style write lands in this tick — the browser\n        paints its placeholder over a dead canvas immediately, and a busy main\n        thread can hold a React update for several frames. The state change is\n        what keeps React's own view in sync, so the reveal that follows a\n        restore clears the inline value again rather than fighting it.\n      */\n      canvas.style.opacity = \"0\"\n      setPaintedKey(null)\n    }\n\n    const onContextLostHide = () => hideNow()\n    canvas.addEventListener(\"webglcontextlost\", onContextLostHide)\n\n    /*\n      Hand the context back before the next document asks for one.\n\n      A hard reload never runs this effect's cleanup — the document is\n      discarded whole — so the outgoing page's contexts are still alive while\n      the incoming page allocates its own. On a grid of orbs that puts the\n      live count past the browser's ~16 cap, and the ones it evicts are\n      exactly the canvases that come back as placeholders until the restore\n      path catches them. `persisted` is a bfcache suspend, where the page is\n      shown again untouched and must keep everything it holds.\n    */\n    const onPageHide = (event: PageTransitionEvent) => {\n      if (event.persisted) return\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Already released — nothing to hand back.\n      }\n    }\n    window.addEventListener(\"pagehide\", onPageHide)\n\n    let ctl = canvasControllers.get(canvas)\n    if (!ctl) {\n      const created: CanvasContextController = {\n        desired: false,\n        start: null,\n        stopGen: null,\n      }\n      canvas.addEventListener(\"webglcontextlost\", (event) => {\n        event.preventDefault() // always cancel — keeps the context restorable\n        created.stopGen?.()\n        created.stopGen = null\n        if (created.desired) {\n          /*\n            Ask for the context back — but in a LATER task. The browser only\n            marks a loss as restorable once the lost event's dispatch has\n            completed and it has seen the canceled flag, so a restoreContext()\n            issued during dispatch (or before it, as the mount path may) is\n            silently refused. This is the path a synchronous cleanup+setup\n            pair hits — React re-running the effect on the same canvas loses\n            the context and wants it right back. For losses we didn't cause\n            (eviction, GPU reset) the call may refuse; the canceled event then\n            lets the browser restore on its own schedule.\n          */\n          setTimeout(() => {\n            if (!created.desired) return\n            try {\n              loseExt?.restoreContext()\n            } catch {\n              // Natural loss — restoration is the browser's call now.\n            }\n          }, 0)\n        }\n      })\n      canvas.addEventListener(\"webglcontextrestored\", () => {\n        if (created.desired && created.start) {\n          created.stopGen = created.start()\n        }\n      })\n      canvasControllers.set(canvas, created)\n      ctl = created\n    }\n    const controller = ctl\n\n    controller.desired = true\n    controller.start = startGeneration\n    if (gl.isContextLost()) {\n      // A previous run on this canvas released the context (effect re-run, or\n      // the router re-showing a kept-alive page). If the lost event already\n      // dispatched this request is honored now; if it is still queued, the\n      // lost handler above re-requests it on dispatch.\n      try {\n        loseExt?.restoreContext()\n      } catch {\n        // No restore path — the orb stays blank rather than throwing.\n      }\n    } else {\n      controller.stopGen = startGeneration()\n    }\n\n    return () => {\n      /*\n        Hide BEFORE tearing the context down.\n\n        This cleanup releases the context deliberately, and the lost event it\n        provokes is dispatched asynchronously — by which point the listener\n        below is unhooked and the replacement effect has not drawn yet. That\n        leaves a revealed canvas with a dead context, which is precisely what\n        the browser paints its broken-canvas placeholder over. The window is\n        not rare: any prop change in this effect's deps re-runs it, so it hits\n        every time the drawer switches preview example (maxDpr differs on the\n        layout one) or a wrapper is toggled.\n      */\n      hideNow()\n      canvas.removeEventListener(\"webglcontextlost\", onContextLostHide)\n      window.removeEventListener(\"pagehide\", onPageHide)\n      controller.desired = false\n      controller.start = null\n      controller.stopGen?.()\n      controller.stopGen = null\n      /*\n        Release the context NOW instead of when the canvas is garbage\n        collected. Browsers cap live WebGL contexts per page (~8–16) and evict\n        the oldest when the cap is hit — client-side navigation that unmounts\n        and remounts a page of orbs otherwise piles up zombie contexts until\n        freshly mounted orbs get evicted and render blank.\n      */\n      try {\n        loseExt?.loseContext()\n      } catch {\n        // Context already lost — nothing to release.\n      }\n    }\n    /*\n      `wrapped` is in here because turning a wrapper on or off moves the canvas\n      from being this component's root element to being a child of the wrapper\n      div — React drops the old element and mounts a new one, and the GL\n      context, its observers and its render loop all belong to the old one. Any\n      other prop leaves the element alone, INCLUDING a swap between two\n      wrappers: the canvas keeps its slot among the decoration layers, so\n      glass -> ring reuses the context instead of rebuilding it.\n    */\n  }, [variant, pauseOffscreen, maxDpr, wrapped])\n\n  const sizeStyle: CSSProperties =\n    size === undefined ? {} : { width: size, height: size }\n\n  /*\n    Spread ahead of the caller's `style`, so an orb that wants to own its own\n    opacity still can — it simply opts out of the reveal.\n\n    A hard flip, deliberately: no transition, no fade. A hidden document\n    (background tab, embedded preview) does not advance CSS transitions, so a\n    faded reveal left orbs pinned at zero in exactly the case the synchronous\n    first frame above exists to serve — mounted, healthy, and invisible. The\n    cut is not a pop either way, since it happens on the frame the orb first\n    has something to show.\n  */\n  const revealStyle: CSSProperties = painted ? {} : { opacity: 0 }\n\n  const canvas = (\n    <canvas\n      // A lost WebGL context can't be reused, so each variant gets a fresh canvas.\n      key={variant.key}\n      ref={canvasRef}\n      className={spec ? undefined : className}\n      style={\n        spec\n          ? {\n              display: \"block\",\n              position: \"absolute\",\n              left: `${spec.inset}%`,\n              top: `${spec.inset}%`,\n              width: `${100 - 2 * spec.inset}%`,\n              height: `${100 - 2 * spec.inset}%`,\n              ...revealStyle,\n              ...(spec.mask ? masked(spec.mask) : {}),\n            }\n          : { display: \"block\", ...sizeStyle, ...revealStyle, ...style }\n      }\n      role={!spec && ariaLabel ? \"img\" : undefined}\n      aria-label={spec ? undefined : ariaLabel}\n      aria-hidden={!spec && ariaLabel ? undefined : true}\n    />\n  )\n\n  if (!spec) return canvas\n\n  /*\n    Wrapped: the box becomes the orb's footprint and the canvas is absolutely\n    positioned inside it. `under`, the canvas and `over` are all positioned\n    with an auto z-index, so they paint in DOM order — decoration behind the\n    orb, then the orb, then decoration in front of it.\n\n    `aspectRatio` is the fallback for the sizeless case: `size` is optional\n    (callers may size the orb with a class instead), and an absolutely\n    positioned canvas contributes nothing to its parent's height, so without\n    it a class that only sets a width would collapse the box to zero.\n  */\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"relative\",\n        aspectRatio: \"1 / 1\",\n        ...(spec.shadow ? { borderRadius: \"50%\", boxShadow: spec.shadow } : {}),\n        ...sizeStyle,\n        ...(wrapperColor ? { color: wrapperColor } : {}),\n        ...style,\n      }}\n      role={ariaLabel ? \"img\" : undefined}\n      aria-label={ariaLabel}\n      aria-hidden={ariaLabel ? undefined : true}\n    >\n      {spec.animated ? (\n        <style\n          href={WRAPPER_STYLE_HREF}\n          precedence=\"default\"\n          dangerouslySetInnerHTML={{ __html: WRAPPER_CSS }}\n        />\n      ) : null}\n      {spec.under}\n      {canvas}\n      {spec.over}\n    </div>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE",
          "target": "@components/voice-agents/orbkit/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 zzzzshawn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
        },
        {
          "path": "components/voice-agents/orbkit/SOURCE.json",
          "target": "@components/voice-agents/orbkit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"OrbKit\",\n  \"repository\": \"https://github.com/zzzzshawn/orbkit\",\n  \"commit\": \"35e42484560fd35e8502703ba58fa99541d8c686\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 zzzzshawn\",\n  \"core\": \"components/voice-agents/orbkit/core.tsx\",\n  \"credits\": \"components/voice-agents/orbkit/CREDITS.md\",\n  \"shaderLicense\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\",\n  \"changes\": [\n    \"Moved the dependency-free OrbKit runtime and selected variants into the Agents Kit voice collection.\",\n    \"Mapped variant imports to the local shared runtime.\",\n    \"Kept the upstream reduced-motion, offscreen pause, DPR cap, context recovery, and cleanup behavior.\"\n  ],\n  \"exclusions\": [\n    {\n      \"name\": \"shdr-19\",\n      \"reason\": \"Non-commercial XorDev shader; excluded from this distributable MIT collection.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    },\n    {\n      \"name\": \"XorDev shader ports\",\n      \"reason\": \"All variants listed under Shaders by XorDev in CREDITS.md are non-commercial and excluded.\",\n      \"license\": \"components/voice-agents/orbkit/LICENSE-SHADERS.md\"\n    }\n  ],\n  \"components\": [\n    {\n      \"name\": \"shdr-11\",\n      \"path\": \"shdr-11.tsx\",\n      \"title\": \"Hydrogen\"\n    },\n    {\n      \"name\": \"shdr-13\",\n      \"path\": \"shdr-13.tsx\",\n      \"title\": \"Ion\"\n    },\n    {\n      \"name\": \"shdr-14\",\n      \"path\": \"shdr-14.tsx\",\n      \"title\": \"Dither\"\n    },\n    {\n      \"name\": \"shdr-21\",\n      \"path\": \"shdr-21.tsx\",\n      \"title\": \"Nimbus\"\n    }\n  ]\n}\n"
        },
        {
          "path": "components/voice-agents/orbkit/CREDITS.md",
          "target": "@components/voice-agents/orbkit/CREDITS.md",
          "type": "registry:file",
          "content": "# Credits\n\nOrbkit ships two kinds of orb. Every file says which it is.\n\n## Shaders by XorDev\n\nThese 19 orbs are ported from golfed shaders by [XorDev](https://x.com/XorDev),\nused with his permission (agreed by direct message on 2026-09-06). Terms:\n**non-commercial use only, with attribution to XorDev**. Each file starts with\na notice that must stay with any copy, and the registry marks these items with\na `credit` field. See [LICENSE-SHADERS.md](LICENSE-SHADERS.md).\n\n| Orb     | Shader by | Original             |\n| ------- | --------- | -------------------- |\n| shdr-01 | XorDev    | https://x.com/XorDev |\n| shdr-02 | XorDev    | https://x.com/XorDev |\n| shdr-03 | XorDev    | https://x.com/XorDev |\n| shdr-04 | XorDev    | https://x.com/XorDev |\n| shdr-05 | XorDev    | https://x.com/XorDev |\n| shdr-06 | XorDev    | https://x.com/XorDev |\n| shdr-07 | XorDev    | https://x.com/XorDev |\n| shdr-08 | XorDev    | https://x.com/XorDev |\n| shdr-09 | XorDev    | https://x.com/XorDev |\n| shdr-10 | XorDev    | https://x.com/XorDev |\n| shdr-15 | XorDev    | https://x.com/XorDev |\n| shdr-18 | XorDev    | https://x.com/XorDev |\n| shdr-19 | XorDev    | https://x.com/XorDev |\n| shdr-20 | XorDev    | https://x.com/XorDev |\n| shdr-22 | XorDev    | https://x.com/XorDev |\n| shdr-25 | XorDev    | https://x.com/XorDev |\n| shdr-26 | XorDev    | https://x.com/XorDev |\n| shdr-28 | XorDev    | https://x.com/XorDev |\n| shdr-31 | XorDev    | https://x.com/XorDev |\n\nReplace a profile link with the specific post once it is known.\n\n## Original orbs\n\nThese 14 orbs are Orbkit's own work and are MIT-licensed, like the runtime:\nshdr-11, shdr-12, shdr-13, shdr-14, shdr-16, shdr-17, shdr-21, shdr-23, shdr-24, shdr-27, shdr-29, shdr-30, shdr-32, shdr-33.\n\n## Adding shaders\n\nAsk the original author before porting anything that is not your own. XorDev\nasked to be consulted before any more of his work is included.\n"
        },
        {
          "path": "components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "target": "@components/voice-agents/orbkit/LICENSE-SHADERS.md",
          "type": "registry:file",
          "content": "# Licence for the ported shaders\n\nThe orb files listed under \"Shaders by XorDev\" in [CREDITS.md](CREDITS.md) are\nderived from shaders by XorDev (https://x.com/XorDev) and are used with the\nauthor's permission on these terms:\n\n1. Non-commercial use only.\n2. Attribution to XorDev must be kept with every copy, including the notice at\n   the top of each file.\n3. Any further use of XorDev's work requires asking the author first.\n\nEverything else in this repository, including the runtime\n(`orbkit-core.tsx`), the site, the build scripts, and the original orbs, is\nlicensed under the MIT licence in [LICENSE](LICENSE).\n"
        }
      ],
      "categories": [
        "OrbKit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "prompt-input",
      "type": "registry:block",
      "title": "Prompt Input",
      "description": "An input field designed for chat interfaces, allowing users to enter and submit text prompts to an AI model",
      "dependencies": [
        "@radix-ui/react-tooltip@^1.2.6",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/prompt-input.tsx",
          "target": "@components/prompt-kit/prompt-input.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Textarea } from \"@/components/ui/textarea\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport React, {\n  createContext,\n  useContext,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\"\n\ntype PromptInputContextType = {\n  isLoading: boolean\n  value: string\n  setValue: (value: string) => void\n  maxHeight: number | string\n  onSubmit?: () => void\n  disabled?: boolean\n  textareaRef: React.RefObject<HTMLTextAreaElement | null>\n}\n\nconst PromptInputContext = createContext<PromptInputContextType>({\n  isLoading: false,\n  value: \"\",\n  setValue: () => {},\n  maxHeight: 240,\n  onSubmit: undefined,\n  disabled: false,\n  textareaRef: React.createRef<HTMLTextAreaElement>(),\n})\n\nfunction usePromptInput() {\n  return useContext(PromptInputContext)\n}\n\nexport type PromptInputProps = {\n  isLoading?: boolean\n  value?: string\n  onValueChange?: (value: string) => void\n  maxHeight?: number | string\n  onSubmit?: () => void\n  children: React.ReactNode\n  className?: string\n  disabled?: boolean\n} & React.ComponentProps<\"div\">\n\nfunction PromptInput({\n  className,\n  isLoading = false,\n  maxHeight = 240,\n  value,\n  onValueChange,\n  onSubmit,\n  children,\n  disabled = false,\n  onClick,\n  ...props\n}: PromptInputProps) {\n  const [internalValue, setInternalValue] = useState(value || \"\")\n  const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n  const handleChange = (newValue: string) => {\n    setInternalValue(newValue)\n    onValueChange?.(newValue)\n  }\n\n  const handleClick: React.MouseEventHandler<HTMLDivElement> = (event) => {\n    if (!disabled) textareaRef.current?.focus()\n    onClick?.(event)\n  }\n\n  return (\n    <TooltipProvider>\n      <PromptInputContext.Provider\n        value={{\n          isLoading,\n          value: value ?? internalValue,\n          setValue: onValueChange ?? handleChange,\n          maxHeight,\n          onSubmit,\n          disabled,\n          textareaRef,\n        }}\n      >\n        <div\n          onClick={handleClick}\n          className={cn(\n            \"border-input bg-background cursor-text rounded-3xl border p-2 shadow-xs\",\n            disabled && \"cursor-not-allowed opacity-60\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </div>\n      </PromptInputContext.Provider>\n    </TooltipProvider>\n  )\n}\n\nexport type PromptInputTextareaProps = {\n  disableAutosize?: boolean\n} & React.ComponentProps<typeof Textarea>\n\nfunction PromptInputTextarea({\n  className,\n  onKeyDown,\n  disableAutosize = false,\n  ...props\n}: PromptInputTextareaProps) {\n  const { value, setValue, maxHeight, onSubmit, disabled, textareaRef } =\n    usePromptInput()\n\n  const adjustHeight = (element: HTMLTextAreaElement | null) => {\n    if (!element || disableAutosize) return\n    element.style.height = \"auto\"\n    element.style.height =\n      typeof maxHeight === \"number\"\n        ? `${Math.min(element.scrollHeight, maxHeight)}px`\n        : `min(${element.scrollHeight}px, ${maxHeight})`\n  }\n\n  const handleRef = (element: HTMLTextAreaElement | null) => {\n    textareaRef.current = element\n    adjustHeight(element)\n  }\n\n  useLayoutEffect(() => {\n    adjustHeight(textareaRef.current)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [value, maxHeight, disableAutosize])\n\n  const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n    adjustHeight(event.target)\n    setValue(event.target.value)\n  }\n\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n      e.preventDefault()\n      onSubmit?.()\n    }\n    onKeyDown?.(e)\n  }\n\n  return (\n    <Textarea\n      ref={handleRef}\n      value={value}\n      onChange={handleChange}\n      onKeyDown={handleKeyDown}\n      className={cn(\n        \"text-primary min-h-[44px] w-full resize-none border-none bg-transparent shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0\",\n        className\n      )}\n      rows={1}\n      disabled={disabled}\n      {...props}\n    />\n  )\n}\n\nexport type PromptInputActionsProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction PromptInputActions({\n  children,\n  className,\n  ...props\n}: PromptInputActionsProps) {\n  return (\n    <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n      {children}\n    </div>\n  )\n}\n\nexport type PromptInputActionProps = {\n  className?: string\n  tooltip: React.ReactNode\n  children: React.ReactNode\n  side?: \"top\" | \"bottom\" | \"left\" | \"right\"\n} & React.ComponentProps<typeof Tooltip>\n\nfunction PromptInputAction({\n  tooltip,\n  children,\n  className,\n  side = \"top\",\n  ...props\n}: PromptInputActionProps) {\n  const { disabled } = usePromptInput()\n\n  return (\n    <Tooltip {...props}>\n      <TooltipTrigger\n        asChild\n        disabled={disabled}\n        onClick={(event) => event.stopPropagation()}\n      >\n        {children}\n      </TooltipTrigger>\n      <TooltipContent side={side} className={className}>\n        {tooltip}\n      </TooltipContent>\n    </Tooltip>\n  )\n}\n\nexport {\n  PromptInput,\n  PromptInputTextarea,\n  PromptInputActions,\n  PromptInputAction,\n}\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/tooltip.tsx",
          "target": "@components/ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 4,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-gray-900 text-gray-50 dark:bg-gray-50 dark:text-gray-900 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-w-sm rounded-md px-3 py-1.5 text-xs\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"fill-gray-900 dark:fill-gray-50 z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "code-block",
      "type": "registry:block",
      "title": "Code Block",
      "description": "A component for displaying code snippets with syntax highlighting and customizable styling",
      "dependencies": [
        "clsx@^2.1.1",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/code-block.tsx",
          "target": "@components/prompt-kit/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React, { useEffect, useState } from \"react\"\nimport { codeToHtml } from \"shiki\"\n\nexport type CodeBlockProps = {\n  children?: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlock({ children, className, ...props }: CodeBlockProps) {\n  return (\n    <div\n      className={cn(\n        \"not-prose flex w-full flex-col overflow-clip border\",\n        \"border-border bg-card text-card-foreground rounded-xl\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type CodeBlockCodeProps = {\n  code: string\n  language?: string\n  theme?: string\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlockCode({\n  code,\n  language = \"tsx\",\n  theme = \"github-light\",\n  className,\n  ...props\n}: CodeBlockCodeProps) {\n  const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)\n\n  useEffect(() => {\n    async function highlight() {\n      if (!code) {\n        setHighlightedHtml(\"<pre><code></code></pre>\")\n        return\n      }\n\n      const html = await codeToHtml(code, { lang: language, theme })\n      setHighlightedHtml(html)\n    }\n    highlight()\n  }, [code, language, theme])\n\n  const classNames = cn(\n    \"w-full overflow-x-auto text-[13px] [&>pre]:px-4 [&>pre]:py-4\",\n    className\n  )\n\n  // SSR fallback: render plain code if not hydrated yet\n  return highlightedHtml ? (\n    <div\n      data-code-theme={theme}\n      className={classNames}\n      dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n      {...props}\n    />\n  ) : (\n    <div data-code-theme={theme} className={classNames} {...props}>\n      <pre>\n        <code>{code}</code>\n      </pre>\n    </div>\n  )\n}\n\nexport type CodeBlockGroupProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction CodeBlockGroup({\n  children,\n  className,\n  ...props\n}: CodeBlockGroupProps) {\n  return (\n    <div\n      className={cn(\"flex items-center justify-between\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport { CodeBlockGroup, CodeBlockCode, CodeBlock }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "markdown",
      "type": "registry:block",
      "title": "Markdown",
      "description": "A component for rendering Markdown content with support for code blocks, GFM, and custom styling",
      "dependencies": [
        "clsx@^2.1.1",
        "marked@^15.0.7",
        "react-markdown@^10.1.0",
        "remark-breaks@^4.0.0",
        "remark-gfm@^4.0.1",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/markdown.tsx",
          "target": "@components/prompt-kit/markdown.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { marked } from \"marked\"\nimport { memo, useId, useMemo } from \"react\"\nimport ReactMarkdown, { Components } from \"react-markdown\"\nimport remarkBreaks from \"remark-breaks\"\nimport remarkGfm from \"remark-gfm\"\nimport { CodeBlock, CodeBlockCode } from \"./code-block\"\n\nexport type MarkdownProps = {\n  children: string\n  id?: string\n  className?: string\n  components?: Partial<Components>\n}\n\nfunction parseMarkdownIntoBlocks(markdown: string): string[] {\n  const tokens = marked.lexer(markdown)\n  return tokens.map((token) => token.raw)\n}\n\nfunction extractLanguage(className?: string): string {\n  if (!className) return \"plaintext\"\n  const match = className.match(/language-(\\w+)/)\n  return match ? match[1] : \"plaintext\"\n}\n\nconst INITIAL_COMPONENTS: Partial<Components> = {\n  code: function CodeComponent({ className, children, ...props }) {\n    const isInline =\n      !props.node?.position?.start.line ||\n      props.node?.position?.start.line === props.node?.position?.end.line\n\n    if (isInline) {\n      return (\n        <span\n          className={cn(\n            \"bg-primary-foreground rounded-sm px-1 font-mono text-sm\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </span>\n      )\n    }\n\n    const language = extractLanguage(className)\n\n    return (\n      <CodeBlock className={className}>\n        <CodeBlockCode code={children as string} language={language} />\n      </CodeBlock>\n    )\n  },\n  pre: function PreComponent({ children }) {\n    return <>{children}</>\n  },\n}\n\nconst MemoizedMarkdownBlock = memo(\n  function MarkdownBlock({\n    content,\n    components = INITIAL_COMPONENTS,\n  }: {\n    content: string\n    components?: Partial<Components>\n  }) {\n    return (\n      <ReactMarkdown\n        remarkPlugins={[remarkGfm, remarkBreaks]}\n        components={components}\n      >\n        {content}\n      </ReactMarkdown>\n    )\n  },\n  function propsAreEqual(prevProps, nextProps) {\n    return prevProps.content === nextProps.content\n  }\n)\n\nMemoizedMarkdownBlock.displayName = \"MemoizedMarkdownBlock\"\n\nfunction MarkdownComponent({\n  children,\n  id,\n  className,\n  components = INITIAL_COMPONENTS,\n}: MarkdownProps) {\n  const generatedId = useId()\n  const blockId = id ?? generatedId\n  const blocks = useMemo(() => parseMarkdownIntoBlocks(children), [children])\n\n  return (\n    <div className={className}>\n      {blocks.map((block, index) => (\n        <MemoizedMarkdownBlock\n          key={`${blockId}-block-${index}`}\n          content={block}\n          components={components}\n        />\n      ))}\n    </div>\n  )\n}\n\nconst Markdown = memo(MarkdownComponent)\nMarkdown.displayName = \"Markdown\"\n\nexport { Markdown }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/prompt-kit/code-block.tsx",
          "target": "@components/prompt-kit/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React, { useEffect, useState } from \"react\"\nimport { codeToHtml } from \"shiki\"\n\nexport type CodeBlockProps = {\n  children?: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlock({ children, className, ...props }: CodeBlockProps) {\n  return (\n    <div\n      className={cn(\n        \"not-prose flex w-full flex-col overflow-clip border\",\n        \"border-border bg-card text-card-foreground rounded-xl\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type CodeBlockCodeProps = {\n  code: string\n  language?: string\n  theme?: string\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlockCode({\n  code,\n  language = \"tsx\",\n  theme = \"github-light\",\n  className,\n  ...props\n}: CodeBlockCodeProps) {\n  const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)\n\n  useEffect(() => {\n    async function highlight() {\n      if (!code) {\n        setHighlightedHtml(\"<pre><code></code></pre>\")\n        return\n      }\n\n      const html = await codeToHtml(code, { lang: language, theme })\n      setHighlightedHtml(html)\n    }\n    highlight()\n  }, [code, language, theme])\n\n  const classNames = cn(\n    \"w-full overflow-x-auto text-[13px] [&>pre]:px-4 [&>pre]:py-4\",\n    className\n  )\n\n  // SSR fallback: render plain code if not hydrated yet\n  return highlightedHtml ? (\n    <div\n      data-code-theme={theme}\n      className={classNames}\n      dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n      {...props}\n    />\n  ) : (\n    <div data-code-theme={theme} className={classNames} {...props}>\n      <pre>\n        <code>{code}</code>\n      </pre>\n    </div>\n  )\n}\n\nexport type CodeBlockGroupProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction CodeBlockGroup({\n  children,\n  className,\n  ...props\n}: CodeBlockGroupProps) {\n  return (\n    <div\n      className={cn(\"flex items-center justify-between\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport { CodeBlockGroup, CodeBlockCode, CodeBlock }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "message",
      "type": "registry:block",
      "title": "Message",
      "description": "A component for displaying chat messages with support for avatars, markdown content, and interactive actions",
      "dependencies": [
        "@radix-ui/react-avatar@^1.1.3",
        "@radix-ui/react-tooltip@^1.2.6",
        "clsx@^2.1.1",
        "marked@^15.0.7",
        "react-markdown@^10.1.0",
        "remark-breaks@^4.0.0",
        "remark-gfm@^4.0.1",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/message.tsx",
          "target": "@components/prompt-kit/message.tsx",
          "type": "registry:component",
          "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport { Markdown } from \"./markdown\"\n\nexport type MessageProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nconst Message = ({ children, className, ...props }: MessageProps) => (\n  <div className={cn(\"flex gap-3\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type MessageAvatarProps = {\n  src: string\n  alt: string\n  fallback?: string\n  delayMs?: number\n  className?: string\n}\n\nconst MessageAvatar = ({\n  src,\n  alt,\n  fallback,\n  delayMs,\n  className,\n}: MessageAvatarProps) => {\n  return (\n    <Avatar className={cn(\"h-8 w-8 shrink-0\", className)}>\n      <AvatarImage src={src} alt={alt} />\n      {fallback && (\n        <AvatarFallback delayMs={delayMs}>{fallback}</AvatarFallback>\n      )}\n    </Avatar>\n  )\n}\n\nexport type MessageContentProps = {\n  children: React.ReactNode\n  markdown?: boolean\n  className?: string\n} & React.ComponentProps<typeof Markdown> &\n  React.HTMLProps<HTMLDivElement>\n\nconst MessageContent = ({\n  children,\n  markdown = false,\n  className,\n  ...props\n}: MessageContentProps) => {\n  const classNames = cn(\n    \"prose prose-sm dark:prose-invert rounded-lg bg-secondary p-2 text-foreground break-words whitespace-normal\",\n    className\n  )\n\n  return markdown ? (\n    <Markdown className={classNames} {...props}>\n      {children as string}\n    </Markdown>\n  ) : (\n    <div className={classNames} {...props}>\n      {children}\n    </div>\n  )\n}\n\nexport type MessageActionsProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nconst MessageActions = ({\n  children,\n  className,\n  ...props\n}: MessageActionsProps) => (\n  <div\n    className={cn(\"text-muted-foreground flex items-center gap-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type MessageActionProps = {\n  className?: string\n  tooltip: React.ReactNode\n  children: React.ReactNode\n  side?: \"top\" | \"bottom\" | \"left\" | \"right\"\n} & React.ComponentProps<typeof Tooltip>\n\nconst MessageAction = ({\n  tooltip,\n  children,\n  className,\n  side = \"top\",\n  ...props\n}: MessageActionProps) => {\n  return (\n    <TooltipProvider>\n      <Tooltip {...props}>\n        <TooltipTrigger asChild>{children}</TooltipTrigger>\n        <TooltipContent side={side} className={className}>\n          {tooltip}\n        </TooltipContent>\n      </Tooltip>\n    </TooltipProvider>\n  )\n}\n\nexport { Message, MessageAvatar, MessageContent, MessageActions, MessageAction }\n"
        },
        {
          "path": "components/ui/avatar.tsx",
          "target": "@components/ui/avatar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Avatar({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n  return (\n    <AvatarPrimitive.Root\n      data-slot=\"avatar\"\n      className={cn(\n        \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarImage({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n  return (\n    <AvatarPrimitive.Image\n      data-slot=\"avatar-image\"\n      className={cn(\"aspect-square size-full\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarFallback({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n  return (\n    <AvatarPrimitive.Fallback\n      data-slot=\"avatar-fallback\"\n      className={cn(\n        \"bg-muted flex size-full items-center justify-center rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Avatar, AvatarImage, AvatarFallback }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/tooltip.tsx",
          "target": "@components/ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 4,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-gray-900 text-gray-50 dark:bg-gray-50 dark:text-gray-900 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-w-sm rounded-md px-3 py-1.5 text-xs\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"fill-gray-900 dark:fill-gray-50 z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "components/prompt-kit/markdown.tsx",
          "target": "@components/prompt-kit/markdown.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { marked } from \"marked\"\nimport { memo, useId, useMemo } from \"react\"\nimport ReactMarkdown, { Components } from \"react-markdown\"\nimport remarkBreaks from \"remark-breaks\"\nimport remarkGfm from \"remark-gfm\"\nimport { CodeBlock, CodeBlockCode } from \"./code-block\"\n\nexport type MarkdownProps = {\n  children: string\n  id?: string\n  className?: string\n  components?: Partial<Components>\n}\n\nfunction parseMarkdownIntoBlocks(markdown: string): string[] {\n  const tokens = marked.lexer(markdown)\n  return tokens.map((token) => token.raw)\n}\n\nfunction extractLanguage(className?: string): string {\n  if (!className) return \"plaintext\"\n  const match = className.match(/language-(\\w+)/)\n  return match ? match[1] : \"plaintext\"\n}\n\nconst INITIAL_COMPONENTS: Partial<Components> = {\n  code: function CodeComponent({ className, children, ...props }) {\n    const isInline =\n      !props.node?.position?.start.line ||\n      props.node?.position?.start.line === props.node?.position?.end.line\n\n    if (isInline) {\n      return (\n        <span\n          className={cn(\n            \"bg-primary-foreground rounded-sm px-1 font-mono text-sm\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </span>\n      )\n    }\n\n    const language = extractLanguage(className)\n\n    return (\n      <CodeBlock className={className}>\n        <CodeBlockCode code={children as string} language={language} />\n      </CodeBlock>\n    )\n  },\n  pre: function PreComponent({ children }) {\n    return <>{children}</>\n  },\n}\n\nconst MemoizedMarkdownBlock = memo(\n  function MarkdownBlock({\n    content,\n    components = INITIAL_COMPONENTS,\n  }: {\n    content: string\n    components?: Partial<Components>\n  }) {\n    return (\n      <ReactMarkdown\n        remarkPlugins={[remarkGfm, remarkBreaks]}\n        components={components}\n      >\n        {content}\n      </ReactMarkdown>\n    )\n  },\n  function propsAreEqual(prevProps, nextProps) {\n    return prevProps.content === nextProps.content\n  }\n)\n\nMemoizedMarkdownBlock.displayName = \"MemoizedMarkdownBlock\"\n\nfunction MarkdownComponent({\n  children,\n  id,\n  className,\n  components = INITIAL_COMPONENTS,\n}: MarkdownProps) {\n  const generatedId = useId()\n  const blockId = id ?? generatedId\n  const blocks = useMemo(() => parseMarkdownIntoBlocks(children), [children])\n\n  return (\n    <div className={className}>\n      {blocks.map((block, index) => (\n        <MemoizedMarkdownBlock\n          key={`${blockId}-block-${index}`}\n          content={block}\n          components={components}\n        />\n      ))}\n    </div>\n  )\n}\n\nconst Markdown = memo(MarkdownComponent)\nMarkdown.displayName = \"Markdown\"\n\nexport { Markdown }\n"
        },
        {
          "path": "components/prompt-kit/code-block.tsx",
          "target": "@components/prompt-kit/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React, { useEffect, useState } from \"react\"\nimport { codeToHtml } from \"shiki\"\n\nexport type CodeBlockProps = {\n  children?: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlock({ children, className, ...props }: CodeBlockProps) {\n  return (\n    <div\n      className={cn(\n        \"not-prose flex w-full flex-col overflow-clip border\",\n        \"border-border bg-card text-card-foreground rounded-xl\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type CodeBlockCodeProps = {\n  code: string\n  language?: string\n  theme?: string\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlockCode({\n  code,\n  language = \"tsx\",\n  theme = \"github-light\",\n  className,\n  ...props\n}: CodeBlockCodeProps) {\n  const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)\n\n  useEffect(() => {\n    async function highlight() {\n      if (!code) {\n        setHighlightedHtml(\"<pre><code></code></pre>\")\n        return\n      }\n\n      const html = await codeToHtml(code, { lang: language, theme })\n      setHighlightedHtml(html)\n    }\n    highlight()\n  }, [code, language, theme])\n\n  const classNames = cn(\n    \"w-full overflow-x-auto text-[13px] [&>pre]:px-4 [&>pre]:py-4\",\n    className\n  )\n\n  // SSR fallback: render plain code if not hydrated yet\n  return highlightedHtml ? (\n    <div\n      data-code-theme={theme}\n      className={classNames}\n      dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n      {...props}\n    />\n  ) : (\n    <div data-code-theme={theme} className={classNames} {...props}>\n      <pre>\n        <code>{code}</code>\n      </pre>\n    </div>\n  )\n}\n\nexport type CodeBlockGroupProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction CodeBlockGroup({\n  children,\n  className,\n  ...props\n}: CodeBlockGroupProps) {\n  return (\n    <div\n      className={cn(\"flex items-center justify-between\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport { CodeBlockGroup, CodeBlockCode, CodeBlock }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "chat-container",
      "type": "registry:block",
      "title": "Chat Container",
      "description": "A component for creating chat interfaces with intelligent auto-scrolling behavior, designed to provide a smooth and responsive user experience",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6",
        "use-stick-to-bottom@^1.1.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/chat-container.tsx",
          "target": "@components/prompt-kit/chat-container.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { StickToBottom } from \"use-stick-to-bottom\"\n\nexport type ChatContainerRootProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport type ChatContainerContentProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport type ChatContainerScrollAnchorProps = {\n  className?: string\n  ref?: React.RefObject<HTMLDivElement>\n} & React.HTMLAttributes<HTMLDivElement>\n\nfunction ChatContainerRoot({\n  children,\n  className,\n  ...props\n}: ChatContainerRootProps) {\n  return (\n    <StickToBottom\n      className={cn(\"flex overflow-y-auto\", className)}\n      resize=\"smooth\"\n      initial=\"instant\"\n      role=\"log\"\n      {...props}\n    >\n      {children}\n    </StickToBottom>\n  )\n}\n\nfunction ChatContainerContent({\n  children,\n  className,\n  ...props\n}: ChatContainerContentProps) {\n  return (\n    <StickToBottom.Content\n      className={cn(\"flex w-full flex-col\", className)}\n      {...props}\n    >\n      {children}\n    </StickToBottom.Content>\n  )\n}\n\nfunction ChatContainerScrollAnchor({\n  className,\n  ...props\n}: ChatContainerScrollAnchorProps) {\n  return (\n    <div\n      className={cn(\"h-px w-full shrink-0 scroll-mt-4\", className)}\n      aria-hidden=\"true\"\n      {...props}\n    />\n  )\n}\n\nexport { ChatContainerRoot, ChatContainerContent, ChatContainerScrollAnchor }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "scroll-button",
      "type": "registry:block",
      "title": "Scroll Button",
      "description": "A floating button component that appears when users scroll up in a container, allowing them to quickly return to the bottom of the content",
      "dependencies": [
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6",
        "use-stick-to-bottom@^1.1.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/scroll-button.tsx",
          "target": "@components/prompt-kit/scroll-button.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { ChevronDown } from \"lucide-react\"\nimport { useStickToBottomContext } from \"use-stick-to-bottom\"\n\nexport type ScrollButtonProps = {\n  className?: string\n  variant?: VariantProps<typeof buttonVariants>[\"variant\"]\n  size?: VariantProps<typeof buttonVariants>[\"size\"]\n} & React.ButtonHTMLAttributes<HTMLButtonElement>\n\nfunction ScrollButton({\n  className,\n  variant = \"outline\",\n  size = \"sm\",\n  ...props\n}: ScrollButtonProps) {\n  const { isAtBottom, scrollToBottom } = useStickToBottomContext()\n\n  return (\n    <Button\n      variant={variant}\n      size={size}\n      className={cn(\n        \"h-10 w-10 rounded-full transition-all duration-150 ease-out\",\n        !isAtBottom\n          ? \"translate-y-0 scale-100 opacity-100\"\n          : \"pointer-events-none translate-y-4 scale-95 opacity-0\",\n        className\n      )}\n      onClick={() => scrollToBottom()}\n      {...props}\n    >\n      <ChevronDown className=\"h-5 w-5\" />\n    </Button>\n  )\n}\n\nexport { ScrollButton }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "loader",
      "type": "registry:block",
      "title": "Loader",
      "description": "A component for displaying a loading indicator with multiple variants and customizable styling",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/loader.tsx",
          "target": "@components/prompt-kit/loader.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React from \"react\"\n\nexport interface LoaderProps {\n  variant?:\n    | \"circular\"\n    | \"classic\"\n    | \"pulse\"\n    | \"pulse-dot\"\n    | \"dots\"\n    | \"typing\"\n    | \"wave\"\n    | \"bars\"\n    | \"terminal\"\n    | \"text-blink\"\n    | \"text-shimmer\"\n    | \"loading-dots\"\n  size?: \"sm\" | \"md\" | \"lg\"\n  text?: string\n  className?: string\n}\n\nexport function CircularLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"border-primary animate-spin rounded-full border-2 border-t-transparent\",\n        sizeClasses[size],\n        className\n      )}\n    >\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function ClassicLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  const barSizes = {\n    sm: { height: \"6px\", width: \"1.5px\" },\n    md: { height: \"8px\", width: \"2px\" },\n    lg: { height: \"10px\", width: \"2.5px\" },\n  }\n\n  return (\n    <div className={cn(\"relative\", sizeClasses[size], className)}>\n      <div className=\"absolute h-full w-full\">\n        {[...Array(12)].map((_, i) => (\n          <div\n            key={i}\n            className=\"bg-primary absolute animate-[spinner-fade_1.2s_linear_infinite] rounded-full\"\n            style={{\n              top: \"0\",\n              left: \"50%\",\n              marginLeft:\n                size === \"sm\" ? \"-0.75px\" : size === \"lg\" ? \"-1.25px\" : \"-1px\",\n              transformOrigin: `${size === \"sm\" ? \"0.75px\" : size === \"lg\" ? \"1.25px\" : \"1px\"} ${size === \"sm\" ? \"10px\" : size === \"lg\" ? \"14px\" : \"12px\"}`,\n              transform: `rotate(${i * 30}deg)`,\n              opacity: 0,\n              animationDelay: `${i * 0.1}s`,\n              height: barSizes[size].height,\n              width: barSizes[size].width,\n            }}\n          />\n        ))}\n      </div>\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function PulseLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-4\",\n    md: \"size-5\",\n    lg: \"size-6\",\n  }\n\n  return (\n    <div className={cn(\"relative\", sizeClasses[size], className)}>\n      <div className=\"border-primary absolute inset-0 animate-[thin-pulse_1.5s_ease-in-out_infinite] rounded-full border-2\" />\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function PulseDotLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const sizeClasses = {\n    sm: \"size-1\",\n    md: \"size-2\",\n    lg: \"size-3\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"bg-primary animate-[pulse-dot_1.2s_ease-in-out_infinite] rounded-full\",\n        sizeClasses[size],\n        className\n      )}\n    >\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function DotsLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const dotSizes = {\n    sm: \"h-1.5 w-1.5\",\n    md: \"h-2 w-2\",\n    lg: \"h-2.5 w-2.5\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[bounce-dots_1.4s_ease-in-out_infinite] rounded-full\",\n            dotSizes[size]\n          )}\n          style={{\n            animationDelay: `${i * 160}ms`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TypingLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const dotSizes = {\n    sm: \"h-1 w-1\",\n    md: \"h-1.5 w-1.5\",\n    lg: \"h-2 w-2\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[typing_1s_infinite] rounded-full\",\n            dotSizes[size]\n          )}\n          style={{\n            animationDelay: `${i * 250}ms`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function WaveLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const barWidths = {\n    sm: \"w-0.5\",\n    md: \"w-0.5\",\n    lg: \"w-1\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  const heights = {\n    sm: [\"6px\", \"9px\", \"12px\", \"9px\", \"6px\"],\n    md: [\"8px\", \"12px\", \"16px\", \"12px\", \"8px\"],\n    lg: [\"10px\", \"15px\", \"20px\", \"15px\", \"10px\"],\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center gap-0.5\",\n        containerSizes[size],\n        className\n      )}\n    >\n      {[...Array(5)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary animate-[wave_1s_ease-in-out_infinite] rounded-full\",\n            barWidths[size]\n          )}\n          style={{\n            animationDelay: `${i * 100}ms`,\n            height: heights[size][i],\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function BarsLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const barWidths = {\n    sm: \"w-1\",\n    md: \"w-1.5\",\n    lg: \"w-2\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4 gap-1\",\n    md: \"h-5 gap-1.5\",\n    lg: \"h-6 gap-2\",\n  }\n\n  return (\n    <div className={cn(\"flex\", containerSizes[size], className)}>\n      {[...Array(3)].map((_, i) => (\n        <div\n          key={i}\n          className={cn(\n            \"bg-primary h-full animate-[wave-bars_1.2s_ease-in-out_infinite]\",\n            barWidths[size]\n          )}\n          style={{\n            animationDelay: `${i * 0.2}s`,\n          }}\n        />\n      ))}\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TerminalLoader({\n  className,\n  size = \"md\",\n}: {\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const cursorSizes = {\n    sm: \"h-3 w-1.5\",\n    md: \"h-4 w-2\",\n    lg: \"h-5 w-2.5\",\n  }\n\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  const containerSizes = {\n    sm: \"h-4\",\n    md: \"h-5\",\n    lg: \"h-6\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex items-center space-x-1\",\n        containerSizes[size],\n        className\n      )}\n    >\n      <span className={cn(\"text-primary font-mono\", textSizes[size])}>\n        {\">\"}\n      </span>\n      <div\n        className={cn(\n          \"bg-primary animate-[blink_1s_step-end_infinite]\",\n          cursorSizes[size]\n        )}\n      />\n      <span className=\"sr-only\">Loading</span>\n    </div>\n  )\n}\n\nexport function TextBlinkLoader({\n  text = \"Thinking\",\n  className,\n  size = \"md\",\n}: {\n  text?: string\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"animate-[text-blink_2s_ease-in-out_infinite] font-medium\",\n        textSizes[size],\n        className\n      )}\n    >\n      {text}\n    </div>\n  )\n}\n\nexport function TextShimmerLoader({\n  text = \"Thinking\",\n  className,\n  size = \"md\",\n}: {\n  text?: string\n  className?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\n        \"bg-[linear-gradient(to_right,var(--muted-foreground)_40%,var(--foreground)_60%,var(--muted-foreground)_80%)]\",\n        \"bg-size-[200%_auto] bg-clip-text font-medium text-transparent\",\n        \"animate-[shimmer_4s_infinite_linear]\",\n        textSizes[size],\n        className\n      )}\n    >\n      {text}\n    </div>\n  )\n}\n\nexport function TextDotsLoader({\n  className,\n  text = \"Thinking\",\n  size = \"md\",\n}: {\n  className?: string\n  text?: string\n  size?: \"sm\" | \"md\" | \"lg\"\n}) {\n  const textSizes = {\n    sm: \"text-xs\",\n    md: \"text-sm\",\n    lg: \"text-base\",\n  }\n\n  return (\n    <div\n      className={cn(\"inline-flex items-center\", className)}\n    >\n      <span className={cn(\"text-primary font-medium\", textSizes[size])}>\n        {text}\n      </span>\n      <span className=\"inline-flex\">\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.2s]\">\n          .\n        </span>\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.4s]\">\n          .\n        </span>\n        <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.6s]\">\n          .\n        </span>\n      </span>\n    </div>\n  )\n}\n\nfunction Loader({\n  variant = \"circular\",\n  size = \"md\",\n  text,\n  className,\n}: LoaderProps) {\n  switch (variant) {\n    case \"circular\":\n      return <CircularLoader size={size} className={className} />\n    case \"classic\":\n      return <ClassicLoader size={size} className={className} />\n    case \"pulse\":\n      return <PulseLoader size={size} className={className} />\n    case \"pulse-dot\":\n      return <PulseDotLoader size={size} className={className} />\n    case \"dots\":\n      return <DotsLoader size={size} className={className} />\n    case \"typing\":\n      return <TypingLoader size={size} className={className} />\n    case \"wave\":\n      return <WaveLoader size={size} className={className} />\n    case \"bars\":\n      return <BarsLoader size={size} className={className} />\n    case \"terminal\":\n      return <TerminalLoader size={size} className={className} />\n    case \"text-blink\":\n      return <TextBlinkLoader text={text} size={size} className={className} />\n    case \"text-shimmer\":\n      return <TextShimmerLoader text={text} size={size} className={className} />\n    case \"loading-dots\":\n      return <TextDotsLoader text={text} size={size} className={className} />\n    default:\n      return <CircularLoader size={size} className={className} />\n  }\n}\n\nexport { Loader }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "prompt-suggestion",
      "type": "registry:block",
      "title": "Prompt Suggestion",
      "description": "A component for implementing interactive prompt suggestions in AI interfaces. The PromptSuggestion component offers two distinct modes: Normal Mode and Highlight Mode.",
      "dependencies": [
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/prompt-suggestion.tsx",
          "target": "@components/prompt-kit/prompt-suggestion.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { VariantProps } from \"class-variance-authority\"\n\nexport type PromptSuggestionProps = {\n  children: React.ReactNode\n  variant?: VariantProps<typeof buttonVariants>[\"variant\"]\n  size?: VariantProps<typeof buttonVariants>[\"size\"]\n  className?: string\n  highlight?: string\n} & React.ButtonHTMLAttributes<HTMLButtonElement>\n\nfunction PromptSuggestion({\n  children,\n  variant,\n  size,\n  className,\n  highlight,\n  ...props\n}: PromptSuggestionProps) {\n  const isHighlightMode = highlight !== undefined && highlight.trim() !== \"\"\n  const content = typeof children === \"string\" ? children : \"\"\n\n  if (!isHighlightMode) {\n    return (\n      <Button\n        variant={variant || \"outline\"}\n        size={size || \"lg\"}\n        className={cn(\"rounded-full\", className)}\n        {...props}\n      >\n        {children}\n      </Button>\n    )\n  }\n\n  if (!content) {\n    return (\n      <Button\n        variant={variant || \"ghost\"}\n        size={size || \"sm\"}\n        className={cn(\n          \"w-full cursor-pointer justify-start rounded-xl py-2\",\n          \"hover:bg-accent\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n      </Button>\n    )\n  }\n\n  const trimmedHighlight = highlight.trim()\n  const contentLower = content.toLowerCase()\n  const highlightLower = trimmedHighlight.toLowerCase()\n  const shouldHighlight = contentLower.includes(highlightLower)\n\n  return (\n    <Button\n      variant={variant || \"ghost\"}\n      size={size || \"sm\"}\n      className={cn(\n        \"w-full cursor-pointer justify-start gap-0 rounded-xl py-2\",\n        \"hover:bg-accent\",\n        className\n      )}\n      {...props}\n    >\n      {shouldHighlight ? (\n        (() => {\n          const index = contentLower.indexOf(highlightLower)\n          if (index === -1)\n            return (\n              <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                {content}\n              </span>\n            )\n\n          const actualHighlightedText = content.substring(\n            index,\n            index + highlightLower.length\n          )\n\n          const before = content.substring(0, index)\n          const after = content.substring(index + actualHighlightedText.length)\n\n          return (\n            <>\n              {before && (\n                <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                  {before}\n                </span>\n              )}\n              <span className=\"text-primary font-medium whitespace-pre-wrap\">\n                {actualHighlightedText}\n              </span>\n              {after && (\n                <span className=\"text-muted-foreground whitespace-pre-wrap\">\n                  {after}\n                </span>\n              )}\n            </>\n          )\n        })()\n      ) : (\n        <span className=\"text-muted-foreground whitespace-pre-wrap\">\n          {content}\n        </span>\n      )}\n    </Button>\n  )\n}\n\nexport { PromptSuggestion }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "response-stream",
      "type": "registry:block",
      "title": "Response Stream",
      "description": "A component to simulate streaming text on the client side, perfect for fake responses, or any controlled progressive text display.",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/response-stream.tsx",
          "target": "@components/prompt-kit/response-stream.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React, { useCallback, useEffect, useRef, useState } from \"react\"\n\nexport type Mode = \"typewriter\" | \"fade\"\n\nexport type UseTextStreamOptions = {\n  textStream: string | AsyncIterable<string>\n  speed?: number\n  mode?: Mode\n  onComplete?: () => void\n  fadeDuration?: number\n  segmentDelay?: number\n  characterChunkSize?: number\n  onError?: (error: unknown) => void\n}\n\nexport type UseTextStreamResult = {\n  displayedText: string\n  isComplete: boolean\n  segments: { text: string; index: number }[]\n  getFadeDuration: () => number\n  getSegmentDelay: () => number\n  reset: () => void\n  startStreaming: () => void\n  pause: () => void\n  resume: () => void\n}\n\nfunction useTextStream({\n  textStream,\n  speed = 20,\n  mode = \"typewriter\",\n  onComplete,\n  fadeDuration,\n  segmentDelay,\n  characterChunkSize,\n  onError,\n}: UseTextStreamOptions): UseTextStreamResult {\n  const [displayedText, setDisplayedText] = useState(\"\")\n  const [isComplete, setIsComplete] = useState(false)\n  const [segments, setSegments] = useState<{ text: string; index: number }[]>(\n    []\n  )\n\n  const speedRef = useRef(speed)\n  const modeRef = useRef(mode)\n  const currentIndexRef = useRef(0)\n  const animationRef = useRef<number | null>(null)\n  const fadeDurationRef = useRef(fadeDuration)\n  const segmentDelayRef = useRef(segmentDelay)\n  const characterChunkSizeRef = useRef(characterChunkSize)\n  const streamRef = useRef<AbortController | null>(null)\n  const completedRef = useRef(false)\n  const onCompleteRef = useRef(onComplete)\n\n  useEffect(() => {\n    speedRef.current = speed\n    modeRef.current = mode\n    fadeDurationRef.current = fadeDuration\n    segmentDelayRef.current = segmentDelay\n    characterChunkSizeRef.current = characterChunkSize\n  }, [speed, mode, fadeDuration, segmentDelay, characterChunkSize])\n\n  useEffect(() => {\n    onCompleteRef.current = onComplete\n  }, [onComplete])\n\n  const getChunkSize = useCallback(() => {\n    if (typeof characterChunkSizeRef.current === \"number\") {\n      return Math.max(1, characterChunkSizeRef.current)\n    }\n\n    const normalizedSpeed = Math.min(100, Math.max(1, speedRef.current))\n\n    if (modeRef.current === \"typewriter\") {\n      if (normalizedSpeed < 25) return 1\n      return Math.max(1, Math.round((normalizedSpeed - 25) / 10))\n    } else if (modeRef.current === \"fade\") {\n      return 1\n    }\n\n    return 1\n  }, [])\n\n  const getProcessingDelay = useCallback(() => {\n    if (typeof segmentDelayRef.current === \"number\") {\n      return Math.max(0, segmentDelayRef.current)\n    }\n\n    const normalizedSpeed = Math.min(100, Math.max(1, speedRef.current))\n    return Math.max(1, Math.round(100 / Math.sqrt(normalizedSpeed)))\n  }, [])\n\n  const getFadeDuration = useCallback(() => {\n    if (typeof fadeDurationRef.current === \"number\")\n      return Math.max(10, fadeDurationRef.current)\n\n    const normalizedSpeed = Math.min(100, Math.max(1, speedRef.current))\n    return Math.round(1000 / Math.sqrt(normalizedSpeed))\n  }, [])\n\n  const getSegmentDelay = useCallback(() => {\n    if (typeof segmentDelayRef.current === \"number\")\n      return Math.max(0, segmentDelayRef.current)\n\n    const normalizedSpeed = Math.min(100, Math.max(1, speedRef.current))\n    return Math.max(1, Math.round(100 / Math.sqrt(normalizedSpeed)))\n  }, [])\n\n  const updateSegments = useCallback((text: string) => {\n    if (modeRef.current === \"fade\") {\n      try {\n        const segmenter = new Intl.Segmenter(navigator.language, {\n          granularity: \"word\",\n        })\n        const segmentIterator = segmenter.segment(text)\n        const newSegments = Array.from(segmentIterator).map(\n          (segment, index) => ({\n            text: segment.segment,\n            index,\n          })\n        )\n        setSegments(newSegments)\n      } catch (error) {\n        const newSegments = text\n          .split(/(\\s+)/)\n          .filter(Boolean)\n          .map((word, index) => ({\n            text: word,\n            index,\n          }))\n        setSegments(newSegments)\n        onError?.(error)\n      }\n    }\n  }, [onError])\n\n  const markComplete = useCallback(() => {\n    if (!completedRef.current) {\n      completedRef.current = true\n      setIsComplete(true)\n      onCompleteRef.current?.()\n    }\n  }, [])\n\n  const reset = useCallback(() => {\n    currentIndexRef.current = 0\n    setDisplayedText(\"\")\n    setSegments([])\n    setIsComplete(false)\n    completedRef.current = false\n\n    if (animationRef.current) {\n      cancelAnimationFrame(animationRef.current)\n      animationRef.current = null\n    }\n  }, [])\n\n  const processStringTypewriter = useCallback(\n    (text: string) => {\n      let lastFrameTime = 0\n\n      const streamContent = (timestamp: number) => {\n        const delay = getProcessingDelay()\n        if (delay > 0 && timestamp - lastFrameTime < delay) {\n          animationRef.current = requestAnimationFrame(streamContent)\n          return\n        }\n        lastFrameTime = timestamp\n\n        if (currentIndexRef.current >= text.length) {\n          markComplete()\n          return\n        }\n\n        const chunkSize = getChunkSize()\n        const endIndex = Math.min(\n          currentIndexRef.current + chunkSize,\n          text.length\n        )\n        const newDisplayedText = text.slice(0, endIndex)\n\n        setDisplayedText(newDisplayedText)\n        if (modeRef.current === \"fade\") {\n          updateSegments(newDisplayedText)\n        }\n\n        currentIndexRef.current = endIndex\n\n        if (endIndex < text.length) {\n          animationRef.current = requestAnimationFrame(streamContent)\n        } else {\n          markComplete()\n        }\n      }\n\n      animationRef.current = requestAnimationFrame(streamContent)\n    },\n    [getProcessingDelay, getChunkSize, updateSegments, markComplete]\n  )\n\n  const processAsyncIterable = useCallback(\n    async (stream: AsyncIterable<string>) => {\n      const controller = new AbortController()\n      streamRef.current = controller\n\n      let displayed = \"\"\n\n      try {\n        for await (const chunk of stream) {\n          if (controller.signal.aborted) return\n\n          displayed += chunk\n          setDisplayedText(displayed)\n          updateSegments(displayed)\n        }\n\n        markComplete()\n      } catch (error) {\n        console.error(\"Error processing text stream:\", error)\n        markComplete()\n        onError?.(error)\n      }\n    },\n    [updateSegments, markComplete, onError]\n  )\n\n  const startStreaming = useCallback(() => {\n    reset()\n\n    if (typeof textStream === \"string\") {\n      processStringTypewriter(textStream)\n    } else if (textStream) {\n      processAsyncIterable(textStream)\n    }\n  }, [textStream, reset, processStringTypewriter, processAsyncIterable])\n\n  const pause = useCallback(() => {\n    if (animationRef.current) {\n      cancelAnimationFrame(animationRef.current)\n      animationRef.current = null\n    }\n  }, [])\n\n  const resume = useCallback(() => {\n    if (typeof textStream === \"string\" && !isComplete) {\n      processStringTypewriter(textStream)\n    }\n  }, [textStream, isComplete, processStringTypewriter])\n\n  useEffect(() => {\n    startStreaming()\n\n    return () => {\n      if (animationRef.current) {\n        cancelAnimationFrame(animationRef.current)\n      }\n      if (streamRef.current) {\n        streamRef.current.abort()\n      }\n    }\n  }, [textStream, startStreaming])\n\n  return {\n    displayedText,\n    isComplete,\n    segments,\n    getFadeDuration,\n    getSegmentDelay,\n    reset,\n    startStreaming,\n    pause,\n    resume,\n  }\n}\n\nexport type ResponseStreamProps = {\n  textStream: string | AsyncIterable<string>\n  mode?: Mode\n  speed?: number // 1-100, where 1 is slowest and 100 is fastest\n  className?: string\n  onComplete?: () => void\n  as?: keyof React.JSX.IntrinsicElements // Element type to render\n  fadeDuration?: number // Custom fade duration in ms (overrides speed)\n  segmentDelay?: number // Custom delay between segments in ms (overrides speed)\n  characterChunkSize?: number // Custom characters per frame for typewriter mode (overrides speed)\n}\n\nfunction ResponseStream({\n  textStream,\n  mode = \"typewriter\",\n  speed = 20,\n  className = \"\",\n  onComplete,\n  as = \"div\",\n  fadeDuration,\n  segmentDelay,\n  characterChunkSize,\n}: ResponseStreamProps) {\n  const animationEndRef = useRef<(() => void) | null>(null)\n\n  const {\n    displayedText,\n    isComplete,\n    segments,\n    getFadeDuration,\n    getSegmentDelay,\n  } = useTextStream({\n    textStream,\n    speed,\n    mode,\n    onComplete,\n    fadeDuration,\n    segmentDelay,\n    characterChunkSize,\n  })\n\n  useEffect(() => {\n    animationEndRef.current = onComplete ?? null\n  }, [onComplete])\n\n  const handleLastSegmentAnimationEnd = useCallback(() => {\n    if (animationEndRef.current && isComplete) {\n      animationEndRef.current()\n    }\n  }, [isComplete])\n\n  // fadeStyle is the style for the fade animation\n  const fadeStyle = `\n    @keyframes fadeIn {\n      from { opacity: 0; }\n      to { opacity: 1; }\n    }\n    \n    .fade-segment {\n      display: inline-block;\n      opacity: 0;\n      animation: fadeIn ${getFadeDuration()}ms ease-out forwards;\n    }\n\n    .fade-segment-space {\n      white-space: pre;\n    }\n  `\n\n  const renderContent = () => {\n    switch (mode) {\n      case \"typewriter\":\n        return <>{displayedText}</>\n\n      case \"fade\":\n        return (\n          <>\n            <style>{fadeStyle}</style>\n            <div className=\"relative\">\n              {segments.map((segment, idx) => {\n                const isWhitespace = /^\\s+$/.test(segment.text)\n                const isLastSegment = idx === segments.length - 1\n\n                return (\n                  <span\n                    key={`${segment.text}-${idx}`}\n                    className={cn(\n                      \"fade-segment\",\n                      isWhitespace && \"fade-segment-space\"\n                    )}\n                    style={{\n                      animationDelay: `${idx * getSegmentDelay()}ms`,\n                    }}\n                    onAnimationEnd={\n                      isLastSegment ? handleLastSegmentAnimationEnd : undefined\n                    }\n                  >\n                    {segment.text}\n                  </span>\n                )\n              })}\n            </div>\n          </>\n        )\n\n      default:\n        return <>{displayedText}</>\n    }\n  }\n\n  const Container = as as keyof React.JSX.IntrinsicElements\n\n  return <Container className={className}>{renderContent()}</Container>\n}\n\nexport { useTextStream, ResponseStream }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "reasoning",
      "type": "registry:block",
      "title": "Reasoning",
      "description": "A collapsible component for showing AI reasoning, explanations, or logic. You can control it manually or let it auto-close when the stream ends. Markdown is supported.",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "marked@^15.0.7",
        "react-markdown@^10.1.0",
        "remark-breaks@^4.0.0",
        "remark-gfm@^4.0.1",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/reasoning.tsx",
          "target": "@components/prompt-kit/reasoning.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport React, {\n  createContext,\n  useContext,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\"\nimport { Markdown } from \"./markdown\"\n\ntype ReasoningContextType = {\n  isOpen: boolean\n  onOpenChange: (open: boolean) => void\n}\n\nconst ReasoningContext = createContext<ReasoningContextType | undefined>(\n  undefined\n)\n\nfunction useReasoningContext() {\n  const context = useContext(ReasoningContext)\n  if (!context) {\n    throw new Error(\n      \"useReasoningContext must be used within a Reasoning provider\"\n    )\n  }\n  return context\n}\n\nexport type ReasoningProps = {\n  children: React.ReactNode\n  className?: string\n  open?: boolean\n  onOpenChange?: (open: boolean) => void\n  isStreaming?: boolean\n}\nfunction Reasoning({\n  children,\n  className,\n  open,\n  onOpenChange,\n  isStreaming,\n}: ReasoningProps) {\n  const [internalOpen, setInternalOpen] = useState(false)\n  const [wasAutoOpened, setWasAutoOpened] = useState(false)\n\n  const isControlled = open !== undefined\n  const isOpen = isControlled ? open : internalOpen\n\n  const handleOpenChange = (newOpen: boolean) => {\n    if (!isControlled) {\n      setInternalOpen(newOpen)\n    }\n    onOpenChange?.(newOpen)\n  }\n\n  useEffect(() => {\n    if (isStreaming && !wasAutoOpened) {\n      if (!isControlled) setInternalOpen(true)\n      setWasAutoOpened(true)\n    }\n\n    if (!isStreaming && wasAutoOpened) {\n      if (!isControlled) setInternalOpen(false)\n      setWasAutoOpened(false)\n    }\n  }, [isStreaming, wasAutoOpened, isControlled])\n\n  return (\n    <ReasoningContext.Provider\n      value={{\n        isOpen,\n        onOpenChange: handleOpenChange,\n      }}\n    >\n      <div className={className}>{children}</div>\n    </ReasoningContext.Provider>\n  )\n}\n\nexport type ReasoningTriggerProps = {\n  children: React.ReactNode\n  className?: string\n} & React.HTMLAttributes<HTMLButtonElement>\n\nfunction ReasoningTrigger({\n  children,\n  className,\n  ...props\n}: ReasoningTriggerProps) {\n  const { isOpen, onOpenChange } = useReasoningContext()\n\n  return (\n    <button\n      className={cn(\"flex cursor-pointer items-center gap-2\", className)}\n      onClick={() => onOpenChange(!isOpen)}\n      {...props}\n    >\n      <span className=\"text-primary\">{children}</span>\n      <div\n        className={cn(\n          \"transform transition-transform\",\n          isOpen ? \"rotate-180\" : \"\"\n        )}\n      >\n        <ChevronDownIcon className=\"size-4\" />\n      </div>\n    </button>\n  )\n}\n\nexport type ReasoningContentProps = {\n  children: React.ReactNode\n  className?: string\n  markdown?: boolean\n  contentClassName?: string\n} & React.HTMLAttributes<HTMLDivElement>\n\nfunction ReasoningContent({\n  children,\n  className,\n  contentClassName,\n  markdown = false,\n  ...props\n}: ReasoningContentProps) {\n  const contentRef = useRef<HTMLDivElement>(null)\n  const innerRef = useRef<HTMLDivElement>(null)\n  const { isOpen } = useReasoningContext()\n\n  useEffect(() => {\n    if (!contentRef.current || !innerRef.current) return\n\n    const observer = new ResizeObserver(() => {\n      if (contentRef.current && innerRef.current && isOpen) {\n        contentRef.current.style.maxHeight = `${innerRef.current.scrollHeight}px`\n      }\n    })\n\n    observer.observe(innerRef.current)\n\n    if (isOpen) {\n      contentRef.current.style.maxHeight = `${innerRef.current.scrollHeight}px`\n    }\n\n    return () => observer.disconnect()\n  }, [isOpen])\n\n  const content = markdown ? (\n    <Markdown>{children as string}</Markdown>\n  ) : (\n    children\n  )\n\n  return (\n    <div\n      ref={contentRef}\n      className={cn(\n        \"overflow-hidden transition-[max-height] duration-150 ease-out\",\n        className\n      )}\n      style={{\n        maxHeight: isOpen ? contentRef.current?.scrollHeight : \"0px\",\n      }}\n      {...props}\n    >\n      <div\n        ref={innerRef}\n        className={cn(\n          \"text-muted-foreground prose prose-sm dark:prose-invert\",\n          contentClassName\n        )}\n      >\n        {content}\n      </div>\n    </div>\n  )\n}\n\nexport { Reasoning, ReasoningTrigger, ReasoningContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/prompt-kit/markdown.tsx",
          "target": "@components/prompt-kit/markdown.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { marked } from \"marked\"\nimport { memo, useId, useMemo } from \"react\"\nimport ReactMarkdown, { Components } from \"react-markdown\"\nimport remarkBreaks from \"remark-breaks\"\nimport remarkGfm from \"remark-gfm\"\nimport { CodeBlock, CodeBlockCode } from \"./code-block\"\n\nexport type MarkdownProps = {\n  children: string\n  id?: string\n  className?: string\n  components?: Partial<Components>\n}\n\nfunction parseMarkdownIntoBlocks(markdown: string): string[] {\n  const tokens = marked.lexer(markdown)\n  return tokens.map((token) => token.raw)\n}\n\nfunction extractLanguage(className?: string): string {\n  if (!className) return \"plaintext\"\n  const match = className.match(/language-(\\w+)/)\n  return match ? match[1] : \"plaintext\"\n}\n\nconst INITIAL_COMPONENTS: Partial<Components> = {\n  code: function CodeComponent({ className, children, ...props }) {\n    const isInline =\n      !props.node?.position?.start.line ||\n      props.node?.position?.start.line === props.node?.position?.end.line\n\n    if (isInline) {\n      return (\n        <span\n          className={cn(\n            \"bg-primary-foreground rounded-sm px-1 font-mono text-sm\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </span>\n      )\n    }\n\n    const language = extractLanguage(className)\n\n    return (\n      <CodeBlock className={className}>\n        <CodeBlockCode code={children as string} language={language} />\n      </CodeBlock>\n    )\n  },\n  pre: function PreComponent({ children }) {\n    return <>{children}</>\n  },\n}\n\nconst MemoizedMarkdownBlock = memo(\n  function MarkdownBlock({\n    content,\n    components = INITIAL_COMPONENTS,\n  }: {\n    content: string\n    components?: Partial<Components>\n  }) {\n    return (\n      <ReactMarkdown\n        remarkPlugins={[remarkGfm, remarkBreaks]}\n        components={components}\n      >\n        {content}\n      </ReactMarkdown>\n    )\n  },\n  function propsAreEqual(prevProps, nextProps) {\n    return prevProps.content === nextProps.content\n  }\n)\n\nMemoizedMarkdownBlock.displayName = \"MemoizedMarkdownBlock\"\n\nfunction MarkdownComponent({\n  children,\n  id,\n  className,\n  components = INITIAL_COMPONENTS,\n}: MarkdownProps) {\n  const generatedId = useId()\n  const blockId = id ?? generatedId\n  const blocks = useMemo(() => parseMarkdownIntoBlocks(children), [children])\n\n  return (\n    <div className={className}>\n      {blocks.map((block, index) => (\n        <MemoizedMarkdownBlock\n          key={`${blockId}-block-${index}`}\n          content={block}\n          components={components}\n        />\n      ))}\n    </div>\n  )\n}\n\nconst Markdown = memo(MarkdownComponent)\nMarkdown.displayName = \"Markdown\"\n\nexport { Markdown }\n"
        },
        {
          "path": "components/prompt-kit/code-block.tsx",
          "target": "@components/prompt-kit/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React, { useEffect, useState } from \"react\"\nimport { codeToHtml } from \"shiki\"\n\nexport type CodeBlockProps = {\n  children?: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlock({ children, className, ...props }: CodeBlockProps) {\n  return (\n    <div\n      className={cn(\n        \"not-prose flex w-full flex-col overflow-clip border\",\n        \"border-border bg-card text-card-foreground rounded-xl\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type CodeBlockCodeProps = {\n  code: string\n  language?: string\n  theme?: string\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlockCode({\n  code,\n  language = \"tsx\",\n  theme = \"github-light\",\n  className,\n  ...props\n}: CodeBlockCodeProps) {\n  const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)\n\n  useEffect(() => {\n    async function highlight() {\n      if (!code) {\n        setHighlightedHtml(\"<pre><code></code></pre>\")\n        return\n      }\n\n      const html = await codeToHtml(code, { lang: language, theme })\n      setHighlightedHtml(html)\n    }\n    highlight()\n  }, [code, language, theme])\n\n  const classNames = cn(\n    \"w-full overflow-x-auto text-[13px] [&>pre]:px-4 [&>pre]:py-4\",\n    className\n  )\n\n  // SSR fallback: render plain code if not hydrated yet\n  return highlightedHtml ? (\n    <div\n      data-code-theme={theme}\n      className={classNames}\n      dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n      {...props}\n    />\n  ) : (\n    <div data-code-theme={theme} className={classNames} {...props}>\n      <pre>\n        <code>{code}</code>\n      </pre>\n    </div>\n  )\n}\n\nexport type CodeBlockGroupProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction CodeBlockGroup({\n  children,\n  className,\n  ...props\n}: CodeBlockGroupProps) {\n  return (\n    <div\n      className={cn(\"flex items-center justify-between\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport { CodeBlockGroup, CodeBlockCode, CodeBlock }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "file-upload",
      "type": "registry:block",
      "title": "File Upload",
      "description": "A component for creating drag-and-drop file upload interfaces with support for single or multiple files, custom triggers, and visual feedback during file dragging operations.",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/file-upload.tsx",
          "target": "@components/prompt-kit/file-upload.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport {\n  Children,\n  cloneElement,\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\"\nimport { createPortal } from \"react-dom\"\n\ntype FileUploadContextValue = {\n  isDragging: boolean\n  inputRef: React.RefObject<HTMLInputElement | null>\n  multiple?: boolean\n  disabled?: boolean\n}\n\nconst FileUploadContext = createContext<FileUploadContextValue | null>(null)\n\nexport type FileUploadProps = {\n  onFilesAdded: (files: File[]) => void\n  children: React.ReactNode\n  multiple?: boolean\n  accept?: string\n  disabled?: boolean\n}\n\nfunction FileUpload({\n  onFilesAdded,\n  children,\n  multiple = true,\n  accept,\n  disabled = false,\n}: FileUploadProps) {\n  const inputRef = useRef<HTMLInputElement>(null)\n  const [isDragging, setIsDragging] = useState(false)\n  const dragCounter = useRef(0)\n\n  const handleFiles = useCallback(\n    (files: FileList) => {\n      const newFiles = Array.from(files)\n      if (multiple) {\n        onFilesAdded(newFiles)\n      } else {\n        onFilesAdded(newFiles.slice(0, 1))\n      }\n    },\n    [multiple, onFilesAdded]\n  )\n\n  useEffect(() => {\n    const handleDrag = (e: DragEvent) => {\n      e.preventDefault()\n      e.stopPropagation()\n    }\n\n    const handleDragIn = (e: DragEvent) => {\n      handleDrag(e)\n      dragCounter.current++\n      if (e.dataTransfer?.items.length) setIsDragging(true)\n    }\n\n    const handleDragOut = (e: DragEvent) => {\n      handleDrag(e)\n      dragCounter.current--\n      if (dragCounter.current === 0) setIsDragging(false)\n    }\n\n    const handleDrop = (e: DragEvent) => {\n      handleDrag(e)\n      setIsDragging(false)\n      dragCounter.current = 0\n      if (e.dataTransfer?.files.length) {\n        handleFiles(e.dataTransfer.files)\n      }\n    }\n\n    window.addEventListener(\"dragenter\", handleDragIn)\n    window.addEventListener(\"dragleave\", handleDragOut)\n    window.addEventListener(\"dragover\", handleDrag)\n    window.addEventListener(\"drop\", handleDrop)\n\n    return () => {\n      window.removeEventListener(\"dragenter\", handleDragIn)\n      window.removeEventListener(\"dragleave\", handleDragOut)\n      window.removeEventListener(\"dragover\", handleDrag)\n      window.removeEventListener(\"drop\", handleDrop)\n    }\n  }, [handleFiles, onFilesAdded, multiple])\n\n  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {\n    if (e.target.files?.length) {\n      handleFiles(e.target.files)\n      e.target.value = \"\"\n    }\n  }\n\n  return (\n    <FileUploadContext.Provider\n      value={{ isDragging, inputRef, multiple, disabled }}\n    >\n      <input\n        type=\"file\"\n        ref={inputRef}\n        onChange={handleFileSelect}\n        className=\"hidden\"\n        multiple={multiple}\n        accept={accept}\n        aria-hidden\n        disabled={disabled}\n      />\n      {children}\n    </FileUploadContext.Provider>\n  )\n}\n\nexport type FileUploadTriggerProps =\n  React.ComponentPropsWithoutRef<\"button\"> & {\n    asChild?: boolean\n  }\n\nfunction FileUploadTrigger({\n  asChild = false,\n  className,\n  children,\n  ...props\n}: FileUploadTriggerProps) {\n  const context = useContext(FileUploadContext)\n  const handleClick = () => context?.inputRef.current?.click()\n\n  if (asChild) {\n    const child = Children.only(children) as React.ReactElement<\n      React.HTMLAttributes<HTMLElement>\n    >\n    return cloneElement(child, {\n      ...props,\n      role: \"button\",\n      className: cn(className, child.props.className),\n      onClick: (e: React.MouseEvent) => {\n        e.stopPropagation()\n        handleClick()\n        child.props.onClick?.(e as React.MouseEvent<HTMLElement>)\n      },\n    })\n  }\n\n  return (\n    <button\n      type=\"button\"\n      className={className}\n      onClick={handleClick}\n      {...props}\n    >\n      {children}\n    </button>\n  )\n}\n\ntype FileUploadContentProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction FileUploadContent({ className, ...props }: FileUploadContentProps) {\n  const context = useContext(FileUploadContext)\n  const [mounted, setMounted] = useState(false)\n\n  useEffect(() => {\n    setMounted(true)\n    return () => setMounted(false)\n  }, [])\n\n  if (!context?.isDragging || !mounted || context?.disabled) {\n    return null\n  }\n\n  const content = (\n    <div\n      className={cn(\n        \"bg-background/80 fixed inset-0 z-50 flex items-center justify-center backdrop-blur-sm\",\n        \"animate-in fade-in-0 slide-in-from-bottom-10 zoom-in-90 duration-150\",\n        className\n      )}\n      {...props}\n    />\n  )\n\n  return createPortal(content, document.body)\n}\n\nexport { FileUpload, FileUploadTrigger, FileUploadContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "jsx-preview",
      "type": "registry:block",
      "title": "Jsx Preview",
      "description": "A component for rendering JSX strings as React components, with support for streaming content and automatic tag completion.",
      "dependencies": [
        "react-jsx-parser@^2.4.0",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/jsx-preview.tsx",
          "target": "@components/prompt-kit/jsx-preview.tsx",
          "type": "registry:component",
          "content": "import * as React from \"react\"\nimport JsxParser from \"react-jsx-parser\"\nimport type { TProps as JsxParserProps } from \"react-jsx-parser\"\n\nfunction matchJsxTag(code: string) {\n  if (code.trim() === \"\") {\n    return null\n  }\n\n  const tagRegex = /<\\/?([a-zA-Z][a-zA-Z0-9]*)\\s*([^>]*?)(\\/)?>/\n  const match = code.match(tagRegex)\n\n  if (!match || typeof match.index === \"undefined\") {\n    return null\n  }\n\n  const [fullMatch, tagName, attributes, selfClosing] = match\n\n  const type = selfClosing\n    ? \"self-closing\"\n    : fullMatch.startsWith(\"</\")\n      ? \"closing\"\n      : \"opening\"\n\n  return {\n    tag: fullMatch,\n    tagName,\n    type,\n    attributes: attributes.trim(),\n    startIndex: match.index,\n    endIndex: match.index + fullMatch.length,\n  }\n}\n\nfunction completeJsxTag(code: string) {\n  const stack: string[] = []\n  let result = \"\"\n  let currentPosition = 0\n\n  while (currentPosition < code.length) {\n    const match = matchJsxTag(code.slice(currentPosition))\n    if (!match) break\n    const { tagName, type, endIndex } = match\n\n    if (type === \"opening\") {\n      stack.push(tagName)\n    } else if (type === \"closing\") {\n      stack.pop()\n    }\n\n    result += code.slice(currentPosition, currentPosition + endIndex)\n    currentPosition += endIndex\n  }\n\n  return (\n    result +\n    stack\n      .reverse()\n      .map((tag) => `</${tag}>`)\n      .join(\"\")\n  )\n}\n\nexport type JSXPreviewProps = {\n  jsx: string\n  isStreaming?: boolean\n} & JsxParserProps\n\nfunction JSXPreview({ jsx, isStreaming = false, ...props }: JSXPreviewProps) {\n  const processedJsx = React.useMemo(\n    () => (isStreaming ? completeJsxTag(jsx) : jsx),\n    [jsx, isStreaming]\n  )\n\n  // Cast JsxParser to any to work around the type incompatibility\n  const Parser = JsxParser as unknown as React.ComponentType<JsxParserProps>\n\n  return <Parser jsx={processedJsx} {...props} />\n}\n\nexport { JSXPreview }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "tool",
      "type": "registry:block",
      "title": "Tool",
      "description": "Displays tool call details including input, output, status, and errors. Ideal for visualizing AI tool usage in chat UIs.",
      "dependencies": [
        "@radix-ui/react-collapsible@^1.1.10",
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/tool.tsx",
          "target": "@components/prompt-kit/tool.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  CheckCircle,\n  ChevronDown,\n  Loader2,\n  Settings,\n  XCircle,\n} from \"lucide-react\"\nimport { useState } from \"react\"\n\nexport type ToolPart = {\n  type: string\n  state:\n    | \"input-streaming\"\n    | \"input-available\"\n    | \"output-available\"\n    | \"output-error\"\n  input?: Record<string, unknown>\n  output?: Record<string, unknown>\n  toolCallId?: string\n  errorText?: string\n}\n\nexport type ToolProps = {\n  toolPart: ToolPart\n  defaultOpen?: boolean\n  className?: string\n}\n\nconst Tool = ({ toolPart, defaultOpen = false, className }: ToolProps) => {\n  const [isOpen, setIsOpen] = useState(defaultOpen)\n\n  const { state, input, output, toolCallId } = toolPart\n\n  const getStateIcon = () => {\n    switch (state) {\n      case \"input-streaming\":\n        return <Loader2 className=\"h-4 w-4 animate-spin text-blue-500\" />\n      case \"input-available\":\n        return <Settings className=\"h-4 w-4 text-orange-500\" />\n      case \"output-available\":\n        return <CheckCircle className=\"h-4 w-4 text-green-500\" />\n      case \"output-error\":\n        return <XCircle className=\"h-4 w-4 text-red-500\" />\n      default:\n        return <Settings className=\"text-muted-foreground h-4 w-4\" />\n    }\n  }\n\n  const getStateBadge = () => {\n    const baseClasses = \"px-2 py-1 rounded-full text-xs font-medium\"\n    switch (state) {\n      case \"input-streaming\":\n        return (\n          <span\n            className={cn(\n              baseClasses,\n              \"bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400\"\n            )}\n          >\n            Processing\n          </span>\n        )\n      case \"input-available\":\n        return (\n          <span\n            className={cn(\n              baseClasses,\n              \"bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400\"\n            )}\n          >\n            Ready\n          </span>\n        )\n      case \"output-available\":\n        return (\n          <span\n            className={cn(\n              baseClasses,\n              \"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\"\n            )}\n          >\n            Completed\n          </span>\n        )\n      case \"output-error\":\n        return (\n          <span\n            className={cn(\n              baseClasses,\n              \"bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400\"\n            )}\n          >\n            Error\n          </span>\n        )\n      default:\n        return (\n          <span\n            className={cn(\n              baseClasses,\n              \"bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400\"\n            )}\n          >\n            Pending\n          </span>\n        )\n    }\n  }\n\n  const formatValue = (value: unknown): string => {\n    if (value === null) return \"null\"\n    if (value === undefined) return \"undefined\"\n    if (typeof value === \"string\") return value\n    if (typeof value === \"object\") {\n      return JSON.stringify(value, null, 2)\n    }\n    return String(value)\n  }\n\n  return (\n    <div\n      className={cn(\n        \"border-border mt-3 overflow-hidden rounded-lg border\",\n        className\n      )}\n    >\n      <Collapsible open={isOpen} onOpenChange={setIsOpen}>\n        <CollapsibleTrigger asChild>\n          <Button\n            variant=\"ghost\"\n            className=\"bg-background h-auto w-full justify-between rounded-b-none px-3 py-2 font-normal\"\n          >\n            <div className=\"flex items-center gap-2\">\n              {getStateIcon()}\n              <span className=\"font-mono text-sm font-medium\">\n                {toolPart.type}\n              </span>\n              {getStateBadge()}\n            </div>\n            <ChevronDown className={cn(\"h-4 w-4\", isOpen && \"rotate-180\")} />\n          </Button>\n        </CollapsibleTrigger>\n        <CollapsibleContent\n          className={cn(\n            \"border-border border-t\",\n            \"data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down overflow-hidden\"\n          )}\n        >\n          <div className=\"bg-background space-y-3 p-3\">\n            {input && Object.keys(input).length > 0 && (\n              <div>\n                <h4 className=\"text-muted-foreground mb-2 text-sm font-medium\">\n                  Input\n                </h4>\n                <div className=\"bg-background rounded border p-2 font-mono text-sm\">\n                  {Object.entries(input).map(([key, value]) => (\n                    <div key={key} className=\"mb-1\">\n                      <span className=\"text-muted-foreground\">{key}:</span>{\" \"}\n                      <span>{formatValue(value)}</span>\n                    </div>\n                  ))}\n                </div>\n              </div>\n            )}\n\n            {output && (\n              <div>\n                <h4 className=\"text-muted-foreground mb-2 text-sm font-medium\">\n                  Output\n                </h4>\n                <div className=\"bg-background max-h-60 overflow-auto rounded border p-2 font-mono text-sm\">\n                  <pre className=\"whitespace-pre-wrap\">\n                    {formatValue(output)}\n                  </pre>\n                </div>\n              </div>\n            )}\n\n            {state === \"output-error\" && toolPart.errorText && (\n              <div>\n                <h4 className=\"mb-2 text-sm font-medium text-red-500\">Error</h4>\n                <div className=\"bg-background rounded border border-red-200 p-2 text-sm dark:border-red-950 dark:bg-red-900/20\">\n                  {toolPart.errorText}\n                </div>\n              </div>\n            )}\n\n            {state === \"input-streaming\" && (\n              <div className=\"text-muted-foreground text-sm\">\n                Processing tool call...\n              </div>\n            )}\n\n            {toolCallId && (\n              <div className=\"text-muted-foreground border-t border-blue-200 pt-2 text-xs\">\n                <span className=\"font-mono\">Call ID: {toolCallId}</span>\n              </div>\n            )}\n          </div>\n        </CollapsibleContent>\n      </Collapsible>\n    </div>\n  )\n}\n\nexport { Tool }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/collapsible.tsx",
          "target": "@components/ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "source",
      "type": "registry:block",
      "title": "Source",
      "description": "Displays website sources used by AI-generated content, showing URL details, titles, and descriptions on hover.",
      "dependencies": [
        "@radix-ui/react-hover-card@1.1.14",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/source.tsx",
          "target": "@components/prompt-kit/source.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n/* eslint-disable @next/next/no-img-element -- favicon URLs are external source metadata */\n\nimport {\n  HoverCard,\n  HoverCardContent,\n  HoverCardTrigger,\n} from \"@/components/prompt-kit/_ui/hover-card\"\nimport { cn } from \"@/lib/utils\"\nimport { createContext, useContext } from \"react\"\n\nconst SourceContext = createContext<{\n  href: string\n  domain: string\n} | null>(null)\n\nfunction useSourceContext() {\n  const ctx = useContext(SourceContext)\n  if (!ctx) throw new Error(\"Source.* must be used inside <Source>\")\n  return ctx\n}\n\nexport type SourceProps = {\n  href: string\n  children: React.ReactNode\n}\n\nexport function Source({ href, children }: SourceProps) {\n  let domain = \"\"\n  try {\n    domain = new URL(href).hostname\n  } catch {\n    domain = href.split(\"/\").pop() || href\n  }\n\n  return (\n    <SourceContext.Provider value={{ href, domain }}>\n      <HoverCard openDelay={150} closeDelay={0}>\n        {children}\n      </HoverCard>\n    </SourceContext.Provider>\n  )\n}\n\nexport type SourceTriggerProps = {\n  label?: string | number\n  showFavicon?: boolean\n  className?: string\n}\n\nexport function SourceTrigger({\n  label,\n  showFavicon = false,\n  className,\n}: SourceTriggerProps) {\n  const { href, domain } = useSourceContext()\n  const labelToShow = label ?? domain.replace(\"www.\", \"\")\n\n  return (\n    <HoverCardTrigger asChild>\n      <a\n        href={href}\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        className={cn(\n          \"bg-muted text-muted-foreground hover:bg-muted-foreground/30 hover:text-primary inline-flex h-5 max-w-32 items-center gap-1 overflow-hidden rounded-full py-0 text-xs no-underline transition-colors duration-150\",\n          showFavicon ? \"pr-2 pl-1\" : \"px-1\",\n          className\n        )}\n      >\n        {showFavicon && (\n          <img\n            src={`https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(\n              href\n            )}`}\n            alt=\"favicon\"\n            width={14}\n            height={14}\n            className=\"size-3.5 rounded-full\"\n          />\n        )}\n        <span className=\"truncate tabular-nums text-center font-normal\">{labelToShow}</span>\n      </a>\n    </HoverCardTrigger>\n  )\n}\n\nexport type SourceContentProps = {\n  title: string\n  description: string\n  className?: string\n}\n\nexport function SourceContent({\n  title,\n  description,\n  className,\n}: SourceContentProps) {\n  const { href, domain } = useSourceContext()\n\n  return (\n    <HoverCardContent className={cn(\"w-80 p-0 shadow-xs\", className)}>\n      <a\n        href={href}\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        className=\"flex flex-col gap-2 p-3\"\n      >\n        <div className=\"flex items-center gap-1.5\">\n          <img\n            src={`https://www.google.com/s2/favicons?sz=64&domain_url=${encodeURIComponent(\n              href\n            )}`}\n            alt=\"favicon\"\n            className=\"size-4 rounded-full\"\n            width={16}\n            height={16}\n          />\n          <div className=\"text-primary truncate text-sm\">\n            {domain.replace(\"www.\", \"\")}\n          </div>\n        </div>\n        <div className=\"line-clamp-2 text-sm font-medium\">{title}</div>\n        <div className=\"text-muted-foreground line-clamp-2 text-sm\">\n          {description}\n        </div>\n      </a>\n    </HoverCardContent>\n  )\n}\n"
        },
        {
          "path": "components/prompt-kit/_ui/hover-card.tsx",
          "target": "@components/prompt-kit/_ui/hover-card.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as HoverCardPrimitive from \"@radix-ui/react-hover-card\"\nimport * as React from \"react\"\n\nfunction HoverCard({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n  return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />\n}\n\nfunction HoverCardTrigger({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n  return (\n    <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n  )\n}\n\nfunction HoverCardContent({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n  return (\n    <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n      <HoverCardPrimitive.Content\n        data-slot=\"hover-card-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n          className\n        )}\n        {...props}\n      />\n    </HoverCardPrimitive.Portal>\n  )\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "image",
      "type": "registry:block",
      "title": "Image",
      "description": "A component for displaying images from base64 or Uint8Array data, with full accessibility and responsive styling. Perfect for AI-generated or user-uploaded images.",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/image.tsx",
          "target": "@components/prompt-kit/image.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n/* eslint-disable @next/next/no-img-element -- generated blob/data URLs cannot use next/image */\n\nimport { cn } from \"@/lib/utils\"\nimport { useEffect, useState, type ImgHTMLAttributes } from \"react\"\n\nexport type GeneratedImageLike = {\n  base64?: string\n  uint8Array?: Uint8Array\n  mediaType?: string\n}\n\nexport type ImageProps = GeneratedImageLike &\n  Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\"> & {\n    alt: string\n  }\n\nfunction getImageSrc({\n  base64,\n  mediaType,\n}: Pick<GeneratedImageLike, \"base64\" | \"mediaType\">) {\n  if (base64 && mediaType) {\n    return `data:${mediaType};base64,${base64}`\n  }\n  return undefined\n}\n\nexport const Image = ({\n  base64,\n  uint8Array,\n  mediaType = \"image/png\",\n  className,\n  alt,\n  ...props\n}: ImageProps) => {\n  const [objectUrl, setObjectUrl] = useState<string | undefined>(undefined)\n\n  useEffect(() => {\n    if (uint8Array && mediaType) {\n      const blob = new Blob([uint8Array as BlobPart], { type: mediaType })\n      const url = URL.createObjectURL(blob)\n      setObjectUrl(url)\n      return () => {\n        URL.revokeObjectURL(url)\n      }\n    }\n    setObjectUrl(undefined)\n    return\n  }, [uint8Array, mediaType])\n\n  const base64Src = getImageSrc({ base64, mediaType })\n  const src = base64Src ?? objectUrl\n\n  if (!src) {\n    return (\n      <div\n        aria-label={alt}\n        role=\"img\"\n        className={cn(\n          \"h-auto max-w-full animate-pulse overflow-hidden rounded-md bg-gray-100 dark:bg-neutral-800\",\n          className\n        )}\n        {...props}\n      />\n    )\n  }\n\n  return (\n    <img\n      src={src}\n      alt={alt}\n      className={cn(\"h-auto max-w-full overflow-hidden rounded-md\", className)}\n      role=\"img\"\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "steps",
      "type": "registry:block",
      "title": "Steps",
      "description": "A component for displaying a sequence of operations in a collapsible layout. Each step can include details and an optional vertical bar. Useful for showing AI steps like reasoning traces, tool calls, or process logs.",
      "dependencies": [
        "@radix-ui/react-collapsible@^1.1.10",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/steps.tsx",
          "target": "@components/prompt-kit/steps.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDown } from \"lucide-react\"\n\nexport type StepsItemProps = React.ComponentProps<\"div\">\n\nexport const StepsItem = ({\n  children,\n  className,\n  ...props\n}: StepsItemProps) => (\n  <div className={cn(\"text-muted-foreground text-sm\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type StepsTriggerProps = React.ComponentProps<\n  typeof CollapsibleTrigger\n> & {\n  leftIcon?: React.ReactNode\n  swapIconOnHover?: boolean\n}\n\nexport const StepsTrigger = ({\n  children,\n  className,\n  leftIcon,\n  swapIconOnHover = true,\n  ...props\n}: StepsTriggerProps) => (\n  <CollapsibleTrigger\n    className={cn(\n      \"group text-muted-foreground hover:text-foreground flex w-full cursor-pointer items-center justify-start gap-1 text-sm transition-colors\",\n      className\n    )}\n    {...props}\n  >\n    <div className=\"flex items-center gap-2\">\n      {leftIcon ? (\n        <span className=\"relative inline-flex size-4 items-center justify-center\">\n          <span\n            className={cn(\n              \"transition-opacity\",\n              swapIconOnHover && \"group-hover:opacity-0\"\n            )}\n          >\n            {leftIcon}\n          </span>\n          {swapIconOnHover && (\n            <ChevronDown className=\"absolute size-4 opacity-0 transition-opacity group-hover:opacity-100 group-data-[state=open]:rotate-180\" />\n          )}\n        </span>\n      ) : null}\n      <span>{children}</span>\n    </div>\n    {!leftIcon && (\n      <ChevronDown className=\"size-4 transition-transform group-data-[state=open]:rotate-180\" />\n    )}\n  </CollapsibleTrigger>\n)\n\nexport type StepsContentProps = React.ComponentProps<\n  typeof CollapsibleContent\n> & {\n  bar?: React.ReactNode\n}\n\nexport const StepsContent = ({\n  children,\n  className,\n  bar,\n  ...props\n}: StepsContentProps) => {\n  return (\n    <CollapsibleContent\n      className={cn(\n        \"text-popover-foreground data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down overflow-hidden\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"mt-3 grid max-w-full min-w-0 grid-cols-[min-content_minmax(0,1fr)] items-start gap-x-3\">\n        <div className=\"min-w-0 self-stretch\">{bar ?? <StepsBar />}</div>\n        <div className=\"min-w-0 space-y-2\">{children}</div>\n      </div>\n    </CollapsibleContent>\n  )\n}\n\nexport type StepsBarProps = React.HTMLAttributes<HTMLDivElement>\n\nexport const StepsBar = ({ className, ...props }: StepsBarProps) => (\n  <div\n    className={cn(\"bg-muted h-full w-[2px]\", className)}\n    aria-hidden\n    {...props}\n  />\n)\n\nexport type StepsProps = React.ComponentProps<typeof Collapsible>\n\nexport function Steps({ defaultOpen = true, className, ...props }: StepsProps) {\n  return (\n    <Collapsible\n      className={cn(className)}\n      defaultOpen={defaultOpen}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "components/ui/collapsible.tsx",
          "target": "@components/ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "system-message",
      "type": "registry:block",
      "title": "System Message",
      "description": "A banner-style component for surfacing contextual information, warnings, or instructions within AI interfaces.",
      "dependencies": [
        "@radix-ui/react-slot@^1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/system-message.tsx",
          "target": "@components/prompt-kit/system-message.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { AlertCircle, AlertTriangle, Info } from \"lucide-react\"\nimport React from \"react\"\n\nconst systemMessageVariants = cva(\n  \"flex flex-row items-center gap-3 rounded-[12px] border py-2 pr-2 pl-3\",\n  {\n    variants: {\n      variant: {\n        action: \"text-zinc-700 dark:text-zinc-300\",\n        error: \"text-red-700 dark:text-red-400\",\n        warning: \"text-amber-700 dark:text-amber-400\",\n      },\n      fill: {\n        true: \"bg-background\",\n        false: \"\",\n      },\n    },\n    compoundVariants: [\n      {\n        variant: \"action\",\n        fill: true,\n        class: \"bg-zinc-100 dark:bg-zinc-900 border-transparent\",\n      },\n      {\n        variant: \"error\",\n        fill: true,\n        class: \"bg-red-100 dark:bg-red-900/20 border-transparent\",\n      },\n      {\n        variant: \"warning\",\n        fill: true,\n        class: \"bg-amber-100 dark:bg-amber-900/20 border-transparent\",\n      },\n      {\n        variant: \"action\",\n        fill: false,\n        class: \"border-zinc-200 dark:border-zinc-800\",\n      },\n      {\n        variant: \"error\",\n        fill: false,\n        class: \"border-red-600 dark:border-red-900\",\n      },\n      {\n        variant: \"warning\",\n        fill: false,\n        class: \"border-amber-600 dark:border-amber-900\",\n      },\n    ],\n    defaultVariants: {\n      variant: \"action\",\n      fill: false,\n    },\n  }\n)\n\nexport type SystemMessageProps = React.ComponentProps<\"div\"> &\n  VariantProps<typeof systemMessageVariants> & {\n    icon?: React.ReactNode\n    isIconHidden?: boolean\n    cta?: {\n      label: string\n      onClick?: () => void\n      variant?: \"solid\" | \"outline\" | \"ghost\"\n    }\n  }\n\nexport function SystemMessage({\n  children,\n  variant = \"action\",\n  fill = false,\n  icon,\n  isIconHidden = false,\n  cta,\n  className,\n  ...props\n}: SystemMessageProps) {\n  const getDefaultIcon = () => {\n    if (isIconHidden) return null\n\n    switch (variant) {\n      case \"error\":\n        return <AlertCircle className=\"size-4\" />\n      case \"warning\":\n        return <AlertTriangle className=\"size-4\" />\n      default:\n        return <Info className=\"size-4\" />\n    }\n  }\n\n  const getIconToShow = () => {\n    if (isIconHidden) return null\n    if (icon) return icon\n    return getDefaultIcon()\n  }\n\n  const shouldShowIcon = getIconToShow() !== null\n\n  return (\n    <div\n      className={cn(systemMessageVariants({ variant, fill }), className)}\n      {...props}\n    >\n      <div className=\"flex flex-1 flex-row items-center gap-3 leading-normal\">\n        {shouldShowIcon && (\n          <div className=\"flex h-[1lh] shrink-0 items-center justify-center self-start\">\n            {getIconToShow()}\n          </div>\n        )}\n\n        <div\n          className={cn(\n            \"flex min-w-0 flex-1 items-center\",\n            shouldShowIcon ? \"gap-3\" : \"gap-0\"\n          )}\n        >\n          <div className=\"text-sm\">{children}</div>\n        </div>\n      </div>\n\n      {cta && (\n        <Button variant=\"default\" size=\"sm\" onClick={cta.onClick}>\n          {cta.label}\n        </Button>\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "chain-of-thought",
      "type": "registry:block",
      "title": "Chain Of Thought",
      "description": "A component for displaying a chain of thought process with collapsible steps and triggers.",
      "dependencies": [
        "@radix-ui/react-collapsible@^1.1.10",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/chain-of-thought.tsx",
          "target": "@components/prompt-kit/chain-of-thought.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDown, Circle } from \"lucide-react\"\nimport React from \"react\"\n\nexport type ChainOfThoughtItemProps = React.ComponentProps<\"div\">\n\nexport const ChainOfThoughtItem = ({\n  children,\n  className,\n  ...props\n}: ChainOfThoughtItemProps) => (\n  <div className={cn(\"text-muted-foreground text-sm\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type ChainOfThoughtTriggerProps = React.ComponentProps<\n  typeof CollapsibleTrigger\n> & {\n  leftIcon?: React.ReactNode\n  swapIconOnHover?: boolean\n}\n\nexport const ChainOfThoughtTrigger = ({\n  children,\n  className,\n  leftIcon,\n  swapIconOnHover = true,\n  ...props\n}: ChainOfThoughtTriggerProps) => (\n  <CollapsibleTrigger\n    className={cn(\n      \"group text-muted-foreground hover:text-foreground flex cursor-pointer items-center justify-start gap-1 text-left text-sm transition-colors\",\n      className\n    )}\n    {...props}\n  >\n    <div className=\"flex items-center gap-2\">\n      {leftIcon ? (\n        <span className=\"relative inline-flex size-4 items-center justify-center\">\n          <span\n            className={cn(\n              \"transition-opacity\",\n              swapIconOnHover && \"group-hover:opacity-0\"\n            )}\n          >\n            {leftIcon}\n          </span>\n          {swapIconOnHover && (\n            <ChevronDown className=\"absolute size-4 opacity-0 transition-opacity group-hover:opacity-100 group-data-[state=open]:rotate-180\" />\n          )}\n        </span>\n      ) : (\n        <span className=\"relative inline-flex size-4 items-center justify-center\">\n          <Circle className=\"size-2 fill-current\" />\n        </span>\n      )}\n      <span>{children}</span>\n    </div>\n    {!leftIcon && (\n      <ChevronDown className=\"size-4 transition-transform group-data-[state=open]:rotate-180\" />\n    )}\n  </CollapsibleTrigger>\n)\n\nexport type ChainOfThoughtContentProps = React.ComponentProps<\n  typeof CollapsibleContent\n>\n\nexport const ChainOfThoughtContent = ({\n  children,\n  className,\n  ...props\n}: ChainOfThoughtContentProps) => {\n  return (\n    <CollapsibleContent\n      className={cn(\n        \"text-popover-foreground data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down overflow-hidden\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"grid grid-cols-[min-content_minmax(0,1fr)] gap-x-4\">\n        <div className=\"bg-primary/20 ml-1.75 h-full w-px group-data-[last=true]:hidden\" />\n        <div className=\"ml-1.75 h-full w-px bg-transparent group-data-[last=false]:hidden\" />\n        <div className=\"mt-2 space-y-2\">{children}</div>\n      </div>\n    </CollapsibleContent>\n  )\n}\n\nexport type ChainOfThoughtProps = {\n  children: React.ReactNode\n  className?: string\n}\n\nexport function ChainOfThought({ children, className }: ChainOfThoughtProps) {\n  const childrenArray = React.Children.toArray(children)\n\n  return (\n    <div className={cn(\"space-y-0\", className)}>\n      {childrenArray.map((child, index) => (\n        <React.Fragment key={index}>\n          {React.isValidElement(child) &&\n            React.cloneElement(\n              child as React.ReactElement<ChainOfThoughtStepProps>,\n              {\n                isLast: index === childrenArray.length - 1,\n              }\n            )}\n        </React.Fragment>\n      ))}\n    </div>\n  )\n}\n\nexport type ChainOfThoughtStepProps = {\n  children: React.ReactNode\n  className?: string\n  isLast?: boolean\n}\n\nexport const ChainOfThoughtStep = ({\n  children,\n  className,\n  isLast = false,\n  ...props\n}: ChainOfThoughtStepProps & React.ComponentProps<typeof Collapsible>) => {\n  return (\n    <Collapsible\n      className={cn(\"group\", className)}\n      data-last={isLast}\n      {...props}\n    >\n      {children}\n      <div className=\"flex justify-start group-data-[last=true]:hidden\">\n        <div className=\"bg-primary/20 ml-1.75 h-4 w-px\" />\n      </div>\n    </Collapsible>\n  )\n}\n"
        },
        {
          "path": "components/ui/collapsible.tsx",
          "target": "@components/ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as CollapsiblePrimitive from \"@radix-ui/react-collapsible\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "text-shimmer",
      "type": "registry:block",
      "title": "Text Shimmer",
      "description": "A component for displaying a shimmer effect on text, perfect for loading states or highlighting text.",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "tailwind": {
        "config": {
          "theme": {
            "keyframes": {
              "shimmer": {
                "0%": {
                  "backgroundPosition": "200% 50%"
                },
                "100%": {
                  "backgroundPosition": "-200% 50%"
                }
              }
            }
          }
        }
      },
      "files": [
        {
          "path": "components/prompt-kit/text-shimmer.tsx",
          "target": "@components/prompt-kit/text-shimmer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport type TextShimmerProps = {\n  as?: string\n  duration?: number\n  spread?: number\n  children: React.ReactNode\n} & React.HTMLAttributes<HTMLElement>\n\nexport function TextShimmer({\n  as = \"span\",\n  className,\n  duration = 4,\n  spread = 20,\n  children,\n  ...props\n}: TextShimmerProps) {\n  const dynamicSpread = Math.min(Math.max(spread, 5), 45)\n  const Component = as as React.ElementType\n\n  return (\n    <Component\n      className={cn(\n        \"bg-size-[200%_auto] bg-clip-text font-medium text-transparent\",\n        \"animate-[shimmer_4s_infinite_linear]\",\n        className\n      )}\n      style={{\n        backgroundImage: `linear-gradient(to right, var(--muted-foreground) ${50 - dynamicSpread}%, var(--foreground) 50%, var(--muted-foreground) ${50 + dynamicSpread}%)`,\n        animationDuration: `${duration}s`,\n      }}\n      {...props}\n    >\n      {children}\n    </Component>\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "thinking-bar",
      "type": "registry:block",
      "title": "Thinking Bar",
      "description": "A component to display the thinking state of an AI model with optional actions.",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/thinking-bar.tsx",
          "target": "@components/prompt-kit/thinking-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { TextShimmer } from \"@/components/prompt-kit/text-shimmer\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronRight } from \"lucide-react\"\n\ntype ThinkingBarProps = {\n  className?: string\n  text?: string\n  onStop?: () => void\n  stopLabel?: string\n  onClick?: () => void\n}\n\nexport function ThinkingBar({\n  className,\n  text = \"Thinking\",\n  onStop,\n  stopLabel = \"Answer now\",\n  onClick,\n}: ThinkingBarProps) {\n  return (\n    <div className={cn(\"flex w-full items-center justify-between\", className)}>\n      {onClick ? (\n        <button\n          type=\"button\"\n          onClick={onClick}\n          className=\"flex items-center gap-1 text-sm transition-opacity hover:opacity-80\"\n        >\n          <TextShimmer className=\"font-medium\">{text}</TextShimmer>\n          <ChevronRight className=\"text-muted-foreground size-4\" />\n        </button>\n      ) : (\n        <TextShimmer className=\"cursor-default font-medium\">{text}</TextShimmer>\n      )}\n      {onStop ? (\n        <button\n          onClick={onStop}\n          type=\"button\"\n          className=\"text-muted-foreground hover:text-foreground border-muted-foreground/50 hover:border-foreground border-b border-dotted text-sm transition-colors\"\n        >\n          {stopLabel}\n        </button>\n      ) : null}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/prompt-kit/text-shimmer.tsx",
          "target": "@components/prompt-kit/text-shimmer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport type TextShimmerProps = {\n  as?: string\n  duration?: number\n  spread?: number\n  children: React.ReactNode\n} & React.HTMLAttributes<HTMLElement>\n\nexport function TextShimmer({\n  as = \"span\",\n  className,\n  duration = 4,\n  spread = 20,\n  children,\n  ...props\n}: TextShimmerProps) {\n  const dynamicSpread = Math.min(Math.max(spread, 5), 45)\n  const Component = as as React.ElementType\n\n  return (\n    <Component\n      className={cn(\n        \"bg-size-[200%_auto] bg-clip-text font-medium text-transparent\",\n        \"animate-[shimmer_4s_infinite_linear]\",\n        className\n      )}\n      style={{\n        backgroundImage: `linear-gradient(to right, var(--muted-foreground) ${50 - dynamicSpread}%, var(--foreground) 50%, var(--muted-foreground) ${50 + dynamicSpread}%)`,\n        animationDuration: `${duration}s`,\n      }}\n      {...props}\n    >\n      {children}\n    </Component>\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "feedback-bar",
      "type": "registry:block",
      "title": "Feedback Bar",
      "description": "A component to collect user feedback on AI responses.",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/prompt-kit/feedback-bar.tsx",
          "target": "@components/prompt-kit/feedback-bar.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { ThumbsDown, ThumbsUp, X } from \"lucide-react\"\n\ntype FeedbackBarProps = {\n  className?: string\n  title?: string\n  icon?: React.ReactNode\n  onHelpful?: () => void\n  onNotHelpful?: () => void\n  onClose?: () => void\n}\n\nexport function FeedbackBar({\n  className,\n  title,\n  icon,\n  onHelpful,\n  onNotHelpful,\n  onClose,\n}: FeedbackBarProps) {\n  return (\n    <div\n      className={cn(\n        \"bg-background border-border inline-flex rounded-[12px] border text-sm\",\n        className\n      )}\n    >\n      <div className=\"flex w-full items-center justify-between\">\n        <div className=\"flex flex-1 items-center justify-start gap-4 py-3 pl-4\">\n          {icon}\n          <span className=\"text-foreground font-medium\">{title}</span>\n        </div>\n        <div className=\"flex items-center justify-center gap-0.5 px-3 py-0\">\n          <button\n            type=\"button\"\n            className=\"text-muted-foreground hover:text-foreground flex size-8 items-center justify-center rounded-md transition-colors\"\n            aria-label=\"Helpful\"\n            onClick={onHelpful}\n          >\n            <ThumbsUp className=\"size-4\" />\n          </button>\n          <button\n            type=\"button\"\n            className=\"text-muted-foreground hover:text-foreground flex size-8 items-center justify-center rounded-md transition-colors\"\n            aria-label=\"Not helpful\"\n            onClick={onNotHelpful}\n          >\n            <ThumbsDown className=\"size-4\" />\n          </button>\n        </div>\n        <div className=\"border-border flex items-center justify-center border-l\">\n          <button\n            type=\"button\"\n            onClick={onClose}\n            className=\"text-muted-foreground hover:text-foreground flex items-center justify-center rounded-md p-3\"\n            aria-label=\"Close\"\n          >\n            <X className=\"size-5\" />\n          </button>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Prompt Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-analytics-pulse",
      "type": "registry:block",
      "title": "Agent Analytics Pulse",
      "description": "agent analytics pulse",
      "dependencies": [
        "clsx@^2.1.1",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-analytics-pulse.tsx",
          "target": "@components/agents-ui/agent-analytics-pulse.tsx",
          "type": "registry:component",
          "content": "export interface PulseMetric {\n  label: string\n  value: string\n  change: string\n  positive?: boolean\n}\n\nexport interface AttributionSlice {\n  channel: string\n  value: number\n  color?: string\n}\n\nexport interface InsightHighlight {\n  id: string\n  title: string\n  detail: string\n  impact: \"high\" | \"medium\" | \"low\"\n}\n\nexport interface AgentAnalyticsPulseProps {\n  title?: string\n  timeframe?: string\n  metrics?: PulseMetric[]\n  trendSeries?: number[]\n  attribution?: AttributionSlice[]\n  highlights?: InsightHighlight[]\n  segmentFilter?: string\n  onSegmentChange?: (segment: string) => void\n  onDrilldown?: () => void\n  className?: string\n}\n\nexport { AgentAnalyticsPulse } from \"./application/analytics-pulse/agent-analytics-pulse\"\n"
        },
        {
          "path": "components/agents-ui/application/analytics-pulse/agent-analytics-pulse.tsx",
          "target": "@components/agents-ui/application/analytics-pulse/agent-analytics-pulse.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Tab, TabList, Tabs } from \"@/components/boardui/base/tabs/tabs\"\nimport { cn } from \"@/lib/utils\"\nimport { useEffect, useState } from \"react\"\nimport type { AgentAnalyticsPulseProps } from \"../../agent-analytics-pulse\"\n\nconst metricsDefault = [\n  { label: \"Active users\", value: \"148k\", change: \"+5.1%\", positive: true },\n  { label: \"Activation rate\", value: \"42.7%\", change: \"+3.4%\", positive: true },\n  { label: \"Churn\", value: \"3.2%\", change: \"-0.6%\", positive: true },\n]\nconst attributionDefault = [\n  { channel: \"Agents\", value: 38 },\n  { channel: \"Lifecycle\", value: 24 },\n  { channel: \"Paid\", value: 18 },\n  { channel: \"Organic\", value: 14 },\n  { channel: \"Other\", value: 6 },\n]\nconst highlightsDefault = [\n  {\n    id: \"agents\",\n    title: \"Agents drive 38% of new ARR\",\n    detail: \"Upsell workflows closed 61 deals with an 82% win rate.\",\n    impact: \"high\" as const,\n  },\n  {\n    id: \"activation\",\n    title: \"Activation improved\",\n    detail: \"Workflow adoption increased activation in the Growth segment.\",\n    impact: \"medium\" as const,\n  },\n]\n\nexport function AgentAnalyticsPulse({\n  title = \"Growth analytics\",\n  timeframe = \"Last 30 days\",\n  metrics = metricsDefault,\n  trendSeries = [62, 64, 66, 70, 74, 78, 81],\n  attribution = attributionDefault,\n  highlights = highlightsDefault,\n  segmentFilter = \"All\",\n  onSegmentChange,\n  onDrilldown,\n  className,\n}: AgentAnalyticsPulseProps) {\n  const [segment, setSegment] = useState(segmentFilter)\n  useEffect(() => setSegment(segmentFilter), [segmentFilter])\n  const values = trendSeries.filter(Number.isFinite)\n  const min = Math.min(...values),\n    max = Math.max(...values)\n  const points = values\n    .map(\n      (value, index) =>\n        `${24 + (index / Math.max(1, values.length - 1)) * 552},${160 - ((value - min) / (max - min || 1)) * 136}`\n    )\n    .join(\" \")\n  const total = attribution.reduce((sum, item) => sum + item.value, 0) || 1\n  return (\n    <section\n      aria-label={title}\n      className={cn(\n        \"agent-widget border-separator-border bg-background-primary-default text-text-primary w-full min-w-0 space-y-5 rounded-xl border p-5\",\n        className\n      )}\n    >\n      <header className=\"flex flex-wrap items-start justify-between gap-4\">\n        <div>\n          <p className=\"text-text-secondary text-xs\">{timeframe}</p>\n          <h2 className=\"mt-1 text-lg font-semibold\">{title}</h2>\n        </div>\n        <Tabs\n          selectedKey={segment}\n          onSelectionChange={(key) => {\n            setSegment(String(key))\n            onSegmentChange?.(String(key))\n          }}\n        >\n          <TabList\n            aria-label=\"Audience segment\"\n            className=\"max-w-full overflow-x-auto\"\n          >\n            {[\"All\", \"Enterprise\", \"Growth\", \"Self-serve\"].map((label) => (\n              <Tab key={label} id={label}>\n                {label}\n              </Tab>\n            ))}\n          </TabList>\n        </Tabs>\n      </header>\n      <dl className=\"border-separator-border grid gap-4 border-y py-4 sm:grid-cols-3\">\n        {metrics.map((metric) => (\n          <div key={metric.label}>\n            <dt className=\"text-text-secondary text-xs\">{metric.label}</dt>\n            <dd className=\"mt-1 flex items-baseline gap-2\">\n              <span className=\"text-xl font-semibold tabular-nums\">\n                {metric.value}\n              </span>\n              <span\n                className={cn(\n                  \"text-xs tabular-nums\",\n                  metric.positive === false\n                    ? \"text-red-600 dark:text-red-400\"\n                    : \"text-green-700 dark:text-green-400\"\n                )}\n              >\n                {metric.change}\n              </span>\n            </dd>\n          </div>\n        ))}\n      </dl>\n      <div className=\"grid min-w-0 gap-6 lg:grid-cols-[minmax(0,1.6fr)_minmax(0,1fr)]\">\n        <div className=\"min-w-0\">\n          <div className=\"flex flex-wrap items-center justify-between gap-3\">\n            <h3 className=\"text-sm font-medium\">Engagement trend</h3>\n            {onDrilldown && (\n              <Button variant=\"secondary\" size=\"small\" onClick={onDrilldown}>\n                Open drilldown\n              </Button>\n            )}\n          </div>\n          {values.length ? (\n            <svg\n              role=\"img\"\n              aria-label={`Engagement values: ${values.join(\", \")}`}\n              viewBox=\"0 0 600 184\"\n              className=\"text-text-primary my-3 w-full\"\n            >\n              <path\n                d=\"M24 160 H576\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                opacity=\".12\"\n              />\n              <polyline\n                points={points}\n                fill=\"none\"\n                stroke=\"currentColor\"\n                strokeWidth=\"2\"\n                strokeLinejoin=\"round\"\n                strokeLinecap=\"round\"\n              />\n              {values.map((value, index) => (\n                <circle\n                  key={index}\n                  cx={24 + (index / Math.max(1, values.length - 1)) * 552}\n                  cy={160 - ((value - min) / (max - min || 1)) * 136}\n                  r=\"3\"\n                  fill=\"currentColor\"\n                />\n              ))}\n            </svg>\n          ) : (\n            <p className=\"text-text-secondary py-8 text-sm\">\n              No trend data available.\n            </p>\n          )}\n          <details className=\"text-text-secondary text-xs\">\n            <summary className=\"focus-visible:outline-border-focus-ring cursor-pointer rounded py-2 focus-visible:outline-2\">\n              View {values.length} data points\n            </summary>\n            <ol className=\"mt-2 grid grid-cols-2 gap-2 tabular-nums\">\n              {values.map((value, i) => (\n                <li key={i}>\n                  Point {i + 1}: {value}\n                </li>\n              ))}\n            </ol>\n          </details>\n        </div>\n        <div className=\"min-w-0\">\n          <h3 className=\"mb-3 text-sm font-medium\">Attribution</h3>\n          <ul className=\"space-y-3\">\n            {attribution.map((item) => (\n              <li key={item.channel}>\n                <div className=\"flex justify-between gap-3 text-xs\">\n                  <span>{item.channel}</span>\n                  <span className=\"text-text-secondary tabular-nums\">\n                    {Math.round((item.value / total) * 100)}%\n                  </span>\n                </div>\n                <div className=\"bg-background-secondary-default mt-1.5 h-1.5 overflow-hidden rounded-full\">\n                  <div\n                    className=\"bg-text-secondary h-full rounded-full\"\n                    style={{\n                      width: `${Math.max(0, Math.min(100, (item.value / total) * 100))}%`,\n                      backgroundColor: item.color,\n                    }}\n                  />\n                </div>\n              </li>\n            ))}\n          </ul>\n        </div>\n      </div>\n      {highlights.length > 0 && (\n        <section className=\"border-separator-border border-t pt-4\">\n          <h3 className=\"text-sm font-medium\">Highlights</h3>\n          <ul className=\"divide-separator-border mt-2 divide-y\">\n            {highlights.map((item) => (\n              <li key={item.id} className=\"py-3\">\n                <div className=\"flex flex-wrap justify-between gap-2\">\n                  <h4 className=\"text-sm font-medium\">{item.title}</h4>\n                  <span className=\"text-text-secondary text-xs\">\n                    {item.impact} impact\n                  </span>\n                </div>\n                <p className=\"text-text-secondary mt-1 text-sm leading-6\">\n                  {item.detail}\n                </p>\n              </li>\n            ))}\n          </ul>\n        </section>\n      )}\n      <footer className=\"border-separator-border text-text-secondary border-t pt-3 text-xs\">\n        {segment} segment · {timeframe}\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/tabs/tabs.tsx",
          "target": "@components/boardui/base/tabs/tabs.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type { ComponentType, ReactNode, Ref } from \"react\";\nimport {\n  Tab as AriaTab,\n  TabList as AriaTabList,\n  TabPanel as AriaTabPanel,\n  Tabs as AriaTabs,\n} from \"react-aria-components\";\nimport type {\n  TabListProps as AriaTabListProps,\n  TabPanelProps as AriaTabPanelProps,\n  TabProps as AriaTabProps,\n  TabsProps as AriaTabsProps,\n} from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Figma source: Board UI → Tab (node 3793:2942).\n *\n * Underline tabs. The tab strip sits on a 1px border/button/default baseline;\n * the active tab paints a 2px foreground underline over it.\n *   tab       px 10, py 8, gap 10 (label ↔ count), Body 1 (14/20)\n *     active     text/primary, Medium weight, 2px foreground underline\n *     inactive   text/primary, Regular weight, transparent underline\n *   count     radius/sm, px 4, py 1, Caption 1/Medium (12/16)\n *     active     selected count background, text/primary\n *     inactive   bg black/10 @ 50% opacity, text/primary\n *   icon      optional 16px leading glyph, inherits the label color\n *\n * Built on react-aria Tabs: roving-tabindex arrow-key navigation, automatic\n * activation, and TabList/TabPanel association.\n */\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\nexport interface TabsProps extends AriaTabsProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tabs({ className, ref, ...props }: TabsProps) {\n  return (\n    <AriaTabs\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"flex w-full flex-col gap-4\",\n          state.orientation === \"vertical\" && \"flex-row\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n\nexport interface TabListProps<T extends object> extends AriaTabListProps<T> {\n  ref?: Ref<HTMLDivElement>;\n}\n\ntype Underline = { left: number; width: number };\n\nexport function TabList<T extends object>({ className, ref, ...props }: TabListProps<T>) {\n  const wrapperRef = useRef<HTMLDivElement>(null);\n  const [underline, setUnderline] = useState<Underline | null>(null);\n\n  useIsomorphicLayoutEffect(() => {\n    const el = wrapperRef.current;\n    if (!el) return;\n    const measure = () => {\n      const selected = el.querySelector<HTMLElement>(\"[role='tab'][data-selected]\");\n      if (selected) {\n        setUnderline({ left: selected.offsetLeft, width: selected.offsetWidth });\n      }\n    };\n    measure();\n    // Re-measure when selection flips (data-selected toggles) or size changes.\n    const mo = new MutationObserver(measure);\n    mo.observe(el, { attributes: true, subtree: true, attributeFilter: [\"data-selected\"] });\n    const ro = new ResizeObserver(measure);\n    ro.observe(el);\n    return () => {\n      mo.disconnect();\n      ro.disconnect();\n    };\n  }, []);\n\n  return (\n    <div ref={wrapperRef} className=\"relative w-full\">\n      <AriaTabList\n        ref={ref}\n        {...props}\n        className={(state) =>\n          cx(\n            \"flex w-full items-center gap-1 border-b border-separator-border\",\n            typeof className === \"function\" ? className(state) : className,\n          )\n        }\n      />\n      {underline && (\n        <span\n          aria-hidden\n          className=\"pointer-events-none absolute bottom-0 left-0 h-0.5 bg-text-primary transition-[transform,width] duration-200 ease\"\n          style={{\n            transform: `translateX(${underline.left}px)`,\n            width: underline.width,\n          }}\n        />\n      )}\n    </div>\n  );\n}\n\nexport interface TabProps extends Omit<AriaTabProps, \"children\"> {\n  children?: ReactNode;\n  /** Optional leading icon (16px). Inherits the label color. */\n  icon?: IconComponent;\n  /** Optional trailing count badge. */\n  count?: ReactNode;\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tab({ className, children, icon: Icon, count, ref, ...props }: TabProps) {\n  return (\n    <AriaTab\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"relative inline-flex cursor-pointer items-center gap-2.5 px-2.5 py-2 whitespace-nowrap\",\n          \"outline-none transition-colors duration-150 ease\",\n          \"focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          state.isDisabled && \"cursor-not-allowed opacity-50\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    >\n      {({ isSelected }) => (\n        <>\n          <span\n            className={cx(\n              \"inline-flex items-center gap-1.5\",\n              isSelected\n                ? \"text-body-medium text-text-primary\"\n                : \"text-body-regular text-text-primary\",\n            )}\n          >\n            {Icon && <Icon className=\"size-4 shrink-0\" aria-hidden />}\n            {children}\n          </span>\n          {count != null && (\n            <span\n              className={cx(\n                \"inline-flex items-center justify-center rounded-sm px-1 py-px text-caption-1-medium whitespace-nowrap\",\n                isSelected\n                  ? \"bg-tab-count-selected-background text-text-primary\"\n                  : \"bg-black/10 text-text-primary opacity-50\",\n              )}\n            >\n              {count}\n            </span>\n          )}\n        </>\n      )}\n    </AriaTab>\n  );\n}\n\nexport interface TabPanelProps extends AriaTabPanelProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function TabPanel({ className, ref, ...props }: TabPanelProps) {\n  return (\n    <AriaTabPanel\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"outline-none focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-artifact",
      "type": "registry:block",
      "title": "Agent Artifact",
      "description": "agent artifact",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-artifact.tsx",
          "target": "@components/agents-ui/agent-artifact.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { ArtifactOutput } from \"@/components/agents-ui/application/artifact-output/artifact-output\"\n\nexport type ArtifactType = \"code\" | \"table\" | \"document\" | \"chart\"\nexport interface ArtifactVersion {\n  id: string\n  label: string\n  timestamp: string\n  content: string\n}\nexport interface ArtifactMetadata {\n  generationTime?: string\n  model?: string\n  tokens?: number\n  size?: string\n}\nexport interface AgentArtifactProps {\n  title?: string\n  artifactType?: ArtifactType\n  content?: string\n  language?: string\n  versions?: ArtifactVersion[]\n  currentVersion?: string\n  isGenerating?: boolean\n  metadata?: ArtifactMetadata\n  className?: string\n  onCopy?: () => void\n  onDownload?: () => void\n  onEdit?: () => void\n  onRegenerate?: () => void\n  onShare?: () => void\n  onVersionChange?: (versionId: string) => void\n}\nexport function AgentArtifact(props: AgentArtifactProps) {\n  return <ArtifactOutput {...props} />\n}\n"
        },
        {
          "path": "components/agents-ui/application/artifact-output/artifact-output.tsx",
          "target": "@components/agents-ui/application/artifact-output/artifact-output.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type {\n  AgentArtifactProps,\n  ArtifactType,\n  ArtifactVersion,\n} from \"@/components/agents-ui/agent-artifact\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport {\n  Tab,\n  TabList,\n  TabPanel,\n  Tabs,\n} from \"@/components/boardui/base/tabs/tabs\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  BarChart3,\n  Code2,\n  Copy,\n  Download,\n  FileText,\n  History,\n  MoreHorizontal,\n  Pencil,\n  Share2,\n  Table2,\n} from \"lucide-react\"\nimport * as React from \"react\"\n\nconst defaultVersions: ArtifactVersion[] = [\n  {\n    id: \"v1\",\n    label: \"Version 1\",\n    timestamp: \"10:02\",\n    content: \"Region,Revenue,Deals\\nNorth America,$1.24M,86\\nEurope,$980K,72\",\n  },\n  {\n    id: \"v2\",\n    label: \"Version 2\",\n    timestamp: \"10:14\",\n    content:\n      \"Region,Revenue,Deals,QoQ Growth\\nNorth America,$1.24M,86,+12%\\nEurope,$980K,72,+8%\\nAPAC,$640K,54,+18%\",\n  },\n]\nconst typeInfo: Record<ArtifactType, { label: string; icon: typeof FileText }> =\n  {\n    code: { label: \"Code\", icon: Code2 },\n    table: { label: \"Table\", icon: Table2 },\n    document: { label: \"Document\", icon: FileText },\n    chart: { label: \"Chart\", icon: BarChart3 },\n  }\n\nfunction TablePreview({ content }: { content: string }) {\n  const lines = content.trim().split(\"\\n\").filter(Boolean)\n  return (\n    <div className=\"border-separator-border overflow-auto rounded-lg border\">\n      <table className=\"w-full min-w-[560px] text-left text-sm\">\n        <thead className=\"bg-background-secondary-default text-text-secondary text-xs\">\n          <tr>\n            <th className=\"w-10 px-3 py-2.5 font-medium\">#</th>\n            {lines[0]?.split(\",\").map((cell) => (\n              <th key={cell} className=\"px-3 py-2.5 font-medium\">\n                {cell.trim()}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>\n          {lines.slice(1).map((line, rowIndex) => (\n            <tr key={rowIndex} className=\"border-separator-border border-t\">\n              <td className=\"text-text-secondary px-3 py-3 text-xs\">\n                {rowIndex + 1}\n              </td>\n              {line.split(\",\").map((cell, cellIndex) => (\n                <td key={cellIndex} className=\"text-text-primary px-3 py-3\">\n                  {cell.trim()}\n                </td>\n              ))}\n            </tr>\n          ))}\n        </tbody>\n      </table>\n    </div>\n  )\n}\nfunction DocumentPreview({ content }: { content: string }) {\n  return (\n    <div className=\"max-w-3xl space-y-2 text-sm leading-7\">\n      {content.split(\"\\n\").map((line, index) =>\n        line.startsWith(\"# \") ? (\n          <h2 key={index} className=\"pt-2 text-xl font-semibold\">\n            {line.slice(2)}\n          </h2>\n        ) : line.startsWith(\"## \") ? (\n          <h3 key={index} className=\"pt-3 text-base font-semibold\">\n            {line.slice(3)}\n          </h3>\n        ) : line.startsWith(\"- \") ? (\n          <p key={index} className=\"pl-4 before:mr-2 before:content-['•']\">\n            {line.slice(2)}\n          </p>\n        ) : line ? (\n          <p key={index}>{line}</p>\n        ) : (\n          <div key={index} className=\"h-2\" />\n        )\n      )}\n    </div>\n  )\n}\nfunction Preview({\n  type,\n  content,\n  language,\n}: {\n  type: ArtifactType\n  content: string\n  language: string\n}) {\n  if (!content)\n    return (\n      <p className=\"text-text-secondary py-12 text-center text-sm\">\n        No artifact content yet.\n      </p>\n    )\n  if (type === \"table\") return <TablePreview content={content} />\n  if (type === \"code\")\n    return (\n      <pre className=\"bg-background-secondary-default max-h-[440px] overflow-auto rounded-lg p-4 font-mono text-xs leading-6\">\n        <code data-language={language}>{content}</code>\n      </pre>\n    )\n  if (type === \"chart\")\n    return (\n      <div className=\"border-separator-border rounded-lg border p-4\">\n        <div className=\"text-text-secondary mb-3 flex items-center gap-2 text-xs\">\n          <BarChart3 className=\"size-4\" />\n          Chart data\n        </div>\n        <pre className=\"overflow-auto font-mono text-xs leading-6 whitespace-pre-wrap\">\n          {content}\n        </pre>\n      </div>\n    )\n  return <DocumentPreview content={content} />\n}\n\nexport function ArtifactOutput({\n  title = \"Generated artifact\",\n  artifactType = \"table\",\n  content,\n  language = \"text\",\n  versions = defaultVersions,\n  currentVersion = \"v2\",\n  isGenerating = false,\n  metadata = {},\n  onCopy,\n  onDownload,\n  onEdit,\n  onRegenerate,\n  onShare,\n  onVersionChange,\n  className,\n}: AgentArtifactProps) {\n  const [versionId, setVersionId] = React.useState(currentVersion)\n  const [historyOpen, setHistoryOpen] = React.useState(false)\n  React.useEffect(() => {\n    setVersionId(currentVersion)\n  }, [currentVersion])\n  React.useEffect(() => {\n    if (\n      !versions.some((version) => version.id === versionId) &&\n      versions.length\n    )\n      setVersionId(versions.at(-1)!.id)\n  }, [versions, versionId])\n  const selectedVersion =\n    versions.find((version) => version.id === versionId) ?? versions.at(-1)\n  const resolvedContent =\n    content !== undefined ? content : (selectedVersion?.content ?? \"\")\n  const TypeIcon = typeInfo[artifactType].icon\n  const chooseVersion = (id: string) => {\n    setVersionId(id)\n    onVersionChange?.(id)\n  }\n  const rawLabel = artifactType === \"code\" ? \"Code\" : \"Raw\"\n\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-3 border-b p-4\">\n        <div className=\"flex min-w-0 gap-3\">\n          <TypeIcon className=\"text-text-secondary mt-0.5 size-5 shrink-0\" />\n          <div className=\"min-w-0\">\n            <h2 className=\"truncate text-lg font-semibold\">{title}</h2>\n            <p className=\"text-text-secondary mt-1 text-xs\">\n              {typeInfo[artifactType].label}\n              {selectedVersion\n                ? ` · ${selectedVersion.label} · ${selectedVersion.timestamp}`\n                : \" · Unversioned\"}\n            </p>\n          </div>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={Share2}\n            onClick={onShare}\n          >\n            Share\n          </Button>\n          <Button\n            variant=\"secondary\"\n            size=\"small\"\n            leadingIcon={Download}\n            onClick={onDownload}\n          >\n            Download\n          </Button>\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            iconOnly\n            aria-label=\"Regenerate artifact\"\n            onClick={onRegenerate}\n          >\n            <MoreHorizontal />\n          </Button>\n        </div>\n      </header>\n      {isGenerating && (\n        <div className=\"border-separator-border text-text-secondary border-b px-4 py-2 text-xs\">\n          Generating new version\n        </div>\n      )}\n      <div\n        className={cx(\n          \"grid\",\n          historyOpen && \"lg:grid-cols-[minmax(0,1fr)_220px]\"\n        )}\n      >\n        <Tabs defaultSelectedKey=\"preview\" className=\"min-w-0\">\n          <TabList className=\"px-4\">\n            <Tab id=\"preview\">Preview</Tab>\n            <Tab id=\"code\">{rawLabel}</Tab>\n            <Tab id=\"details\">Details</Tab>\n          </TabList>\n          <TabPanel id=\"preview\" className=\"p-5\">\n            <Preview\n              type={artifactType}\n              content={resolvedContent}\n              language={language}\n            />\n          </TabPanel>\n          <TabPanel id=\"code\" className=\"p-5\">\n            <pre className=\"bg-background-secondary-default max-h-[440px] overflow-auto rounded-lg p-4 font-mono text-xs leading-6 whitespace-pre-wrap\">\n              {resolvedContent || \"No artifact content yet.\"}\n            </pre>\n          </TabPanel>\n          <TabPanel id=\"details\" className=\"p-5\">\n            <dl className=\"grid grid-cols-[120px_1fr] gap-x-4 gap-y-3 text-sm\">\n              <dt className=\"text-text-secondary\">Type</dt>\n              <dd>{typeInfo[artifactType].label}</dd>\n              <dt className=\"text-text-secondary\">Language</dt>\n              <dd>{language}</dd>\n              {metadata.model && (\n                <>\n                  <dt className=\"text-text-secondary\">Generated by</dt>\n                  <dd>{metadata.model}</dd>\n                </>\n              )}\n              {metadata.generationTime && (\n                <>\n                  <dt className=\"text-text-secondary\">Generation time</dt>\n                  <dd>{metadata.generationTime}</dd>\n                </>\n              )}\n              {metadata.tokens !== undefined && (\n                <>\n                  <dt className=\"text-text-secondary\">Tokens</dt>\n                  <dd>{metadata.tokens.toLocaleString()}</dd>\n                </>\n              )}\n              {metadata.size && (\n                <>\n                  <dt className=\"text-text-secondary\">Size</dt>\n                  <dd>{metadata.size}</dd>\n                </>\n              )}\n            </dl>\n          </TabPanel>\n        </Tabs>\n        {historyOpen && (\n          <aside className=\"border-separator-border border-t p-4 lg:border-t-0 lg:border-l\">\n            <h3 className=\"text-sm font-medium\">Version history</h3>\n            <div className=\"divide-separator-border border-separator-border mt-3 divide-y border-y\">\n              {versions.map((version) => (\n                <button\n                  key={version.id}\n                  onClick={() => chooseVersion(version.id)}\n                  className={cx(\n                    \"flex min-h-12 w-full items-center justify-between gap-3 px-2 text-left text-sm\",\n                    version.id === versionId &&\n                      \"bg-background-secondary-default\"\n                  )}\n                >\n                  <span>{version.label}</span>\n                  <span className=\"text-text-secondary text-xs\">\n                    {version.timestamp}\n                  </span>\n                </button>\n              ))}\n            </div>\n          </aside>\n        )}\n      </div>\n      <footer className=\"border-separator-border flex flex-wrap items-center justify-between gap-3 border-t p-4\">\n        <div className=\"flex gap-1\">\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={Copy}\n            onClick={onCopy}\n          >\n            Copy\n          </Button>\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={Pencil}\n            onClick={onEdit}\n          >\n            Edit\n          </Button>\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={History}\n            onClick={() => setHistoryOpen((open) => !open)}\n          >\n            Versions\n          </Button>\n        </div>\n        <span className=\"text-text-secondary text-xs\">\n          {metadata.size ?? typeInfo[artifactType].label}\n          {metadata.model ? ` · ${metadata.model}` : \"\"}\n          {metadata.generationTime ? ` · ${metadata.generationTime}` : \"\"}\n        </span>\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/tabs/tabs.tsx",
          "target": "@components/boardui/base/tabs/tabs.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type { ComponentType, ReactNode, Ref } from \"react\";\nimport {\n  Tab as AriaTab,\n  TabList as AriaTabList,\n  TabPanel as AriaTabPanel,\n  Tabs as AriaTabs,\n} from \"react-aria-components\";\nimport type {\n  TabListProps as AriaTabListProps,\n  TabPanelProps as AriaTabPanelProps,\n  TabProps as AriaTabProps,\n  TabsProps as AriaTabsProps,\n} from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Figma source: Board UI → Tab (node 3793:2942).\n *\n * Underline tabs. The tab strip sits on a 1px border/button/default baseline;\n * the active tab paints a 2px foreground underline over it.\n *   tab       px 10, py 8, gap 10 (label ↔ count), Body 1 (14/20)\n *     active     text/primary, Medium weight, 2px foreground underline\n *     inactive   text/primary, Regular weight, transparent underline\n *   count     radius/sm, px 4, py 1, Caption 1/Medium (12/16)\n *     active     selected count background, text/primary\n *     inactive   bg black/10 @ 50% opacity, text/primary\n *   icon      optional 16px leading glyph, inherits the label color\n *\n * Built on react-aria Tabs: roving-tabindex arrow-key navigation, automatic\n * activation, and TabList/TabPanel association.\n */\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\nexport interface TabsProps extends AriaTabsProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tabs({ className, ref, ...props }: TabsProps) {\n  return (\n    <AriaTabs\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"flex w-full flex-col gap-4\",\n          state.orientation === \"vertical\" && \"flex-row\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n\nexport interface TabListProps<T extends object> extends AriaTabListProps<T> {\n  ref?: Ref<HTMLDivElement>;\n}\n\ntype Underline = { left: number; width: number };\n\nexport function TabList<T extends object>({ className, ref, ...props }: TabListProps<T>) {\n  const wrapperRef = useRef<HTMLDivElement>(null);\n  const [underline, setUnderline] = useState<Underline | null>(null);\n\n  useIsomorphicLayoutEffect(() => {\n    const el = wrapperRef.current;\n    if (!el) return;\n    const measure = () => {\n      const selected = el.querySelector<HTMLElement>(\"[role='tab'][data-selected]\");\n      if (selected) {\n        setUnderline({ left: selected.offsetLeft, width: selected.offsetWidth });\n      }\n    };\n    measure();\n    // Re-measure when selection flips (data-selected toggles) or size changes.\n    const mo = new MutationObserver(measure);\n    mo.observe(el, { attributes: true, subtree: true, attributeFilter: [\"data-selected\"] });\n    const ro = new ResizeObserver(measure);\n    ro.observe(el);\n    return () => {\n      mo.disconnect();\n      ro.disconnect();\n    };\n  }, []);\n\n  return (\n    <div ref={wrapperRef} className=\"relative w-full\">\n      <AriaTabList\n        ref={ref}\n        {...props}\n        className={(state) =>\n          cx(\n            \"flex w-full items-center gap-1 border-b border-separator-border\",\n            typeof className === \"function\" ? className(state) : className,\n          )\n        }\n      />\n      {underline && (\n        <span\n          aria-hidden\n          className=\"pointer-events-none absolute bottom-0 left-0 h-0.5 bg-text-primary transition-[transform,width] duration-200 ease\"\n          style={{\n            transform: `translateX(${underline.left}px)`,\n            width: underline.width,\n          }}\n        />\n      )}\n    </div>\n  );\n}\n\nexport interface TabProps extends Omit<AriaTabProps, \"children\"> {\n  children?: ReactNode;\n  /** Optional leading icon (16px). Inherits the label color. */\n  icon?: IconComponent;\n  /** Optional trailing count badge. */\n  count?: ReactNode;\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tab({ className, children, icon: Icon, count, ref, ...props }: TabProps) {\n  return (\n    <AriaTab\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"relative inline-flex cursor-pointer items-center gap-2.5 px-2.5 py-2 whitespace-nowrap\",\n          \"outline-none transition-colors duration-150 ease\",\n          \"focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          state.isDisabled && \"cursor-not-allowed opacity-50\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    >\n      {({ isSelected }) => (\n        <>\n          <span\n            className={cx(\n              \"inline-flex items-center gap-1.5\",\n              isSelected\n                ? \"text-body-medium text-text-primary\"\n                : \"text-body-regular text-text-primary\",\n            )}\n          >\n            {Icon && <Icon className=\"size-4 shrink-0\" aria-hidden />}\n            {children}\n          </span>\n          {count != null && (\n            <span\n              className={cx(\n                \"inline-flex items-center justify-center rounded-sm px-1 py-px text-caption-1-medium whitespace-nowrap\",\n                isSelected\n                  ? \"bg-tab-count-selected-background text-text-primary\"\n                  : \"bg-black/10 text-text-primary opacity-50\",\n              )}\n            >\n              {count}\n            </span>\n          )}\n        </>\n      )}\n    </AriaTab>\n  );\n}\n\nexport interface TabPanelProps extends AriaTabPanelProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function TabPanel({ className, ref, ...props }: TabPanelProps) {\n  return (\n    <AriaTabPanel\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"outline-none focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-audio-generator",
      "type": "registry:block",
      "title": "Agent Audio Generator",
      "description": "agent audio generator",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-audio-generator.tsx",
          "target": "@components/agents-ui/agent-audio-generator.tsx",
          "type": "registry:component",
          "content": "export { AgentAudioGenerator } from \"./application/media/audio-generator\"\nexport type {\n  AgentAudioGeneratorProps,\n  VoiceOption,\n} from \"./application/media/audio-generator\"\n"
        },
        {
          "path": "components/agents-ui/application/media/audio-generator.tsx",
          "target": "@components/agents-ui/application/media/audio-generator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  ChevronDown,\n  Copy,\n  Download,\n  Edit2,\n  Pause,\n  Play,\n  RefreshCw,\n  Volume2,\n} from \"lucide-react\"\nimport { useState } from \"react\"\n\nexport interface VoiceOption {\n  id: string\n  name: string\n  gender: \"Male\" | \"Female\"\n  accent?: string\n}\nexport interface AgentAudioGeneratorProps {\n  audioUrl?: string\n  isGenerating?: boolean\n  isPlaying?: boolean\n  currentTime?: number\n  duration?: number\n  onPlay?: () => void\n  onPause?: () => void\n  onSeek?: (time: number) => void\n  onExport?: (format?: \"mp3\" | \"wav\" | \"m4a\") => void\n  onCopy?: () => void\n  onEdit?: () => void\n  onRegenerateResponse?: () => void\n  onLanguageChange?: (language: string) => void\n  onSpeedChange?: (speed: string) => void\n  onVoiceChange?: (voice: VoiceOption) => void\n  onToneChange?: (tone: string) => void\n  language?: string\n  speed?: string\n  voice?: VoiceOption\n  tone?: string\n  availableVoices?: VoiceOption[]\n  className?: string\n  timestamp?: string\n}\n\nconst voices: VoiceOption[] = [\n  { id: \"jenny\", name: \"Jenny\", gender: \"Female\", accent: \"American\" },\n  { id: \"alex\", name: \"Alex\", gender: \"Male\", accent: \"British\" },\n  { id: \"sarah\", name: \"Sarah\", gender: \"Female\", accent: \"Australian\" },\n]\nconst time = (seconds: number) =>\n  `${Math.floor(seconds / 60)}:${Math.floor(seconds % 60)\n    .toString()\n    .padStart(2, \"0\")}`\n\nfunction Setting({\n  label,\n  value,\n  onClick,\n}: {\n  label: string\n  value: string\n  onClick: () => void\n}) {\n  return (\n    <button\n      type=\"button\"\n      onClick={onClick}\n      className=\"border-separator-border hover:bg-background-secondary-hover flex min-h-12 items-center justify-between gap-3 border-b px-4 text-left sm:border-r\"\n    >\n      <span className=\"text-caption-1-medium text-text-secondary\">{label}</span>\n      <span className=\"text-body-medium inline-flex items-center gap-1.5\">\n        {value}\n        <ChevronDown className=\"text-text-tertiary size-3.5\" />\n      </span>\n    </button>\n  )\n}\n\nexport function AgentAudioGenerator({\n  audioUrl,\n  isGenerating = false,\n  isPlaying = false,\n  currentTime = 21,\n  duration = 62,\n  onPlay,\n  onPause,\n  onSeek,\n  onExport,\n  onCopy,\n  onEdit,\n  onRegenerateResponse,\n  onLanguageChange,\n  onSpeedChange,\n  onVoiceChange,\n  onToneChange,\n  language = \"English (US)\",\n  speed = \"Normal\",\n  voice = voices[0],\n  tone = \"Friendly\",\n  availableVoices = voices,\n  className,\n  timestamp = \"Just now\",\n}: AgentAudioGeneratorProps) {\n  const [isExporting, setIsExporting] = useState(false)\n  const progress =\n    duration > 0 ? Math.min(100, (currentTime / duration) * 100) : 0\n  const bars = Array.from({ length: 48 }, (_, index) =>\n    Math.min(\n      32,\n      Math.abs(Math.sin(index * 1.31) * 21 + Math.sin(index * 0.39) * 7) + 5\n    )\n  )\n  const voiceIndex = Math.max(\n    0,\n    availableVoices.findIndex((item) => item.id === voice?.id)\n  )\n  const nextVoice =\n    availableVoices[(voiceIndex + 1) % Math.max(1, availableVoices.length)]\n  const handleExport = async () => {\n    if (!audioUrl || isGenerating || isExporting) return\n    setIsExporting(true)\n    try {\n      await onExport?.()\n    } finally {\n      setIsExporting(false)\n    }\n  }\n\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-2 border-b px-4 py-3\">\n        <div>\n          <h3 className=\"text-headline-semibold\">Generated audio</h3>\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {isGenerating\n              ? \"Generating audio\"\n              : isExporting\n                ? \"Preparing export\"\n                : `Ready  |  ${time(duration)}  |  ${timestamp}`}\n          </p>\n        </div>\n        <div className=\"flex gap-1\">\n          {onEdit && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Edit2}\n              onClick={onEdit}\n            >\n              Edit\n            </Button>\n          )}\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={isExporting ? RefreshCw : Download}\n            onClick={handleExport}\n            disabled={!audioUrl || isGenerating || isExporting}\n          >\n            {isExporting ? \"Exporting\" : \"Export\"}\n          </Button>\n        </div>\n      </header>\n      <div className=\"p-4\">\n        <div className=\"bg-background-secondary-default flex items-center gap-4 rounded-lg p-4\">\n          <Button\n            size=\"medium\"\n            iconOnly\n            leadingIcon={isGenerating ? RefreshCw : isPlaying ? Pause : Play}\n            aria-label={isPlaying ? \"Pause audio\" : \"Play audio\"}\n            disabled={isGenerating || !audioUrl}\n            onClick={isPlaying ? onPause : onPlay}\n          />\n          <div className=\"min-w-0 flex-1\">\n            <div className=\"relative flex h-10 items-center gap-0.5\">\n              {bars.map((height, index) => (\n                <span\n                  key={index}\n                  className={cx(\n                    \"w-1 rounded-full\",\n                    (index / bars.length) * 100 <= progress\n                      ? \"bg-text-primary\"\n                      : \"bg-border-button-default\"\n                  )}\n                  style={{ height }}\n                />\n              ))}\n              <input\n                type=\"range\"\n                min={0}\n                max={duration}\n                value={currentTime}\n                onChange={(event) => onSeek?.(Number(event.target.value))}\n                aria-label=\"Audio position\"\n                className=\"absolute inset-0 cursor-pointer opacity-0\"\n              />\n            </div>\n            <div className=\"text-caption-1-regular text-text-secondary mt-1 flex justify-between tabular-nums\">\n              <span>{time(currentTime)}</span>\n              <span>{time(duration)}</span>\n            </div>\n          </div>\n          <Volume2 className=\"text-text-secondary size-4\" />\n        </div>\n      </div>\n      <div className=\"border-separator-border grid border-t sm:grid-cols-2\">\n        <Setting\n          label=\"Language\"\n          value={language}\n          onClick={() =>\n            onLanguageChange?.(\n              language === \"English (US)\" ? \"Spanish\" : \"English (US)\"\n            )\n          }\n        />\n        <Setting\n          label=\"Speed\"\n          value={speed}\n          onClick={() =>\n            onSpeedChange?.(speed === \"Normal\" ? \"1.25x\" : \"Normal\")\n          }\n        />\n        <Setting\n          label=\"Voice\"\n          value={\n            voice\n              ? `${voice.name}${voice.accent ? `, ${voice.accent}` : \"\"}`\n              : \"Default\"\n          }\n          onClick={() => {\n            if (nextVoice) onVoiceChange?.(nextVoice)\n          }}\n        />\n        <Setting\n          label=\"Tone\"\n          value={tone}\n          onClick={() =>\n            onToneChange?.(tone === \"Friendly\" ? \"Professional\" : \"Friendly\")\n          }\n        />\n      </div>\n      {(onCopy || onRegenerateResponse) && (\n        <footer className=\"border-separator-border flex gap-1 border-t px-3 py-2\">\n          {onCopy && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Copy}\n              onClick={onCopy}\n            >\n              Copy\n            </Button>\n          )}\n          {onRegenerateResponse && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={RefreshCw}\n              onClick={onRegenerateResponse}\n            >\n              Regenerate\n            </Button>\n          )}\n        </footer>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-card",
      "type": "registry:block",
      "title": "Agent Card",
      "description": "agent card",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-card.tsx",
          "target": "@components/agents-ui/agent-card.tsx",
          "type": "registry:component",
          "content": "export { AgentCard } from \"./application/agent-card/agent-card\"\nexport type {\n  AgentCardProps,\n  AgentCapability,\n  AgentStatus,\n} from \"./application/agent-card/agent-card\"\n"
        },
        {
          "path": "components/agents-ui/application/agent-card/agent-card.tsx",
          "target": "@components/agents-ui/application/agent-card/agent-card.tsx",
          "type": "registry:component",
          "content": "import { Avatar } from \"@/components/boardui/base/avatar/avatar\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  CheckCircle2,\n  Circle,\n  CircleDot,\n  Loader2,\n  PauseCircle,\n  XCircle,\n} from \"lucide-react\"\n\nexport type AgentStatus =\n  | \"idle\"\n  | \"thinking\"\n  | \"running\"\n  | \"paused\"\n  | \"error\"\n  | \"completed\"\nexport interface AgentCapability {\n  name: string\n  description: string\n  icon?: React.ReactNode\n}\nexport interface AgentCardProps {\n  name: string\n  description?: string\n  avatar?: string\n  status?: AgentStatus\n  capabilities?: AgentCapability[]\n  className?: string\n  onAction?: (action: string) => void\n}\nconst states = {\n  idle: { icon: Circle, label: \"Idle\", color: \"text-text-secondary\" },\n  thinking: {\n    icon: CircleDot,\n    label: \"Thinking\",\n    color: \"text-foreground-icon-notice\",\n  },\n  running: { icon: Loader2, label: \"Running\", color: \"text-accent-600\" },\n  paused: {\n    icon: PauseCircle,\n    label: \"Paused\",\n    color: \"text-foreground-icon-notice\",\n  },\n  error: { icon: XCircle, label: \"Error\", color: \"text-foreground-icon-error\" },\n  completed: {\n    icon: CheckCircle2,\n    label: \"Completed\",\n    color: \"text-foreground-icon-positive\",\n  },\n} satisfies Record<\n  AgentStatus,\n  { icon: typeof Circle; label: string; color: string }\n>\nexport function AgentCard({\n  name,\n  description,\n  avatar,\n  status = \"idle\",\n  capabilities = [],\n  className,\n  onAction,\n}: AgentCardProps) {\n  const state = states[status]\n  const Icon = state.icon\n  return (\n    <article\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"flex items-start gap-3 p-4\">\n        <Avatar\n          size=\"md\"\n          src={avatar}\n          alt={name}\n          initials={name.slice(0, 2).toUpperCase()}\n        />\n        <div className=\"min-w-0 flex-1\">\n          <div className=\"flex flex-wrap items-center justify-between gap-2\">\n            <h3 className=\"text-headline-semibold\">{name}</h3>\n            <span\n              className={cx(\n                \"text-caption-1-medium inline-flex items-center gap-1.5\",\n                state.color\n              )}\n            >\n              <Icon\n                className={cx(\n                  \"size-3.5\",\n                  status === \"running\" && \"animate-spin\"\n                )}\n              />\n              {state.label}\n            </span>\n          </div>\n          {description && (\n            <p className=\"text-body-2-regular text-text-secondary mt-1 leading-5\">\n              {description}\n            </p>\n          )}\n        </div>\n      </header>\n      {capabilities.length > 0 && (\n        <section className=\"border-separator-border border-t\">\n          <h4 className=\"text-caption-1-medium text-text-secondary px-4 pt-3 pb-1\">\n            Capabilities\n          </h4>\n          <div className=\"divide-separator-border divide-y\">\n            {capabilities.map((capability) => (\n              <div key={capability.name} className=\"flex gap-3 px-4 py-3\">\n                {capability.icon && (\n                  <span className=\"text-text-secondary mt-0.5\">\n                    {capability.icon}\n                  </span>\n                )}\n                <div>\n                  <p className=\"text-body-medium\">{capability.name}</p>\n                  <p className=\"text-caption-1-regular text-text-secondary\">\n                    {capability.description}\n                  </p>\n                </div>\n              </div>\n            ))}\n          </div>\n        </section>\n      )}\n      {onAction && (\n        <footer className=\"border-separator-border flex gap-2 border-t px-3 py-2\">\n          {status === \"idle\" && (\n            <Button size=\"small\" onClick={() => onAction(\"start\")}>\n              Start agent\n            </Button>\n          )}\n          {(status === \"running\" || status === \"thinking\") && (\n            <>\n              <Button\n                size=\"small\"\n                variant=\"secondary\"\n                onClick={() => onAction(\"pause\")}\n              >\n                Pause\n              </Button>\n              <Button\n                size=\"small\"\n                variant=\"danger\"\n                onClick={() => onAction(\"stop\")}\n              >\n                Stop\n              </Button>\n            </>\n          )}\n          {status === \"paused\" && (\n            <Button size=\"small\" onClick={() => onAction(\"resume\")}>\n              Resume\n            </Button>\n          )}\n          {(status === \"completed\" || status === \"error\") && (\n            <Button size=\"small\" onClick={() => onAction(\"restart\")}>\n              Restart\n            </Button>\n          )}\n        </footer>\n      )}\n    </article>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/avatar/avatar.tsx",
          "target": "@components/boardui/base/avatar/avatar.tsx",
          "type": "registry:component",
          "content": "/* eslint-disable @next/next/no-img-element */\nimport type { HTMLAttributes, Ref } from \"react\";\nimport { cx, sortCx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Figma source: Board UI → Avatar (styles Avatar/1…Avatar/26; used throughout\n * dashboard 1, node 3731:2932).\n *\n * Sizes used in the designs (px):\n *   xs = 20   breadcrumb workspace marks     (initials 10/15 semibold)\n *   sm = 24   table rows                     (initials 12/16 semibold)\n *   md = 32   sidebar workspace / team card  (initials 16/22 semibold)\n *   lg = 36   people cards                   (initials 18/24 semibold)\n *\n * Renders a photo when `src` is given, otherwise centered initials on a\n * tinted disc. Initial tints from Figma:\n *   neutral → bg avatar/neutral/background, text text/secondary\n *   blue    → bg color/blue/300,    text color/blue/900\n *   lime    → bg color/lime/200,    text color/lime/700\n *   pink    → bg color/pink/200,    text color/pink/500\n */\n\ntype AvatarSize = \"xs\" | \"sm\" | \"md\" | \"lg\";\ntype AvatarColor = \"neutral\" | \"blue\" | \"lime\" | \"pink\";\n\nexport interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {\n  size?: AvatarSize;\n  color?: AvatarColor;\n  /** Photo URL. Wins over `initials`. */\n  src?: string;\n  alt?: string;\n  /** Fallback initials, e.g. \"M\". */\n  initials?: string;\n  ref?: Ref<HTMLSpanElement>;\n}\n\nconst styles = sortCx({\n  base: \"inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full text-center align-middle transition-[width,height,font-size] duration-200 ease\",\n  size: {\n    xs: \"size-5 text-[10px] leading-[15px] font-semibold\",\n    sm: \"size-6 text-caption-1-semibold tracking-normal\",\n    md: \"size-8 text-headline-semibold\",\n    lg: \"size-9 text-[18px] leading-6 font-semibold\",\n  },\n  color: {\n    neutral: \"bg-avatar-neutral-background text-text-secondary\",\n    blue: \"bg-blue-300 text-blue-900\",\n    lime: \"bg-lime-200 text-lime-700\",\n    pink: \"bg-pink-200 text-pink-500\",\n  },\n});\n\nexport function Avatar({\n  size = \"md\",\n  color = \"neutral\",\n  src,\n  alt,\n  initials,\n  className,\n  ref,\n  ...props\n}: AvatarProps) {\n  return (\n    <span\n      ref={ref}\n      className={cx(styles.base, styles.size[size], styles.color[color], className)}\n      {...props}\n    >\n      {src ? (\n        <img\n          src={src}\n          alt={alt ?? \"\"}\n          loading=\"lazy\"\n          decoding=\"async\"\n          className=\"size-full object-cover\"\n        />\n      ) : (\n        initials\n      )}\n    </span>\n  );\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-chat-history",
      "type": "registry:block",
      "title": "Agent Chat History",
      "description": "agent chat history",
      "dependencies": [
        "@remixicon/react@^4.9.0",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-chat-history.tsx",
          "target": "@components/agents-ui/agent-chat-history.tsx",
          "type": "registry:component",
          "content": "export { AgentChatHistory } from \"./application/chat-history/chat-history\"\nexport type {\n  AgentChatHistoryProps,\n  ChatMessage,\n  ChatSession,\n} from \"./application/chat-history/chat-history\"\n"
        },
        {
          "path": "components/agents-ui/application/chat-history/chat-history.tsx",
          "target": "@components/agents-ui/application/chat-history/chat-history.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Dropdown,\n  DropdownDivider,\n  DropdownItem,\n  DropdownPopover,\n  DropdownTrigger,\n} from \"@/components/boardui/base/dropdown/dropdown\"\nimport { Input } from \"@/components/boardui/base/input/input\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  Archive,\n  Download,\n  Filter,\n  MoreHorizontal,\n  Search,\n  Star,\n  Trash2,\n} from \"lucide-react\"\nimport { useMemo, useState } from \"react\"\n\nexport type ChatMessage = {\n  id: string\n  role: \"user\" | \"assistant\"\n  content: string\n  timestamp: Date\n  tokens?: number\n  model?: string\n}\nexport type ChatSession = {\n  id: string\n  title: string\n  messages: ChatMessage[]\n  createdAt: Date\n  updatedAt: Date\n  starred?: boolean\n  archived?: boolean\n}\nexport interface AgentChatHistoryProps {\n  sessions: ChatSession[]\n  selectedSessionId?: string\n  onSelectSession?: (session: ChatSession) => void\n  onDeleteSession?: (sessionId: string) => void\n  onStarSession?: (sessionId: string) => void\n  onArchiveSession?: (sessionId: string) => void\n  onExportSession?: (sessionId: string) => void\n  className?: string\n}\nfunction relativeDate(date: Date) {\n  const days = Math.floor((Date.now() - date.getTime()) / 86400000)\n  return days === 0\n    ? \"Today\"\n    : days === 1\n      ? \"Yesterday\"\n      : days < 7\n        ? `${days} days ago`\n        : date.toLocaleDateString()\n}\n\nexport function AgentChatHistory({\n  sessions,\n  selectedSessionId,\n  onSelectSession,\n  onDeleteSession,\n  onStarSession,\n  onArchiveSession,\n  onExportSession,\n  className,\n}: AgentChatHistoryProps) {\n  const [query, setQuery] = useState(\"\")\n  const [filter, setFilter] = useState<\"all\" | \"starred\" | \"archived\">(\"all\")\n  const visible = useMemo(\n    () =>\n      sessions.filter(\n        (session) =>\n          (filter === \"all\" ||\n            (filter === \"starred\" ? session.starred : session.archived)) &&\n          (!query ||\n            session.title.toLowerCase().includes(query.toLowerCase()) ||\n            session.messages.some((message) =>\n              message.content.toLowerCase().includes(query.toLowerCase())\n            ))\n      ),\n    [sessions, filter, query]\n  )\n  const selected = sessions.find((session) => session.id === selectedSessionId)\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default grid min-h-[440px] overflow-hidden rounded-2xl border md:grid-cols-[288px_minmax(0,1fr)]\",\n        className\n      )}\n    >\n      <aside className=\"border-separator-border flex min-h-0 flex-col border-b md:border-r md:border-b-0\">\n        <header className=\"border-separator-border space-y-2 border-b p-3\">\n          <Input\n            aria-label=\"Search conversations\"\n            placeholder=\"Search conversations\"\n            value={query}\n            onChange={setQuery}\n            leadingIcon={Search}\n          />\n          <div className=\"flex items-center justify-between\">\n            <Dropdown>\n              <DropdownTrigger className=\"text-caption-1-medium hover:bg-background-secondary-hover inline-flex min-h-8 items-center gap-1.5 rounded-lg px-2\">\n                <Filter className=\"size-3.5\" />\n                {filter === \"all\"\n                  ? \"All\"\n                  : filter === \"starred\"\n                    ? \"Starred\"\n                    : \"Archived\"}\n              </DropdownTrigger>\n              <DropdownPopover aria-label=\"Conversation filter\">\n                <DropdownItem\n                  selected={filter === \"all\"}\n                  onSelect={() => setFilter(\"all\")}\n                >\n                  All conversations\n                </DropdownItem>\n                <DropdownItem\n                  selected={filter === \"starred\"}\n                  onSelect={() => setFilter(\"starred\")}\n                >\n                  Starred\n                </DropdownItem>\n                <DropdownItem\n                  selected={filter === \"archived\"}\n                  onSelect={() => setFilter(\"archived\")}\n                >\n                  Archived\n                </DropdownItem>\n              </DropdownPopover>\n            </Dropdown>\n            <span className=\"text-caption-1-regular text-text-tertiary tabular-nums\">\n              {visible.length}\n            </span>\n          </div>\n        </header>\n        <div className=\"min-h-0 flex-1 overflow-y-auto\">\n          {visible.map((session) => {\n            const last = session.messages.at(-1)\n            return (\n              <div\n                key={session.id}\n                className={cx(\n                  \"group border-separator-border relative border-b\",\n                  session.id === selectedSessionId &&\n                    \"bg-background-secondary-default\"\n                )}\n              >\n                <button\n                  type=\"button\"\n                  onClick={() => onSelectSession?.(session)}\n                  className=\"hover:bg-background-secondary-hover w-full p-3 pr-10 text-left\"\n                >\n                  <div className=\"flex items-center gap-2\">\n                    <span className=\"text-body-medium min-w-0 flex-1 truncate\">\n                      {session.title}\n                    </span>\n                    {session.starred && (\n                      <Star className=\"text-text-secondary size-3.5 fill-current\" />\n                    )}\n                  </div>\n                  <p className=\"text-caption-1-regular text-text-secondary mt-1 line-clamp-2 leading-4\">\n                    {last?.content ?? \"No messages yet\"}\n                  </p>\n                  <p className=\"text-caption-1-regular text-text-tertiary mt-2\">\n                    {session.messages.length} messages |{\" \"}\n                    {relativeDate(session.updatedAt)}\n                  </p>\n                </button>\n                <Dropdown>\n                  <DropdownTrigger className=\"hover:bg-background-secondary-hover absolute top-2 right-2 grid size-8 place-items-center rounded-lg opacity-0 group-hover:opacity-100\">\n                    <MoreHorizontal className=\"size-4\" />\n                  </DropdownTrigger>\n                  <DropdownPopover\n                    aria-label={`${session.title} actions`}\n                    placement=\"bottom end\"\n                  >\n                    <DropdownItem onSelect={() => onStarSession?.(session.id)}>\n                      <Star className=\"size-4\" />\n                      {session.starred ? \"Unstar\" : \"Star\"}\n                    </DropdownItem>\n                    <DropdownItem\n                      onSelect={() => onArchiveSession?.(session.id)}\n                    >\n                      <Archive className=\"size-4\" />\n                      {session.archived ? \"Unarchive\" : \"Archive\"}\n                    </DropdownItem>\n                    <DropdownItem\n                      onSelect={() => onExportSession?.(session.id)}\n                    >\n                      <Download className=\"size-4\" />\n                      Export\n                    </DropdownItem>\n                    <DropdownDivider />\n                    <DropdownItem\n                      className=\"text-text-error-placeholder\"\n                      onSelect={() => onDeleteSession?.(session.id)}\n                    >\n                      <Trash2 className=\"size-4\" />\n                      Delete\n                    </DropdownItem>\n                  </DropdownPopover>\n                </Dropdown>\n              </div>\n            )\n          })}\n          {visible.length === 0 && (\n            <p className=\"text-body-2-regular text-text-secondary p-6 text-center\">\n              No conversations found.\n            </p>\n          )}\n        </div>\n      </aside>\n      <main className=\"min-w-0\">\n        {selected ? (\n          <>\n            <header className=\"border-separator-border border-b px-4 py-3\">\n              <h3 className=\"text-headline-semibold\">{selected.title}</h3>\n              <p className=\"text-caption-1-regular text-text-secondary\">\n                {selected.messages.length} messages | Updated{\" \"}\n                {relativeDate(selected.updatedAt)}\n              </p>\n            </header>\n            <div className=\"divide-separator-border divide-y\">\n              {selected.messages.map((message) => (\n                <article key={message.id} className=\"px-4 py-3\">\n                  <header className=\"text-caption-1-medium mb-1.5 flex flex-wrap items-center gap-2\">\n                    <span>{message.role === \"user\" ? \"You\" : \"Assistant\"}</span>\n                    <time className=\"text-text-tertiary\">\n                      {message.timestamp.toLocaleTimeString([], {\n                        hour: \"2-digit\",\n                        minute: \"2-digit\",\n                      })}\n                    </time>\n                    {message.model && (\n                      <span className=\"text-text-tertiary\">\n                        {message.model}\n                      </span>\n                    )}\n                    {message.tokens !== undefined && (\n                      <span className=\"text-text-tertiary ml-auto tabular-nums\">\n                        {message.tokens} tokens\n                      </span>\n                    )}\n                  </header>\n                  <p className=\"text-body-2-regular leading-5 whitespace-pre-wrap\">\n                    {message.content}\n                  </p>\n                </article>\n              ))}\n            </div>\n          </>\n        ) : (\n          <div className=\"grid min-h-80 place-items-center p-8 text-center\">\n            <div>\n              <p className=\"text-body-medium\">Select a conversation</p>\n              <p className=\"text-body-2-regular text-text-secondary mt-1\">\n                Messages and run metadata appear here.\n              </p>\n            </div>\n          </div>\n        )}\n      </main>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/dropdown/dropdown.tsx",
          "target": "@components/boardui/base/dropdown/dropdown.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { createContext, useContext, useRef, useState, type ComponentProps, type ReactNode, type RefObject } from \"react\";\nimport {\n  Button as AriaButton,\n  Dialog as AriaDialog,\n  DialogTrigger as AriaDialogTrigger,\n  Popover as AriaPopover,\n} from \"react-aria-components\";\nimport {\n  MENU_ITEM,\n  MENU_ITEM_ACTIVE,\n  MENU_ITEM_INTERACTIVE,\n  MENU_POPOVER_SURFACE,\n  MENU_POPOVER_WIDTH,\n} from \"@/components/boardui/base/dropdown/menu-styles\";\nimport { cx } from \"@/components/boardui/utils/cx\";\nimport { useDismissOnOutsidePress, useTriggerToggle } from \"@/components/boardui/utils/use-dismiss-on-outside-press\";\n\n/**\n * Dropdown - the BoardUI popover-menu recipe as composable primitives, built\n * on React Aria's DialogTrigger/Popover. Unlike Select (which picks a value\n * into a trigger), Dropdown is a free-form menu surface: grouped rows of\n * actions, headers, footers, whatever the panel needs.\n *\n * The same recipe powers the dashboard sidebar's team/account menus and the\n * AI chat template's add/model/folder menus:\n *\n * - Panel: white, 1px border/button/default, radius 16, p 10, shadow/dropdown.\n * - Appear animation: 150ms fade + scale-95 + 2px blur in and out.\n * - Rows: rounded-2lg, background/secondary/hover on hover and on the selected\n *   row, body-medium labels, 4px apart (the panel's flex column carries a\n *   gap-1, the same rhythm as the Select listbox).\n *\n * Composition:\n *\n * ```tsx\n * <Dropdown isOpen={isOpen} onOpenChange={setIsOpen}>\n *   <DropdownTrigger>Open</DropdownTrigger>\n *   <DropdownPopover aria-label=\"Actions\" placement=\"bottom start\">\n *     <DropdownGroup label=\"Add\">\n *       <DropdownItem onSelect={close}>…row content…</DropdownItem>\n *     </DropdownGroup>\n *     <DropdownDivider />\n *     <DropdownGroup label=\"Plugins\">…</DropdownGroup>\n *   </DropdownPopover>\n * </Dropdown>\n * ```\n *\n * State can be uncontrolled (omit isOpen/onOpenChange) - control it when the\n * trigger needs to react to the open state (e.g. rotating a chevron).\n */\n\n/* ------------------------------------------------------------------- shell */\n\ninterface DropdownContextValue {\n  triggerRef: RefObject<HTMLButtonElement | null>;\n  popoverRef: RefObject<HTMLElement | null>;\n}\n\nconst DropdownContext = createContext<DropdownContextValue | null>(null);\n\nexport interface DropdownProps {\n  isOpen?: boolean;\n  onOpenChange?: (isOpen: boolean) => void;\n  /** Trigger (a DropdownTrigger) followed by a DropdownPopover. */\n  children: ReactNode;\n}\n\n/**\n * The popover is `isNonModal`: react-aria's modal scroll lock puts\n * `overflow: hidden` on <html>, which collapses the page scroll position and\n * visibly yanks sticky layout (e.g. the docs sidebar) whenever a menu opens.\n * Non-modal skips the lock, but react-aria hard-couples outside-press\n * dismissal to modality - so open state lives here (bridging any controlled\n * props) and dismissal is restored via useDismissOnOutsidePress, the same\n * fix as Select and the date-picker family.\n */\nexport function Dropdown({ isOpen: controlledOpen, onOpenChange, children }: DropdownProps) {\n  const triggerRef = useRef<HTMLButtonElement>(null);\n  const popoverRef = useRef<HTMLElement>(null);\n  const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n\n  const isOpen = controlledOpen ?? uncontrolledOpen;\n  const setOpen = (next: boolean) => {\n    setUncontrolledOpen(next);\n    onOpenChange?.(next);\n  };\n\n  useDismissOnOutsidePress(isOpen, () => setOpen(false), [triggerRef, popoverRef]);\n  // Pressing the trigger while open closes the menu instead of reopening\n  const allowOpenChange = useTriggerToggle(isOpen, triggerRef);\n\n  return (\n    <DropdownContext.Provider value={{ triggerRef, popoverRef }}>\n      <AriaDialogTrigger isOpen={isOpen} onOpenChange={(o) => allowOpenChange(o) && setOpen(o)}>\n        {children}\n      </AriaDialogTrigger>\n    </DropdownContext.Provider>\n  );\n}\n\n/** The element that opens the menu. Style it entirely via className. */\nexport function DropdownTrigger({ className, ...props }: ComponentProps<typeof AriaButton>) {\n  const context = useContext(DropdownContext);\n  return (\n    <AriaButton\n      ref={context?.triggerRef}\n      {...props}\n      className={cx(\n        \"cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n        className as string,\n      )}\n    />\n  );\n}\n\n/* ------------------------------------------------------------------- panel */\n\nexport interface DropdownPopoverProps\n  extends Pick<ComponentProps<typeof AriaPopover>, \"placement\" | \"offset\" | \"crossOffset\"> {\n  \"aria-label\": string;\n  /** Extra classes on the panel - e.g. a width override (default w-[266px]). */\n  className?: string;\n  /** Classes on the inner dialog (the flex column), e.g. gap between groups. */\n  dialogClassName?: string;\n  children: ReactNode;\n}\n\nexport function DropdownPopover({\n  \"aria-label\": ariaLabel,\n  placement = \"bottom start\",\n  offset = 4,\n  crossOffset,\n  className,\n  dialogClassName,\n  children,\n}: DropdownPopoverProps) {\n  const context = useContext(DropdownContext);\n  return (\n    <AriaPopover\n      ref={context?.popoverRef}\n      isNonModal\n      placement={placement}\n      offset={offset}\n      crossOffset={crossOffset}\n      className={cx(\n        MENU_POPOVER_WIDTH,\n        MENU_POPOVER_SURFACE,\n        className,\n      )}\n    >\n      {/* gap-1 keeps bare DropdownItems 4px apart, the same rhythm as the\n          Select listbox; DropdownDivider's margins are sized to absorb it. */}\n      <AriaDialog aria-label={ariaLabel} className={cx(\"flex flex-col gap-1 outline-none\", dialogClassName)}>\n        {children}\n      </AriaDialog>\n    </AriaPopover>\n  );\n}\n\n/* ----------------------------------------------------------------- content */\n\nexport interface DropdownGroupProps {\n  /** Muted body-medium heading above the rows. */\n  label?: string;\n  className?: string;\n  children: ReactNode;\n}\n\nexport function DropdownGroup({ label, className, children }: DropdownGroupProps) {\n  return (\n    // pt-1 is spacing for the group LABEL - a label-less group must not\n    // carry it, or its first row floats 4px lower than the panel padding\n    // implies (visible as extra space above the first item's hover pill).\n    <div className={cx(\"flex w-full flex-col gap-1.5\", label && \"pt-1\", className)}>\n      {label && <span className=\"pl-2 text-body-medium text-text-secondary\">{label}</span>}\n      <div className=\"flex w-full flex-col gap-1\">{children}</div>\n    </div>\n  );\n}\n\nexport interface DropdownItemProps {\n  /** Highlights the row like the hover state (current selection). */\n  selected?: boolean;\n  onSelect?: () => void;\n  /** Row padding defaults to p-2 - override for denser rows (px-2 py-1.5). */\n  className?: string;\n  children: ReactNode;\n}\n\n/**\n * A menu row. Content is free-form - icon + label, avatar + name, label +\n * trailing badge - laid out in a gap-2 flex row.\n */\nexport function DropdownItem({ selected, onSelect, className, children }: DropdownItemProps) {\n  return (\n    <button\n      type=\"button\"\n      aria-pressed={selected}\n      onClick={onSelect}\n      className={cx(\n        MENU_ITEM,\n        selected ? MENU_ITEM_ACTIVE : MENU_ITEM_INTERACTIVE,\n        className,\n      )}\n    >\n      {children}\n    </button>\n  );\n}\n\n/** Full-bleed 1px divider between groups (bleeds through the panel's p-2.5).\n *  my-1.5 + the dialog's gap-1 on both sides = the original 10px breathing room. */\nexport function DropdownDivider({ className }: { className?: string }) {\n  return <div className={cx(\"-mx-2.5 my-1.5 h-px shrink-0 bg-border-button-default\", className)} />;\n}\n"
        },
        {
          "path": "components/boardui/base/dropdown/menu-styles.ts",
          "target": "@components/boardui/base/dropdown/menu-styles.ts",
          "type": "registry:component",
          "content": "/**\n * Shared visual recipe for BoardUI menu surfaces.\n *\n * Select and Dropdown intentionally keep their distinct React Aria semantics\n * (single-value listbox vs. action menu), while consuming the same panel,\n * motion, and row treatments from here.\n */\nexport const MENU_POPOVER_SURFACE = [\n  \"max-w-[calc(100vw-32px)] overflow-y-auto\",\n  \"rounded-2xl border border-border-button-default bg-background-primary-default p-2.5 shadow-dropdown\",\n  \"transition duration-150 ease-out\",\n  \"data-[entering]:opacity-0 data-[entering]:scale-95 data-[entering]:blur-[2px]\",\n  \"data-[exiting]:opacity-0 data-[exiting]:scale-95 data-[exiting]:blur-[2px]\",\n  \"data-[placement=bottom]:origin-top-left data-[placement=top]:origin-bottom-left\",\n  \"data-[placement=left]:origin-right data-[placement=right]:origin-left\",\n].join(\" \");\n\nexport const MENU_POPOVER_WIDTH = \"w-[266px]\";\n\nexport const MENU_ITEMS_CONTAINER = \"flex w-full flex-col gap-1 outline-none\";\n\nexport const MENU_ITEM = [\n  \"flex w-full cursor-pointer items-center gap-2 rounded-2lg p-2 text-left\",\n  \"text-text-primary outline-none transition-colors\",\n].join(\" \");\n\nexport const MENU_ITEM_ACTIVE = \"bg-dropdown-item-hover-background\";\n\nexport const MENU_ITEM_INTERACTIVE =\n  \"hover:bg-dropdown-item-hover-background focus-visible:bg-dropdown-item-hover-background\";\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/utils/use-dismiss-on-outside-press.ts",
          "target": "@components/boardui/utils/use-dismiss-on-outside-press.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport type { RefObject } from \"react\";\n\n/**\n * React Aria's `Popover` couples \"non-modal\" with \"not dismissable on\n * outside interaction\" — `isNonModal` (which we set to avoid the scroll\n * lock / focus trap that comes with a modal popover) also silently disables\n * its built-in outside-click-to-close behavior. This restores just that\n * piece manually: closes when a pointerdown lands outside every given ref\n * (typically the trigger + the popover's own content).\n */\nexport function useDismissOnOutsidePress(\n  isOpen: boolean,\n  onDismiss: () => void,\n  refs: RefObject<HTMLElement | null>[],\n) {\n  useEffect(() => {\n    if (!isOpen) return;\n\n    const handlePointerDown = (event: PointerEvent) => {\n      const target = event.target as Node;\n      if (refs.some((ref) => ref.current?.contains(target))) return;\n      onDismiss();\n    };\n\n    document.addEventListener(\"pointerdown\", handlePointerDown, true);\n    return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n  }, [isOpen, onDismiss, refs]);\n}\n\n/**\n * Companion fix for the same `isNonModal` popovers: pressing the trigger\n * while the popover is open should close it (toggle), but React Aria fires\n * `onOpenChange(false)` immediately followed by `onOpenChange(true)` within\n * the same press, so the popover never actually closes.\n *\n * This watches for a pointerdown on the trigger while open and swallows the\n * spurious reopen that follows. Wire the returned guard into the component's\n * `onOpenChange`:\n *\n *   const allowOpenChange = useTriggerToggle(isOpen, triggerRef);\n *   <AriaSelect onOpenChange={(o) => allowOpenChange(o) && setIsOpen(o)} …\n */\nexport function useTriggerToggle(\n  isOpen: boolean,\n  triggerRef: RefObject<HTMLElement | null>,\n) {\n  const suppressReopenRef = useRef(false);\n\n  useEffect(() => {\n    if (!isOpen) return;\n\n    const handlePointerDown = (event: PointerEvent) => {\n      if (!triggerRef.current?.contains(event.target as Node)) return;\n      suppressReopenRef.current = true;\n      // Safety valve: only the very next open within this click may be\n      // swallowed; never leave a stale suppression behind.\n      setTimeout(() => {\n        suppressReopenRef.current = false;\n      }, 400);\n    };\n\n    document.addEventListener(\"pointerdown\", handlePointerDown, true);\n    return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n  }, [isOpen, triggerRef]);\n\n  return (next: boolean) => {\n    if (next && suppressReopenRef.current) {\n      suppressReopenRef.current = false;\n      return false;\n    }\n    return true;\n  };\n}\n"
        },
        {
          "path": "components/boardui/base/input/input.tsx",
          "target": "@components/boardui/base/input/input.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  createContext,\n  useContext,\n  type ComponentType,\n  type ReactNode,\n  type Ref,\n} from \"react\";\nimport {\n  Group as AriaGroup,\n  Input as AriaInput,\n  TextField as AriaTextField,\n} from \"react-aria-components\";\nimport type {\n  InputProps as AriaInputProps,\n  TextFieldProps as AriaTextFieldProps,\n} from \"react-aria-components\";\nimport { Label } from \"./label\";\nimport { HintText } from \"./hint-text\";\nimport { cx, sortCx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Figma source: Board UI → Input (node 3665:1849).\n *\n * Architecture (mirrors the Untitled UI / React Aria pattern):\n *\n *   InputBase   - the styled field shell. Renders <AriaGroup> + adornments\n *                 + <AriaInput>. State (hover / focus / disabled / invalid)\n *                 arrives as render-prop booleans from Aria.\n *   TextField   - wraps <AriaTextField> and a TextFieldContext so size /\n *                 classes can flow from the composer down into InputBase\n *                 without prop drilling.\n *   Input       - opinionated composition: TextField → Label → InputBase\n *                 → HintText. The component most consumers use.\n *\n * Why React Aria:\n *   - Label ↔ input ↔ hint association via aria-labelledby / aria-describedby\n *   - aria-required, aria-invalid auto-applied\n *   - Form library / native validation integration\n *   - i18n, RTL, autofill edge cases handled\n *   - Render-prop state surfaces `isFocusWithin`, `isHovered`, `isDisabled`,\n *     `isInvalid`, `isRequired` - no CSS pseudo gymnastics\n *\n * Visuals stay 1:1 with Figma - see `styles/theme.css` for the tokens.\n */\n\ntype InputSize = \"medium\" | \"small\";\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\n/* -------------------------------------------------------------------------- */\n/*  TextFieldContext                                                           */\n/* -------------------------------------------------------------------------- */\n\ninterface TextFieldContextValue {\n  size?: InputSize;\n  fieldClassName?: string;\n  inputClassName?: string;\n}\n\nconst TextFieldContext = createContext<TextFieldContextValue>({});\n\n/* -------------------------------------------------------------------------- */\n/*  TextField                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface TextFieldProps\n  extends Omit<AriaTextFieldProps, \"className\">,\n    TextFieldContextValue {\n  className?: string;\n  children?: ReactNode | ((state: { isRequired: boolean; isInvalid: boolean; isDisabled: boolean; isReadOnly: boolean }) => ReactNode);\n}\n\nexport function TextField({\n  size = \"medium\",\n  fieldClassName,\n  inputClassName,\n  className,\n  children,\n  ...props\n}: TextFieldProps) {\n  return (\n    <TextFieldContext.Provider value={{ size, fieldClassName, inputClassName }}>\n      <AriaTextField\n        {...props}\n        data-input-size={size}\n        className={cx(\n          \"group flex h-max w-full flex-col items-start gap-1\",\n          className,\n        )}\n      >\n        {children as never /* RAC accepts render-prop children */}\n      </AriaTextField>\n    </TextFieldContext.Provider>\n  );\n}\n\nTextField.displayName = \"TextField\";\n\n/* -------------------------------------------------------------------------- */\n/*  InputBase                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputBaseProps extends Omit<AriaInputProps, \"size\" | \"className\"> {\n  size?: InputSize;\n  className?: string;\n  leadingIcon?: IconComponent;\n  trailingIcon?: IconComponent;\n  /** Custom element rendered in the leading slot (Phone basic uses this). */\n  leadingAddon?: ReactNode;\n  /** Class for the field shell. */\n  fieldClassName?: string;\n  /** Ref to the <input> element. */\n  ref?: Ref<HTMLInputElement>;\n  /** Ref to the field shell wrapper. */\n  groupRef?: Ref<HTMLDivElement>;\n}\n\nconst inputStyles = sortCx({\n  field: [\n    \"relative flex w-full items-center\",\n    \"rounded-2lg\",\n    \"bg-background-tertiary-default text-foreground-icon-tertiary\",\n    \"ring-2 ring-inset ring-transparent\",\n    \"transition-[background-color,box-shadow,color] duration-[var(--input-transition-ms)] ease\",\n  ].join(\" \"),\n\n  fieldSize: {\n    medium: \"p-2\",                // 8px all sides → h auto = 36\n    small:  \"h-8 px-1.5 py-2\",    // 32 / 6 / 8\n  },\n\n  // When a leadingAddon is present (Phone basic): tighten left padding.\n  fieldWithAddonSize: {\n    medium: \"h-9 pl-1 pr-2 py-2\", // 36 / 4 / 8 / 8\n    small:  \"h-8 pl-1 pr-1.5 py-2\",\n  },\n\n  content: \"flex w-full items-center gap-2 min-w-0\",\n  leftSection: \"flex flex-1 items-center gap-0.5 min-w-0\",\n\n  input: [\n    \"min-w-0 flex-1 bg-transparent border-0 outline-none p-0 m-0\",\n    \"font-sans text-body-regular text-text-primary pl-1\",\n    \"placeholder:text-text-tertiary\",\n    \"focus:placeholder:text-text-primary\",\n    \"disabled:text-input-disabled-text disabled:placeholder:text-input-disabled-text\",\n    \"disabled:cursor-not-allowed\",\n    \"aria-invalid:placeholder:text-text-error-placeholder\",\n  ].join(\" \"),\n\n  icon: \"size-5 shrink-0\",\n});\n\nexport function InputBase({\n  size: sizeProp,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  leadingAddon,\n  fieldClassName,\n  className,\n  ref,\n  groupRef,\n  ...inputProps\n}: InputBaseProps) {\n  const ctx = useContext(TextFieldContext);\n  const size: InputSize = sizeProp ?? ctx.size ?? \"medium\";\n  const hasAddon = leadingAddon !== undefined && leadingAddon !== null;\n\n  return (\n    <AriaGroup\n      ref={groupRef}\n      className={({ isFocusWithin, isHovered, isDisabled, isInvalid }) =>\n        cx(\n          inputStyles.field,\n          hasAddon\n            ? inputStyles.fieldWithAddonSize[size]\n            : inputStyles.fieldSize[size],\n          // Hover: idle, no focus, no disabled, no invalid\n          isHovered &&\n            !isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-hover\",\n          // Focus wins over hover\n          isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-active\",\n          // Disabled\n          isDisabled &&\n            \"bg-input-disabled-background text-input-disabled-foreground\",\n          // Invalid\n          isInvalid && \"bg-background-tertiary-error text-foreground-icon-error\",\n          ctx.fieldClassName,\n          fieldClassName,\n        )\n      }\n    >\n      <div className={inputStyles.content}>\n        <div className={inputStyles.leftSection}>\n          {hasAddon ? (\n            leadingAddon\n          ) : Leading ? (\n            <Leading className={inputStyles.icon} aria-hidden />\n          ) : null}\n          <AriaInput\n            ref={ref}\n            {...inputProps}\n            className={cx(inputStyles.input, ctx.inputClassName, className)}\n          />\n        </div>\n        {Trailing ? (\n          <Trailing className={inputStyles.icon} aria-hidden />\n        ) : null}\n      </div>\n    </AriaGroup>\n  );\n}\n\nInputBase.displayName = \"InputBase\";\n\n/* -------------------------------------------------------------------------- */\n/*  Input (composed)                                                           */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputProps\n  extends Omit<TextFieldProps, \"children\">,\n    Pick<\n      InputBaseProps,\n      | \"leadingIcon\"\n      | \"trailingIcon\"\n      | \"leadingAddon\"\n      | \"fieldClassName\"\n      | \"groupRef\"\n      | \"ref\"\n    > {\n  label?: ReactNode;\n  hint?: ReactNode;\n  /** Show an info icon next to the label. Replace with tooltip when Tooltip lands. */\n  tooltip?: boolean | string;\n  placeholder?: string;\n}\n\nexport function Input({\n  label,\n  hint,\n  tooltip,\n  placeholder,\n  leadingIcon,\n  trailingIcon,\n  leadingAddon,\n  fieldClassName,\n  ref,\n  groupRef,\n  className,\n  ...textFieldProps\n}: InputProps) {\n  return (\n    <TextField\n      {...textFieldProps}\n      className={className}\n      // Don't clobber an explicit aria-label; fall back to the placeholder\n      // only for unlabelled fields that don't provide one.\n      aria-label={\n        textFieldProps[\"aria-label\"] ??\n        (!label && typeof placeholder === \"string\" ? placeholder : undefined)\n      }\n    >\n      {({ isRequired, isInvalid }) => (\n        <>\n          {label && (\n            <Label\n              isRequired={isRequired}\n              isInvalid={isInvalid}\n              tooltip={tooltip}\n            >\n              {label}\n            </Label>\n          )}\n          <InputBase\n            ref={ref}\n            groupRef={groupRef}\n            placeholder={placeholder}\n            leadingIcon={leadingIcon}\n            trailingIcon={trailingIcon}\n            leadingAddon={leadingAddon}\n            fieldClassName={fieldClassName}\n          />\n          {hint && <HintText isInvalid={isInvalid}>{hint}</HintText>}\n        </>\n      )}\n    </TextField>\n  );\n}\n\nInput.displayName = \"Input\";\n"
        },
        {
          "path": "components/boardui/base/input/label.tsx",
          "target": "@components/boardui/base/input/label.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport { RiInformationFill } from \"@remixicon/react\";\nimport type { LabelProps as AriaLabelProps } from \"react-aria-components\";\nimport { Label as AriaLabel } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Field label. Wraps `react-aria-components`' Label so the parent `TextField`\n * automatically wires `htmlFor` / `aria-labelledby`.\n *\n * Visuals come from Figma:\n *   - Inter Medium 14/20, color text/primary\n *   - 2px gap between label + required asterisk + info icon\n *   - asterisk is text/error-primary (red/500)\n *   - info icon is 16×16 in foreground/icon/quaternary\n *\n * Pass `isRequired` to show the asterisk. Pass `tooltip` to show the info\n * icon (currently a static glyph - when the Tooltip component lands it'll\n * wire up here).\n */\n\nexport interface LabelProps extends AriaLabelProps {\n  children: ReactNode;\n  isRequired?: boolean;\n  /** Reserved for invalid-aware styling (asterisk color, etc.) once we need it. */\n  isInvalid?: boolean;\n  /** Show the info icon next to the label. */\n  tooltip?: boolean | string;\n  ref?: Ref<HTMLLabelElement>;\n}\n\nexport function Label({\n  isRequired = false,\n  isInvalid: _isInvalid,\n  tooltip,\n  className,\n  children,\n  ...props\n}: LabelProps) {\n  void _isInvalid;\n  return (\n    <AriaLabel\n      data-label=\"true\"\n      {...props}\n      className={cx(\n        \"flex cursor-default items-center gap-0.5\",\n        \"text-body-medium text-text-primary\",\n        className,\n      )}\n    >\n      {children}\n      {isRequired && (\n        <span\n          aria-hidden=\"true\"\n          className=\"text-body-medium text-text-error-primary\"\n        >\n          *\n        </span>\n      )}\n      {tooltip && (\n        <RiInformationFill\n          className=\"size-4 shrink-0 text-foreground-icon-quaternary\"\n          aria-hidden\n        />\n      )}\n    </AriaLabel>\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/input/hint-text.tsx",
          "target": "@components/boardui/base/input/hint-text.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport type { TextProps as AriaTextProps } from \"react-aria-components\";\nimport { Text as AriaText } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Caption text rendered below a field. Wraps `react-aria-components`' Text\n * so the parent `TextField` automatically wires `aria-describedby` (when\n * `slot=\"description\"`) or `aria-errormessage` (when `slot=\"errorMessage\"`).\n *\n * Visuals come from Figma:\n *   - Inter Medium 12/16, letter-spacing 0.15px\n *   - color text/secondary (default) or text/error-primary (invalid)\n *   - 1px top padding to align with the field's bottom edge\n */\n\nexport interface HintTextProps extends AriaTextProps {\n  children: ReactNode;\n  isInvalid?: boolean;\n  ref?: Ref<HTMLElement>;\n}\n\nexport function HintText({\n  isInvalid = false,\n  className,\n  ...props\n}: HintTextProps) {\n  return (\n    <AriaText\n      slot={isInvalid ? \"errorMessage\" : \"description\"}\n      {...props}\n      className={cx(\n        \"pt-px text-caption-1-medium text-text-secondary\",\n        isInvalid && \"text-text-error-primary\",\n        className,\n      )}\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-checkpoint",
      "type": "registry:block",
      "title": "Agent Checkpoint",
      "description": "agent checkpoint",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-checkpoint.tsx",
          "target": "@components/agents-ui/agent-checkpoint.tsx",
          "type": "registry:component",
          "content": "\"use client\"\nexport { AgentCheckpoint } from \"@/components/agents-ui/application/checkpoint/checkpoint\"\nexport type { AgentCheckpointProps, CheckpointStatus } from \"@/components/agents-ui/application/checkpoint/checkpoint\"\n"
        },
        {
          "path": "components/agents-ui/application/checkpoint/checkpoint.tsx",
          "target": "@components/agents-ui/application/checkpoint/checkpoint.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Bookmark, Play, RotateCcw } from \"lucide-react\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\n\n/**\n * Restore interaction adapted from Vercel AI Elements checkpoint (Apache-2.0).\n * https://github.com/vercel/ai-elements\n */\nexport type CheckpointStatus = \"ready\" | \"restoring\" | \"restored\" | \"error\"\n\nexport interface AgentCheckpointProps {\n  id: string\n  label: string\n  description?: string\n  timestamp?: string\n  messageCount?: number\n  status?: CheckpointStatus\n  progress?: number\n  error?: string\n  disabled?: boolean\n  onRestore?: (checkpointId: string) => void\n  onResume?: (checkpointId: string) => void\n  className?: string\n}\n\nconst statusLabel: Record<CheckpointStatus, string> = {\n  ready: \"Saved\",\n  restoring: \"Restoring\",\n  restored: \"Restored\",\n  error: \"Restore failed\",\n}\n\nconst statusTone: Record<CheckpointStatus, string> = {\n  ready: \"text-text-secondary\",\n  restoring: \"text-accent-600\",\n  restored: \"text-green-700 dark:text-green-400\",\n  error: \"text-red-700 dark:text-red-400\",\n}\n\nexport function AgentCheckpoint({ id, label, description, timestamp, messageCount, status = \"ready\", progress = 0, error, disabled = false, onRestore, onResume, className }: AgentCheckpointProps) {\n  const busy = status === \"restoring\"\n  const value = Math.max(0, Math.min(100, progress))\n  return <section className={cx(\"rounded-xl border border-separator-border bg-background-primary-default p-4\", className)} aria-label={`Checkpoint: ${label}`}>\n    <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n      <div className=\"flex min-w-0 gap-3\"><Bookmark className=\"mt-0.5 size-4 shrink-0 text-text-secondary\" /><div className=\"min-w-0\"><div className=\"flex flex-wrap items-center gap-x-3 gap-y-1\"><h2 className=\"text-sm font-medium text-text-primary\">{label}</h2><span className={cx(\"text-xs\", statusTone[status])}>{statusLabel[status]}</span></div>{description && <p className=\"mt-1 text-sm leading-5 text-text-secondary\">{description}</p>}<div className=\"mt-2 flex flex-wrap gap-x-3 text-xs tabular-nums text-text-secondary\">{timestamp && <time>{timestamp}</time>}{messageCount !== undefined && <span>{messageCount} messages</span>}<span>Checkpoint {id}</span></div></div></div>\n      <div className=\"flex shrink-0 gap-2\">{onResume && <Button size=\"small\" variant=\"secondary\" leadingIcon={Play} disabled={disabled || busy} onClick={() => onResume(id)}>Resume</Button>}{onRestore && <Button size=\"small\" leadingIcon={RotateCcw} disabled={disabled || busy} onClick={() => onRestore(id)}>{busy ? \"Restoring\" : \"Restore\"}</Button>}</div>\n    </div>\n    {busy && <div className=\"mt-4\"><div className=\"flex justify-between text-xs text-text-secondary\"><span>Restoring conversation and workspace state</span><span className=\"tabular-nums\">{Math.round(value)}%</span></div><div className=\"mt-2 h-1.5 overflow-hidden rounded-full bg-background-secondary-default\" role=\"progressbar\" aria-label=\"Restore progress\" aria-valuemin={0} aria-valuemax={100} aria-valuenow={value}><span className=\"block h-full bg-accent-600 transition-[width] duration-150 motion-reduce:transition-none\" style={{ width: `${value}%` }} /></div></div>}\n    {status === \"error\" && <p className=\"mt-4 border-l-2 border-red-500 pl-3 text-sm text-red-700 dark:text-red-400\" role=\"alert\">{error ?? \"The checkpoint could not be restored. Try again or choose another checkpoint.\"}</p>}\n  </section>\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/agents-ui/application/checkpoint/LICENSE",
          "target": "@components/agents-ui/application/checkpoint/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/agents-ui/application/checkpoint/NOTICE.md",
          "target": "@components/agents-ui/application/checkpoint/NOTICE.md",
          "type": "registry:file",
          "content": "# Source notice\n\nThis component is an independent BoardUI implementation informed by the public checkpoint and restore interaction described by Vercel AI Elements.\n\nNo component implementation or source code was copied. The upstream Apache-2.0 license notice is included because its public checkpoint interaction materially influenced this component.\n"
        },
        {
          "path": "components/agents-ui/application/checkpoint/SOURCE.json",
          "target": "@components/agents-ui/application/checkpoint/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements checkpoint\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"revision\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"referenceFiles\": [\"packages/elements/src/checkpoint.tsx\", \"skills/ai-elements/references/checkpoint.md\"],\n  \"relationship\": \"Independent BoardUI implementation informed by the public checkpoint and restore interaction; upstream source code was not copied.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-code-executor",
      "type": "registry:block",
      "title": "Agent Code Executor",
      "description": "agent code executor",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-code-executor.tsx",
          "target": "@components/agents-ui/agent-code-executor.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { CodeExecutor } from \"@/components/agents-ui/application/code-executor/code-executor\"\n\nexport interface CodeExecutionOutput {\n  stdout?: string\n  stderr?: string\n  exitCode: number\n  executionTime?: string\n  memoryUsage?: string\n}\nexport interface CodeExecutionHistoryItem {\n  id: string\n  code: string\n  output: CodeExecutionOutput\n  timestamp: string\n  status: \"success\" | \"error\"\n}\nexport interface AgentCodeExecutorProps {\n  sandboxName?: string\n  language?: string\n  code?: string\n  output?: CodeExecutionOutput\n  executionHistory?: CodeExecutionHistoryItem[]\n  isExecuting?: boolean\n  sandboxLevel?: \"sandboxed\" | \"unrestricted\"\n  onRun?: () => void\n  onStop?: () => void\n  onClear?: () => void\n  onCopyCode?: () => void\n  onEditCode?: (editable: boolean) => void\n  className?: string\n}\nexport function AgentCodeExecutor(props: AgentCodeExecutorProps) {\n  return <CodeExecutor {...props} />\n}\n"
        },
        {
          "path": "components/agents-ui/application/code-executor/code-executor.tsx",
          "target": "@components/agents-ui/application/code-executor/code-executor.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type {\n  AgentCodeExecutorProps,\n  CodeExecutionHistoryItem,\n  CodeExecutionOutput,\n} from \"@/components/agents-ui/agent-code-executor\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  ChevronDown,\n  ClipboardCopy,\n  Code2,\n  History,\n  Pencil,\n  Play,\n  Square,\n  Trash2,\n} from \"lucide-react\"\nimport * as React from \"react\"\n\nconst sampleCode = `import pandas as pd\n\nrenewals = pd.read_csv(\"renewals_q3.csv\")\nat_risk = renewals.query(\"risk_score >= 0.7\")\nprint(at_risk.groupby(\"owner\")[\"renewal_value\"].sum())`\n\nconst sampleOutput: CodeExecutionOutput = {\n  stdout: \"Morgan Lee     520000\\nJordan Kim     410000\\nPriya Shah     360000\",\n  exitCode: 0,\n  executionTime: \"1.24s\",\n  memoryUsage: \"48.2 MB\",\n}\n\nconst sampleHistory: CodeExecutionHistoryItem[] = [\n  {\n    id: \"run-2\",\n    code: 'at_risk = renewals.query(\"risk_score >= 0.7\")\\nprint(len(at_risk))',\n    output: {\n      stdout: \"12\",\n      exitCode: 0,\n      executionTime: \"0.38s\",\n      memoryUsage: \"24.1 MB\",\n    },\n    timestamp: \"2 min ago\",\n    status: \"success\",\n  },\n  {\n    id: \"run-1\",\n    code: 'renewals = pd.read_csv(\"renewals_q3.csv\")\\nprint(renewals.columns)',\n    output: {\n      stderr: \"FileNotFoundError: renewals_q3.csv\",\n      exitCode: 1,\n      executionTime: \"0.09s\",\n      memoryUsage: \"21.8 MB\",\n    },\n    timestamp: \"5 min ago\",\n    status: \"error\",\n  },\n]\n\nfunction ExecutionHistory({\n  records,\n}: {\n  records: CodeExecutionHistoryItem[]\n}) {\n  if (records.length === 0) return null\n  return (\n    <details className=\"group border-separator-border border-t\">\n      <summary className=\"text-text-primary focus-visible:ring-border-focus-ring flex min-h-11 cursor-pointer list-none items-center gap-2 px-4 text-xs font-medium outline-none focus-visible:ring-2 focus-visible:ring-inset\">\n        <History className=\"text-text-secondary size-4\" />\n        Previous runs\n        <span className=\"text-text-secondary\">{records.length}</span>\n        <ChevronDown className=\"text-text-secondary ml-auto size-4 transition-transform group-open:rotate-180\" />\n      </summary>\n      <ol className=\"divide-separator-border border-separator-border divide-y border-t\">\n        {records.map((record, index) => (\n          <li key={record.id}>\n            <details className=\"group/run\">\n              <summary className=\"focus-visible:ring-border-focus-ring grid cursor-pointer list-none gap-1 px-4 py-3 outline-none focus-visible:ring-2 focus-visible:ring-inset sm:grid-cols-[2rem_1fr_auto_auto] sm:items-center sm:gap-3\">\n                <span className=\"text-text-secondary text-xs tabular-nums\">\n                  {String(index + 1).padStart(2, \"0\")}\n                </span>\n                <code className=\"text-text-primary min-w-0 truncate font-mono text-xs\">\n                  {record.code.split(\"\\n\")[0]}\n                </code>\n                <span\n                  className={cx(\n                    \"text-xs\",\n                    record.status === \"success\"\n                      ? \"text-green-700 dark:text-green-400\"\n                      : \"text-red-700 dark:text-red-400\"\n                  )}\n                >\n                  {record.status === \"success\" ? \"Succeeded\" : \"Failed\"}\n                </span>\n                <time className=\"text-text-secondary text-xs tabular-nums\">\n                  {record.timestamp}\n                </time>\n              </summary>\n              <div className=\"bg-background-secondary-default grid gap-3 px-4 py-3 lg:grid-cols-2\">\n                <div>\n                  <p className=\"text-text-secondary mb-2 text-xs font-medium\">\n                    Code\n                  </p>\n                  <pre className=\"text-text-primary overflow-auto font-mono text-xs leading-5 whitespace-pre-wrap\">\n                    {record.code}\n                  </pre>\n                </div>\n                <div>\n                  <p className=\"text-text-secondary mb-2 text-xs font-medium\">\n                    Output\n                  </p>\n                  {record.output.stdout && (\n                    <pre className=\"text-text-primary overflow-auto font-mono text-xs leading-5 whitespace-pre-wrap\">\n                      {record.output.stdout}\n                    </pre>\n                  )}\n                  {record.output.stderr && (\n                    <pre className=\"overflow-auto border-l-2 border-red-500 pl-3 font-mono text-xs leading-5 whitespace-pre-wrap text-red-700 dark:text-red-400\">\n                      {record.output.stderr}\n                    </pre>\n                  )}\n                  {!record.output.stdout && !record.output.stderr && (\n                    <p className=\"text-text-secondary text-xs\">\n                      No output returned.\n                    </p>\n                  )}\n                </div>\n                <div className=\"border-separator-border text-text-secondary flex flex-wrap gap-x-4 gap-y-1 border-t pt-3 text-xs tabular-nums lg:col-span-2\">\n                  <span>Run {record.id}</span>\n                  <span>Exit {record.output.exitCode}</span>\n                  <span>\n                    {record.output.executionTime ?? \"Runtime unavailable\"}\n                  </span>\n                  <span>\n                    {record.output.memoryUsage ?? \"Memory unavailable\"}\n                  </span>\n                </div>\n              </div>\n            </details>\n          </li>\n        ))}\n      </ol>\n    </details>\n  )\n}\n\nexport function CodeExecutor({\n  sandboxName = \"renewal-analysis\",\n  language = \"Python\",\n  code = sampleCode,\n  output = sampleOutput,\n  executionHistory = sampleHistory,\n  isExecuting = false,\n  sandboxLevel = \"sandboxed\",\n  onRun,\n  onStop,\n  onClear,\n  onCopyCode,\n  onEditCode,\n  className,\n}: AgentCodeExecutorProps) {\n  const [editing, setEditing] = React.useState(false)\n  const toggleEditing = () => {\n    const next = !editing\n    setEditing(next)\n    onEditCode?.(next)\n  }\n\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-3 border-b p-4\">\n        <div>\n          <h2 className=\"flex items-center gap-2 text-lg font-semibold\">\n            <Code2 className=\"text-text-secondary size-4\" />\n            Code execution\n          </h2>\n          <p className=\"text-text-secondary mt-1 text-xs\">\n            {sandboxName} · {language} · {sandboxLevel}\n          </p>\n        </div>\n        <div className=\"flex gap-2\">\n          {isExecuting ? (\n            <Button\n              variant=\"danger\"\n              size=\"small\"\n              leadingIcon={Square}\n              onClick={onStop}\n            >\n              Stop\n            </Button>\n          ) : (\n            <Button size=\"small\" leadingIcon={Play} onClick={onRun}>\n              Run code\n            </Button>\n          )}\n          <Button\n            variant=\"secondary\"\n            size=\"small\"\n            leadingIcon={Pencil}\n            onClick={toggleEditing}\n          >\n            {editing ? \"Finish editing\" : \"Edit\"}\n          </Button>\n        </div>\n      </header>\n      <div className=\"grid lg:grid-cols-2\">\n        <div className=\"border-separator-border border-b lg:border-r lg:border-b-0\">\n          <div className=\"bg-background-secondary-default text-text-secondary flex h-11 items-center justify-between px-3 text-xs\">\n            Code\n            <Button\n              variant=\"ghost\"\n              size=\"xs\"\n              iconOnly\n              leadingIcon={ClipboardCopy}\n              onClick={onCopyCode}\n              aria-label=\"Copy code\"\n            />\n          </div>\n          <pre\n            contentEditable={editing}\n            suppressContentEditableWarning\n            className=\"min-h-80 overflow-auto p-4 font-mono text-xs leading-6 whitespace-pre outline-none\"\n          >\n            {code}\n          </pre>\n        </div>\n        <div>\n          <div className=\"bg-background-secondary-default text-text-secondary flex h-11 items-center justify-between px-3 text-xs\">\n            Output\n            <span\n              className={\n                output.exitCode === 0\n                  ? \"text-green-700 dark:text-green-400\"\n                  : \"text-red-700 dark:text-red-400\"\n              }\n            >\n              {isExecuting ? \"Running\" : `Exit ${output.exitCode}`}\n            </span>\n          </div>\n          <div className=\"min-h-80 overflow-auto p-4 font-mono text-xs leading-6\">\n            {output.stdout && (\n              <pre className=\"whitespace-pre-wrap\">{output.stdout}</pre>\n            )}\n            {output.stderr && (\n              <pre className=\"mt-3 border-l-2 border-red-500 pl-3 whitespace-pre-wrap text-red-700 dark:text-red-400\">\n                {output.stderr}\n              </pre>\n            )}\n          </div>\n        </div>\n      </div>\n      <ExecutionHistory records={executionHistory} />\n      <footer className=\"border-separator-border flex items-center justify-between border-t p-4\">\n        <span className=\"text-text-secondary text-xs\">\n          {output.executionTime ?? \"Runtime unavailable\"} ·{\" \"}\n          {output.memoryUsage ?? \"Memory unavailable\"}\n        </span>\n        <Button\n          variant=\"ghost\"\n          size=\"xs\"\n          iconOnly\n          leadingIcon={Trash2}\n          onClick={onClear}\n          aria-label=\"Clear output\"\n        />\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-competitor-research",
      "type": "registry:block",
      "title": "Agent Competitor Research",
      "description": "agent competitor research",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-competitor-research.tsx",
          "target": "@components/agents-ui/agent-competitor-research.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { CompetitorResearch } from \"@/components/agents-ui/application/competitor-research/competitor-research\"\n\nexport type ResearchDepth = \"quick\" | \"standard\" | \"deep\"\nexport type ThreatLevel = \"low\" | \"medium\" | \"high\"\nexport interface Competitor {\n  name: string\n  description: string\n  category: string\n  strengths: string[]\n  weaknesses: string[]\n  threatLevel: ThreatLevel\n  marketPosition: string\n}\nexport interface ComparisonFeature {\n  feature: string\n  competitorScores: Record<string, boolean>\n}\nexport interface AgentCompetitorResearchProps {\n  query?: string\n  researchDepth?: ResearchDepth\n  competitors?: Competitor[]\n  comparisonFeatures?: ComparisonFeature[]\n  keyFindings?: string[]\n  sourcesCount?: number\n  lastUpdated?: string\n  isResearching?: boolean\n  onExport?: () => void\n  onDeepenResearch?: () => void\n  onRefresh?: () => void\n  onCompareFeature?: (feature: string) => void\n  className?: string\n}\nexport function AgentCompetitorResearch(props: AgentCompetitorResearchProps) {\n  return <CompetitorResearch {...props} />\n}\n"
        },
        {
          "path": "components/agents-ui/application/competitor-research/competitor-research.tsx",
          "target": "@components/agents-ui/application/competitor-research/competitor-research.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type {\n  AgentCompetitorResearchProps,\n  ComparisonFeature,\n  Competitor,\n} from \"@/components/agents-ui/agent-competitor-research\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Download, RefreshCw, Search, X } from \"lucide-react\"\n\nconst comps0: Competitor[] = [\n  {\n    name: \"Asana\",\n    description: \"Established work management platform.\",\n    category: \"Work management\",\n    strengths: [\"Enterprise adoption\", \"Workflow templates\"],\n    weaknesses: [\"Plan complexity\", \"Limited native actions\"],\n    threatLevel: \"high\",\n    marketPosition: \"Enterprise leader\",\n  },\n  {\n    name: \"Monday.com\",\n    description: \"Flexible visual work platform.\",\n    category: \"Work operating system\",\n    strengths: [\"Flexible configuration\", \"Strong onboarding\"],\n    weaknesses: [\"Configuration overhead\", \"Variable reporting depth\"],\n    threatLevel: \"high\",\n    marketPosition: \"Broad challenger\",\n  },\n]\nconst features0: ComparisonFeature[] = [\n  {\n    feature: \"Agent task execution\",\n    competitorScores: { Asana: false, \"Monday.com\": true },\n  },\n  {\n    feature: \"Enterprise permissions\",\n    competitorScores: { Asana: true, \"Monday.com\": true },\n  },\n  {\n    feature: \"Native CRM context\",\n    competitorScores: { Asana: false, \"Monday.com\": true },\n  },\n]\nexport function CompetitorResearch({\n  query = \"AI work management platforms\",\n  researchDepth = \"standard\",\n  competitors = comps0,\n  comparisonFeatures = features0,\n  keyFindings = [\n    \"Governance matters more than raw feature count.\",\n    \"CRM context is a clear differentiation opportunity.\",\n  ],\n  sourcesCount = 24,\n  lastUpdated = \"14:32\",\n  isResearching = false,\n  onExport,\n  onDeepenResearch,\n  onRefresh,\n  onCompareFeature,\n  className,\n}: AgentCompetitorResearchProps) {\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap justify-between gap-3 border-b p-5\">\n        <div>\n          <h2 className=\"flex items-center gap-2 text-lg font-semibold\">\n            <Search className=\"size-4\" />\n            Competitor research\n          </h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">{query}</p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={RefreshCw}\n            onClick={onRefresh}\n          >\n            Refresh\n          </Button>\n          <Button\n            variant=\"secondary\"\n            size=\"small\"\n            leadingIcon={Download}\n            onClick={onExport}\n          >\n            Export\n          </Button>\n        </div>\n      </header>\n      {isResearching && (\n        <p className=\"border-separator-border text-text-secondary border-b p-2 text-xs\">\n          Researching sources\n        </p>\n      )}\n      <div className=\"grid lg:grid-cols-[3fr_2fr]\">\n        <div className=\"p-5\">\n          {competitors.map((c) => (\n            <article\n              key={c.name}\n              className=\"border-separator-border border-b py-4 first:pt-0\"\n            >\n              <div className=\"flex justify-between\">\n                <h3 className=\"text-sm font-semibold\">{c.name}</h3>\n                <span className=\"text-text-secondary text-xs\">\n                  {c.threatLevel} threat\n                </span>\n              </div>\n              <p className=\"text-text-secondary text-xs\">\n                {c.category} · {c.marketPosition}\n              </p>\n              <p className=\"mt-2 text-sm\">{c.description}</p>\n              <div className=\"mt-3 grid grid-cols-2 gap-3 text-sm\">\n                <ul>\n                  {c.strengths.map((x) => (\n                    <li key={x} className=\"flex gap-2\">\n                      <Check className=\"mt-1 size-3 text-green-600\" />\n                      {x}\n                    </li>\n                  ))}\n                </ul>\n                <ul>\n                  {c.weaknesses.map((x) => (\n                    <li key={x} className=\"flex gap-2\">\n                      <X className=\"text-text-secondary mt-1 size-3\" />\n                      {x}\n                    </li>\n                  ))}\n                </ul>\n              </div>\n            </article>\n          ))}\n        </div>\n        <aside className=\"border-separator-border border-t p-5 lg:border-t-0 lg:border-l\">\n          <h3 className=\"text-sm font-medium\">Key findings</h3>\n          {keyFindings.map((x, i) => (\n            <p\n              key={x}\n              className=\"border-separator-border border-b py-3 text-sm\"\n            >\n              <span className=\"text-text-secondary mr-2 text-xs\">{i + 1}</span>\n              {x}\n            </p>\n          ))}\n          <Button\n            variant=\"secondary\"\n            size=\"small\"\n            className=\"mt-4\"\n            onClick={onDeepenResearch}\n          >\n            Deepen research\n          </Button>\n        </aside>\n      </div>\n      <div className=\"border-separator-border overflow-auto border-t p-5\">\n        <table className=\"w-full min-w-[560px] text-sm\">\n          <thead>\n            <tr>\n              <th className=\"p-2 text-left\">Capability</th>\n              {competitors.map((c) => (\n                <th key={c.name}>{c.name}</th>\n              ))}\n            </tr>\n          </thead>\n          <tbody>\n            {comparisonFeatures.map((f) => (\n              <tr\n                key={f.feature}\n                tabIndex={0}\n                onClick={() => onCompareFeature?.(f.feature)}\n                className=\"border-separator-border cursor-pointer border-t\"\n              >\n                <th className=\"p-3 text-left font-medium\">{f.feature}</th>\n                {competitors.map((c) => (\n                  <td key={c.name} className=\"text-center\">\n                    {f.competitorScores[c.name] ? \"Available\" : \"Not available\"}\n                  </td>\n                ))}\n              </tr>\n            ))}\n          </tbody>\n        </table>\n        <p className=\"text-text-secondary mt-4 text-xs\">\n          {competitors.length} competitors · {sourcesCount} sources ·{\" \"}\n          {researchDepth} depth · Updated {lastUpdated}\n        </p>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-context-meter",
      "type": "registry:block",
      "title": "Agent Context Meter",
      "description": "agent context meter",
      "dependencies": [
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-context-meter.tsx",
          "target": "@components/agents-ui/agent-context-meter.tsx",
          "type": "registry:component",
          "content": "\"use client\"\nexport { AgentContextMeter } from \"@/components/agents-ui/application/context-meter/context-meter\"\nexport type { AgentContextMeterProps, ContextSource, ContextSourceKind } from \"@/components/agents-ui/application/context-meter/context-meter\"\n"
        },
        {
          "path": "components/agents-ui/application/context-meter/context-meter.tsx",
          "target": "@components/agents-ui/application/context-meter/context-meter.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { ChevronDown } from \"lucide-react\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\n\n/**\n * Token-usage presentation adapted from Vercel AI Elements context (Apache-2.0).\n * https://github.com/vercel/ai-elements\n */\nexport type ContextSourceKind = \"system\" | \"conversation\" | \"tools\" | \"retrieval\" | \"output\" | \"other\"\n\nexport interface ContextSource {\n  id: string\n  label: string\n  tokens: number\n  kind?: ContextSourceKind\n}\n\nexport interface AgentContextMeterProps {\n  usedTokens: number\n  totalTokens: number\n  sources?: ContextSource[]\n  label?: string\n  showBreakdown?: boolean\n  className?: string\n}\n\nconst number = new Intl.NumberFormat(\"en-US\")\nconst compact = new Intl.NumberFormat(\"en-US\", { notation: \"compact\", maximumFractionDigits: 1 })\n\nexport function AgentContextMeter({ usedTokens, totalTokens, sources = [], label = \"Context window\", showBreakdown = true, className }: AgentContextMeterProps) {\n  const safeTotal = Math.max(0, totalTokens)\n  const safeUsed = Math.max(0, usedTokens)\n  const percent = safeTotal > 0 ? Math.min(100, (safeUsed / safeTotal) * 100) : 0\n  const remaining = Math.max(0, safeTotal - safeUsed)\n  const supplied = sources.reduce((sum, source) => sum + Math.max(0, source.tokens), 0)\n  const unallocated = Math.max(0, safeUsed - supplied)\n\n  return <section className={cx(\"overflow-hidden rounded-xl border border-separator-border bg-background-primary-default\", className)} aria-label={label}>\n    <header className=\"p-4\">\n      <div className=\"flex items-start justify-between gap-4\"><div><h2 className=\"text-sm font-medium text-text-primary\">{label}</h2><p className=\"mt-1 text-xs text-text-secondary\">{compact.format(safeUsed)} of {compact.format(safeTotal)} tokens used</p></div><span className=\"text-sm font-medium tabular-nums text-text-primary\">{percent.toFixed(percent < 10 ? 1 : 0)}%</span></div>\n      <div className=\"mt-3 h-1.5 overflow-hidden rounded-full bg-background-secondary-default\" role=\"progressbar\" aria-label={`${label} usage`} aria-valuemin={0} aria-valuemax={safeTotal} aria-valuenow={Math.min(safeUsed, safeTotal)}><span className=\"block h-full bg-accent-600 transition-[width] duration-150 motion-reduce:transition-none\" style={{ width: `${percent}%` }} /></div>\n      <div className=\"mt-2 flex justify-between text-xs tabular-nums text-text-secondary\"><span>{number.format(safeUsed)} used</span><span>{number.format(remaining)} remaining</span></div>\n    </header>\n    {showBreakdown && <details className=\"group border-t border-separator-border\"><summary className=\"flex min-h-11 cursor-pointer list-none items-center gap-2 px-4 text-xs font-medium text-text-primary outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-border-focus-ring\">Source breakdown<span className=\"text-text-secondary\">{sources.length + (unallocated > 0 ? 1 : 0)}</span><ChevronDown className=\"ml-auto size-4 text-text-secondary transition-transform group-open:rotate-180\" /></summary><div className=\"divide-y divide-separator-border border-t border-separator-border px-4\">{sources.map((source) => <div key={source.id} className=\"grid grid-cols-[1fr_auto] gap-3 py-2.5 text-xs\"><span className=\"min-w-0\"><span className=\"block truncate text-text-primary\">{source.label}</span>{source.kind && <span className=\"mt-0.5 block capitalize text-text-secondary\">{source.kind}</span>}</span><span className=\"tabular-nums text-text-secondary\">{number.format(Math.max(0, source.tokens))}</span></div>)}{unallocated > 0 && <div className=\"grid grid-cols-[1fr_auto] gap-3 py-2.5 text-xs\"><span className=\"text-text-primary\">Other context</span><span className=\"tabular-nums text-text-secondary\">{number.format(unallocated)}</span></div>}{sources.length === 0 && unallocated === 0 && <p className=\"py-3 text-xs text-text-secondary\">No source breakdown supplied.</p>}</div></details>}\n  </section>\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/agents-ui/application/context-meter/LICENSE",
          "target": "@components/agents-ui/application/context-meter/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/agents-ui/application/context-meter/NOTICE.md",
          "target": "@components/agents-ui/application/context-meter/NOTICE.md",
          "type": "registry:file",
          "content": "# Source notice\n\nThis component is an independent BoardUI implementation informed by the public context-window concepts and token-breakdown behavior of Vercel AI Elements.\n\nNo AI SDK integration, token-cost dependency, hover-card implementation, compound-component code, or source code was copied. The upstream Apache-2.0 license notice is included because its public interaction model materially influenced this component.\n"
        },
        {
          "path": "components/agents-ui/application/context-meter/SOURCE.json",
          "target": "@components/agents-ui/application/context-meter/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements context\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"revision\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"referenceFiles\": [\"packages/elements/src/context.tsx\", \"skills/ai-elements/references/context.md\"],\n  \"relationship\": \"Independent BoardUI implementation informed by public context usage and token-breakdown concepts; upstream source code was not copied.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-data-analysis",
      "type": "registry:block",
      "title": "Agent Data Analysis",
      "description": "agent data analysis",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-data-analysis.tsx",
          "target": "@components/agents-ui/agent-data-analysis.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { DataAnalysis } from \"@/components/agents-ui/application/data-analysis/data-analysis\"\n\nexport interface DataMetric {\n  label: string\n  value: string\n  change: string\n  changeDirection: \"up\" | \"down\" | \"neutral\"\n}\nexport interface DataPreview {\n  headers: string[]\n  rows: string[][]\n}\nexport interface DataInsight {\n  id: string\n  title: string\n  description: string\n  confidence: number\n  category: \"trend\" | \"anomaly\" | \"correlation\" | \"recommendation\"\n}\nexport interface DistributionBar {\n  label: string\n  value: number\n  maxValue: number\n  color: string\n}\nexport interface AgentDataAnalysisProps {\n  datasetName?: string\n  description?: string\n  rowCount?: number\n  columnCount?: number\n  metrics?: DataMetric[]\n  dataPreview?: DataPreview\n  insights?: DataInsight[]\n  distribution?: DistributionBar[]\n  isAnalyzing?: boolean\n  onExport?: () => void\n  onDeeperAnalysis?: () => void\n  onAskFollowUp?: () => void\n  onDownload?: () => void\n  className?: string\n}\nexport function AgentDataAnalysis(props: AgentDataAnalysisProps) {\n  return <DataAnalysis {...props} />\n}\n"
        },
        {
          "path": "components/agents-ui/application/data-analysis/data-analysis.tsx",
          "target": "@components/agents-ui/application/data-analysis/data-analysis.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type {\n  AgentDataAnalysisProps,\n  DataInsight,\n  DataMetric,\n  DataPreview,\n  DistributionBar,\n} from \"@/components/agents-ui/agent-data-analysis\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  AlertTriangle,\n  Download,\n  GitBranch,\n  Lightbulb,\n  MessageSquare,\n  Search,\n  TrendingUp,\n} from \"lucide-react\"\n\nconst metrics0: DataMetric[] = [\n  {\n    label: \"At-risk value\",\n    value: \"$1.84M\",\n    change: \"+12% QoQ\",\n    changeDirection: \"up\",\n  },\n  {\n    label: \"Accounts at risk\",\n    value: \"12\",\n    change: \"+3 QoQ\",\n    changeDirection: \"up\",\n  },\n  {\n    label: \"Executive action\",\n    value: \"4\",\n    change: \"This week\",\n    changeDirection: \"neutral\",\n  },\n]\nconst preview0: DataPreview = {\n  headers: [\"Account\", \"Renewal\", \"Health\", \"Owner\"],\n  rows: [\n    [\"Northwind\", \"$520K\", \"At risk\", \"Morgan Lee\"],\n    [\"Acme Health\", \"$410K\", \"At risk\", \"Jordan Kim\"],\n    [\"Contour Labs\", \"$360K\", \"At risk\", \"Priya Shah\"],\n  ],\n}\nconst insights0: DataInsight[] = [\n  {\n    id: \"1\",\n    title: \"Sponsor coverage is the strongest risk signal\",\n    description: \"Seven accounts do not have a confirmed executive sponsor.\",\n    confidence: 0.93,\n    category: \"correlation\",\n  },\n  {\n    id: \"2\",\n    title: \"Four accounts need action this week\",\n    description:\n      \"Their value and declining adoption exceed the escalation threshold.\",\n    confidence: 0.89,\n    category: \"recommendation\",\n  },\n]\nconst dist0: DistributionBar[] = [\n  { label: \"Product adoption\", value: 38, maxValue: 100, color: \"#2563eb\" },\n  { label: \"Sponsor coverage\", value: 27, maxValue: 100, color: \"#64748b\" },\n  { label: \"Support pressure\", value: 21, maxValue: 100, color: \"#d97706\" },\n]\nconst icons = {\n  trend: TrendingUp,\n  anomaly: AlertTriangle,\n  correlation: GitBranch,\n  recommendation: Lightbulb,\n}\nconst directionLabel: Record<DataMetric[\"changeDirection\"], string> = {\n  up: \"Up\",\n  down: \"Down\",\n  neutral: \"No change\",\n}\nexport function DataAnalysis({\n  datasetName = \"renewals_q3.csv\",\n  description = \"Renewal forecast joined with account health and CRM notes.\",\n  rowCount = 842,\n  columnCount = 18,\n  metrics = metrics0,\n  dataPreview = preview0,\n  insights = insights0,\n  distribution = dist0,\n  isAnalyzing = false,\n  onExport,\n  onDeeperAnalysis,\n  onAskFollowUp,\n  onDownload,\n  className,\n}: AgentDataAnalysisProps) {\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap justify-between gap-3 border-b p-5\">\n        <div>\n          <h2 className=\"text-lg font-semibold\">{datasetName}</h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">{description}</p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={Download}\n            onClick={onDownload}\n          >\n            Download\n          </Button>\n          <Button variant=\"secondary\" size=\"small\" onClick={onExport}>\n            Export report\n          </Button>\n        </div>\n      </header>\n      {isAnalyzing && (\n        <p className=\"border-separator-border text-text-secondary border-b px-5 py-2 text-xs\">\n          Analyzing dataset\n        </p>\n      )}\n      <div className=\"divide-separator-border border-separator-border grid divide-y border-b sm:grid-cols-3 sm:divide-x sm:divide-y-0\">\n        {metrics.map((x) => (\n          <div key={x.label} className=\"p-4\">\n            <p className=\"text-text-secondary text-xs\">{x.label}</p>\n            <p className=\"mt-1 text-xl font-semibold\">\n              {x.value}\n              <span\n                className=\"text-text-secondary ml-2 text-xs font-normal\"\n                data-direction={x.changeDirection}\n              >\n                {x.change} · {directionLabel[x.changeDirection]}\n              </span>\n            </p>\n          </div>\n        ))}\n      </div>\n      <div className=\"grid lg:grid-cols-[3fr_2fr]\">\n        <div className=\"p-5\">\n          <h3 className=\"mb-3 text-sm font-medium\">Account preview</h3>\n          <div className=\"border-separator-border overflow-auto rounded-lg border\">\n            <table className=\"w-full min-w-[520px] text-left text-sm\">\n              <thead className=\"bg-background-secondary-default text-text-secondary text-xs\">\n                <tr>\n                  {dataPreview.headers.map((x) => (\n                    <th key={x} className=\"p-3\">\n                      {x}\n                    </th>\n                  ))}\n                </tr>\n              </thead>\n              <tbody>\n                {dataPreview.rows.map((r, i) => (\n                  <tr key={i} className=\"border-separator-border border-t\">\n                    {r.map((x, j) => (\n                      <td key={j} className=\"p-3\">\n                        {x}\n                      </td>\n                    ))}\n                  </tr>\n                ))}\n              </tbody>\n            </table>\n          </div>\n        </div>\n        <aside className=\"border-separator-border border-t p-5 lg:border-t-0 lg:border-l\">\n          <h3 className=\"text-sm font-medium\">Risk drivers</h3>\n          {distribution.map((x) => {\n            const p = x.maxValue ? (x.value / x.maxValue) * 100 : 0\n            return (\n              <div key={x.label} className=\"mt-4\">\n                <div className=\"flex justify-between text-xs\">\n                  <span>{x.label}</span>\n                  <span>{Math.round(p)}%</span>\n                </div>\n                <div className=\"bg-background-secondary-default mt-1 h-1.5\">\n                  <div\n                    className=\"h-full\"\n                    style={{ width: `${p}%`, backgroundColor: x.color }}\n                  />\n                </div>\n              </div>\n            )\n          })}\n        </aside>\n      </div>\n      <div className=\"border-separator-border border-t p-5\">\n        <div className=\"flex justify-between\">\n          <h3 className=\"text-sm font-medium\">Findings</h3>\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={Search}\n            onClick={onDeeperAnalysis}\n          >\n            Deeper analysis\n          </Button>\n        </div>\n        {insights.map((x) => {\n          const I = icons[x.category]\n          return (\n            <article\n              key={x.id}\n              className=\"border-separator-border grid grid-cols-[20px_1fr_auto] gap-3 border-b py-3\"\n            >\n              <I className=\"text-text-secondary size-4\" />\n              <div>\n                <h4 className=\"text-sm font-medium\">{x.title}</h4>\n                <p className=\"text-text-secondary mt-1 text-sm\">\n                  {x.description}\n                </p>\n              </div>\n              <span className=\"text-text-secondary text-xs\">\n                {Math.round(x.confidence * 100)}%\n              </span>\n            </article>\n          )\n        })}\n        <div className=\"mt-4 flex justify-between\">\n          <span className=\"text-text-secondary text-xs\">\n            {rowCount} rows · {columnCount} columns\n          </span>\n          <Button\n            variant=\"secondary\"\n            size=\"small\"\n            leadingIcon={MessageSquare}\n            onClick={onAskFollowUp}\n          >\n            Ask follow-up\n          </Button>\n        </div>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-doc-scanner",
      "type": "registry:block",
      "title": "Agent Doc Scanner",
      "description": "agent doc scanner",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-doc-scanner.tsx",
          "target": "@components/agents-ui/agent-doc-scanner.tsx",
          "type": "registry:component",
          "content": "export { AgentDocScanner } from \"./application/document-scanner/document-scanner\"\nexport type {\n  AgentDocScannerProps,\n  DocumentInfo,\n  ExtractedSection,\n} from \"./application/document-scanner/document-scanner\"\n"
        },
        {
          "path": "components/agents-ui/application/document-scanner/document-scanner.tsx",
          "target": "@components/agents-ui/application/document-scanner/document-scanner.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n/* eslint-disable @next/next/no-img-element */\n/* Extracted payloads are intentionally provider-defined. */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport {\n  Tab,\n  TabList,\n  TabPanel,\n  Tabs,\n} from \"@/components/boardui/base/tabs/tabs\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  ChevronLeft,\n  ChevronRight,\n  Copy,\n  File,\n  FileSpreadsheet,\n  FileText,\n  Highlighter,\n  RefreshCw,\n  RotateCw,\n  Upload,\n  ZoomIn,\n  ZoomOut,\n} from \"lucide-react\"\nimport { useId, useState } from \"react\"\n\nexport interface ExtractedSection {\n  id: string\n  type: \"text\" | \"table\" | \"image\" | \"metadata\"\n  title: string\n  content: any\n  confidence?: number\n  page?: number\n}\nexport interface DocumentInfo {\n  name: string\n  type: \"pdf\" | \"csv\" | \"docx\" | \"xlsx\" | \"txt\"\n  size: number\n  pages?: number\n  uploadedAt?: string\n}\nexport interface AgentDocScannerProps {\n  document?: DocumentInfo\n  extractedSections?: ExtractedSection[]\n  currentPage?: number\n  totalPages?: number\n  isProcessing?: boolean\n  uploadProgress?: number\n  previewUrl?: string\n  onFileUpload?: (file: File) => void\n  onExtract?: (sectionId: string) => void\n  onExport?: (format?: \"json\" | \"csv\" | \"txt\") => void\n  onPageChange?: (page: number) => void\n  onZoomIn?: () => void\n  onZoomOut?: () => void\n  onRotate?: () => void\n  onCopySection?: (sectionId: string) => void\n  onHighlightSection?: (sectionId: string) => void\n  showBottomActions?: boolean\n  className?: string\n  timestamp?: string\n}\nconst size = (bytes: number) =>\n  bytes < 1024\n    ? `${bytes} B`\n    : bytes < 1048576\n      ? `${(bytes / 1024).toFixed(1)} KB`\n      : `${(bytes / 1048576).toFixed(1)} MB`\nfunction DocumentIcon({\n  type,\n  className,\n}: {\n  type: DocumentInfo[\"type\"]\n  className?: string\n}) {\n  return type === \"pdf\" ? (\n    <FileText className={className} />\n  ) : type === \"csv\" || type === \"xlsx\" ? (\n    <FileSpreadsheet className={className} />\n  ) : (\n    <File className={className} />\n  )\n}\nfunction Content({ section }: { section: ExtractedSection }) {\n  if (\n    section.type === \"metadata\" &&\n    section.content &&\n    typeof section.content === \"object\"\n  )\n    return (\n      <dl className=\"grid gap-2 sm:grid-cols-2\">\n        {Object.entries(section.content).map(([key, value]) => (\n          <div\n            key={key}\n            className=\"bg-background-secondary-default flex justify-between gap-3 rounded-sm px-3 py-2\"\n          >\n            <dt className=\"text-caption-1-regular text-text-secondary capitalize\">\n              {key.replace(/([A-Z])/g, \" $1\")}\n            </dt>\n            <dd className=\"text-caption-1-medium\">{String(value)}</dd>\n          </div>\n        ))}\n      </dl>\n    )\n  if (\n    section.type === \"table\" &&\n    Array.isArray(section.content) &&\n    section.content.length > 0\n  ) {\n    const keys = Object.keys(section.content[0])\n    return (\n      <div className=\"border-separator-border overflow-x-auto rounded-lg border\">\n        <table className=\"text-body-2-regular w-full text-left\">\n          <thead className=\"bg-background-secondary-default\">\n            <tr>\n              {keys.map((key) => (\n                <th key={key} className=\"px-3 py-2 font-medium capitalize\">\n                  {key}\n                </th>\n              ))}\n            </tr>\n          </thead>\n          <tbody className=\"divide-separator-border divide-y\">\n            {section.content.map(\n              (row: Record<string, unknown>, index: number) => (\n                <tr key={index}>\n                  {keys.map((key) => (\n                    <td key={key} className=\"px-3 py-2\">\n                      {String(row[key] ?? \"\")}\n                    </td>\n                  ))}\n                </tr>\n              )\n            )}\n          </tbody>\n        </table>\n      </div>\n    )\n  }\n  return (\n    <p className=\"text-body-2-regular leading-5 whitespace-pre-wrap\">\n      {String(section.content ?? \"\")}\n    </p>\n  )\n}\nexport function AgentDocScanner({\n  document,\n  extractedSections = [],\n  currentPage = 1,\n  totalPages = 1,\n  isProcessing = false,\n  uploadProgress = 0,\n  previewUrl,\n  onFileUpload,\n  onExtract,\n  onExport,\n  onPageChange,\n  onZoomIn,\n  onZoomOut,\n  onRotate,\n  onCopySection,\n  onHighlightSection,\n  showBottomActions = true,\n  className,\n  timestamp = \"2:34 PM\",\n}: AgentDocScannerProps) {\n  const [dragging, setDragging] = useState(false)\n  const inputId = useId()\n  if (!document)\n    return (\n      <section\n        className={cx(\n          \"border-separator-border bg-background-primary-default rounded-2xl border p-4\",\n          className\n        )}\n      >\n        <label\n          htmlFor={inputId}\n          onDragEnter={(event) => {\n            event.preventDefault()\n            setDragging(true)\n          }}\n          onDragOver={(event) => event.preventDefault()}\n          onDragLeave={() => setDragging(false)}\n          onDrop={(event) => {\n            event.preventDefault()\n            setDragging(false)\n            const file = event.dataTransfer.files[0]\n            if (file) onFileUpload?.(file)\n          }}\n          className={cx(\n            \"border-separator-border grid min-h-64 cursor-pointer place-items-center rounded-lg border border-dashed p-8 text-center\",\n            dragging &&\n              \"bg-background-secondary-default ring-border-focus-ring ring-2\"\n          )}\n        >\n          <div>\n            <Upload className=\"text-text-secondary mx-auto size-6\" />\n            <h3 className=\"text-headline-semibold mt-3\">Upload a document</h3>\n            <p className=\"text-body-2-regular text-text-secondary mt-1\">\n              PDF, CSV, DOCX, XLSX, or TXT up to 10 MB\n            </p>\n            <span className=\"rounded-2lg border-border-button-default text-body-medium mt-4 inline-flex min-h-9 items-center border px-3\">\n              Choose file\n            </span>\n          </div>\n          <input\n            id={inputId}\n            type=\"file\"\n            className=\"sr-only\"\n            accept=\".pdf,.csv,.docx,.xlsx,.txt\"\n            onChange={(event) => {\n              const file = event.target.files?.[0]\n              if (file) onFileUpload?.(file)\n            }}\n          />\n        </label>\n      </section>\n    )\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3\">\n        <div className=\"flex min-w-0 items-center gap-3\">\n          <DocumentIcon\n            type={document.type}\n            className=\"text-text-secondary size-5\"\n          />\n          <div className=\"min-w-0\">\n            <h3 className=\"text-headline-semibold truncate\">{document.name}</h3>\n            <p className=\"text-caption-1-regular text-text-secondary\">\n              {size(document.size)} | {document.pages ?? totalPages} pages |{\" \"}\n              {timestamp}\n            </p>\n          </div>\n        </div>\n        <select\n          aria-label=\"Export format\"\n          defaultValue=\"\"\n          onChange={(event) => {\n            if (event.target.value)\n              onExport?.(event.target.value as \"json\" | \"csv\" | \"txt\")\n            event.target.value = \"\"\n          }}\n          className=\"rounded-2lg bg-background-tertiary-default text-body-medium focus:ring-border-button-active h-9 px-3 ring-2 ring-transparent outline-none\"\n        >\n          <option value=\"\" disabled>\n            Export\n          </option>\n          <option value=\"json\">JSON</option>\n          <option value=\"csv\">CSV</option>\n          <option value=\"txt\">Text</option>\n        </select>\n      </header>\n      {isProcessing && (\n        <div className=\"bg-background-secondary-default h-0.5\">\n          <span\n            className=\"bg-accent-600 block h-full\"\n            style={{ width: `${Math.max(4, Math.min(100, uploadProgress))}%` }}\n          />\n        </div>\n      )}\n      <Tabs defaultSelectedKey=\"preview\">\n        <TabList className=\"px-3\">\n          <Tab id=\"preview\">Document</Tab>\n          <Tab id=\"extracted\">Extracted data</Tab>\n        </TabList>\n        <TabPanel id=\"preview\">\n          <div className=\"border-separator-border flex items-center gap-1 border-b px-3 py-2\">\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={ChevronLeft}\n              aria-label=\"Previous page\"\n              disabled={currentPage <= 1}\n              onClick={() => onPageChange?.(Math.max(1, currentPage - 1))}\n            />\n            <span className=\"text-caption-1-regular text-text-secondary px-2 tabular-nums\">\n              Page {currentPage} of {totalPages}\n            </span>\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={ChevronRight}\n              aria-label=\"Next page\"\n              disabled={currentPage >= totalPages}\n              onClick={() =>\n                onPageChange?.(Math.min(totalPages, currentPage + 1))\n              }\n            />\n            <span className=\"bg-separator-border mx-1 h-4 w-px\" />\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={ZoomOut}\n              aria-label=\"Zoom out\"\n              onClick={onZoomOut}\n            />\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={ZoomIn}\n              aria-label=\"Zoom in\"\n              onClick={onZoomIn}\n            />\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={RotateCw}\n              aria-label=\"Rotate\"\n              onClick={onRotate}\n            />\n          </div>\n          <div className=\"bg-background-secondary-default grid min-h-96 place-items-center p-4\">\n            {previewUrl ? (\n              document.type === \"pdf\" ? (\n                <iframe\n                  src={previewUrl}\n                  title={document.name}\n                  className=\"h-[520px] w-full rounded-lg bg-white\"\n                />\n              ) : (\n                <img\n                  src={previewUrl}\n                  alt={`Preview of ${document.name}`}\n                  className=\"max-h-[520px] max-w-full rounded-lg object-contain\"\n                />\n              )\n            ) : (\n              <div className=\"text-text-secondary text-center\">\n                <DocumentIcon type={document.type} className=\"mx-auto size-8\" />\n                <p className=\"text-body-2-regular mt-2\">Preview unavailable</p>\n              </div>\n            )}\n          </div>\n        </TabPanel>\n        <TabPanel id=\"extracted\">\n          <div className=\"divide-separator-border divide-y\">\n            {extractedSections.map((section) => (\n              <article key={section.id} className=\"p-4\">\n                <header className=\"mb-3 flex items-center gap-2\">\n                  <h4 className=\"text-body-medium min-w-0 flex-1\">\n                    {section.title}\n                  </h4>\n                  {section.page && (\n                    <span className=\"text-caption-1-regular text-text-secondary\">\n                      Page {section.page}\n                    </span>\n                  )}\n                  {section.confidence !== undefined && (\n                    <span className=\"text-caption-1-regular text-text-secondary tabular-nums\">\n                      {Math.round(section.confidence * 100)}%\n                    </span>\n                  )}\n                  {onCopySection && (\n                    <Button\n                      size=\"small\"\n                      variant=\"ghost\"\n                      iconOnly\n                      leadingIcon={Copy}\n                      aria-label={`Copy ${section.title}`}\n                      onClick={() => onCopySection(section.id)}\n                    />\n                  )}\n                  {onHighlightSection && (\n                    <Button\n                      size=\"small\"\n                      variant=\"ghost\"\n                      iconOnly\n                      leadingIcon={Highlighter}\n                      aria-label={`Highlight ${section.title}`}\n                      onClick={() => onHighlightSection(section.id)}\n                    />\n                  )}\n                </header>\n                <Content section={section} />\n              </article>\n            ))}\n            {extractedSections.length === 0 && (\n              <p className=\"text-body-2-regular text-text-secondary p-8 text-center\">\n                No extracted content yet.\n              </p>\n            )}\n          </div>\n        </TabPanel>\n      </Tabs>\n      {showBottomActions && (\n        <footer className=\"border-separator-border flex items-center justify-between gap-2 border-t px-4 py-2.5\">\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {extractedSections.length} sections |{\" \"}\n            {isProcessing ? \"Processing\" : \"Ready\"}\n          </p>\n          {onExtract && (\n            <Button\n              size=\"small\"\n              variant=\"secondary\"\n              leadingIcon={RefreshCw}\n              onClick={() => onExtract(extractedSections[0]?.id ?? \"document\")}\n            >\n              Extract again\n            </Button>\n          )}\n        </footer>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/tabs/tabs.tsx",
          "target": "@components/boardui/base/tabs/tabs.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type { ComponentType, ReactNode, Ref } from \"react\";\nimport {\n  Tab as AriaTab,\n  TabList as AriaTabList,\n  TabPanel as AriaTabPanel,\n  Tabs as AriaTabs,\n} from \"react-aria-components\";\nimport type {\n  TabListProps as AriaTabListProps,\n  TabPanelProps as AriaTabPanelProps,\n  TabProps as AriaTabProps,\n  TabsProps as AriaTabsProps,\n} from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Figma source: Board UI → Tab (node 3793:2942).\n *\n * Underline tabs. The tab strip sits on a 1px border/button/default baseline;\n * the active tab paints a 2px foreground underline over it.\n *   tab       px 10, py 8, gap 10 (label ↔ count), Body 1 (14/20)\n *     active     text/primary, Medium weight, 2px foreground underline\n *     inactive   text/primary, Regular weight, transparent underline\n *   count     radius/sm, px 4, py 1, Caption 1/Medium (12/16)\n *     active     selected count background, text/primary\n *     inactive   bg black/10 @ 50% opacity, text/primary\n *   icon      optional 16px leading glyph, inherits the label color\n *\n * Built on react-aria Tabs: roving-tabindex arrow-key navigation, automatic\n * activation, and TabList/TabPanel association.\n */\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\nexport interface TabsProps extends AriaTabsProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tabs({ className, ref, ...props }: TabsProps) {\n  return (\n    <AriaTabs\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"flex w-full flex-col gap-4\",\n          state.orientation === \"vertical\" && \"flex-row\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n\nexport interface TabListProps<T extends object> extends AriaTabListProps<T> {\n  ref?: Ref<HTMLDivElement>;\n}\n\ntype Underline = { left: number; width: number };\n\nexport function TabList<T extends object>({ className, ref, ...props }: TabListProps<T>) {\n  const wrapperRef = useRef<HTMLDivElement>(null);\n  const [underline, setUnderline] = useState<Underline | null>(null);\n\n  useIsomorphicLayoutEffect(() => {\n    const el = wrapperRef.current;\n    if (!el) return;\n    const measure = () => {\n      const selected = el.querySelector<HTMLElement>(\"[role='tab'][data-selected]\");\n      if (selected) {\n        setUnderline({ left: selected.offsetLeft, width: selected.offsetWidth });\n      }\n    };\n    measure();\n    // Re-measure when selection flips (data-selected toggles) or size changes.\n    const mo = new MutationObserver(measure);\n    mo.observe(el, { attributes: true, subtree: true, attributeFilter: [\"data-selected\"] });\n    const ro = new ResizeObserver(measure);\n    ro.observe(el);\n    return () => {\n      mo.disconnect();\n      ro.disconnect();\n    };\n  }, []);\n\n  return (\n    <div ref={wrapperRef} className=\"relative w-full\">\n      <AriaTabList\n        ref={ref}\n        {...props}\n        className={(state) =>\n          cx(\n            \"flex w-full items-center gap-1 border-b border-separator-border\",\n            typeof className === \"function\" ? className(state) : className,\n          )\n        }\n      />\n      {underline && (\n        <span\n          aria-hidden\n          className=\"pointer-events-none absolute bottom-0 left-0 h-0.5 bg-text-primary transition-[transform,width] duration-200 ease\"\n          style={{\n            transform: `translateX(${underline.left}px)`,\n            width: underline.width,\n          }}\n        />\n      )}\n    </div>\n  );\n}\n\nexport interface TabProps extends Omit<AriaTabProps, \"children\"> {\n  children?: ReactNode;\n  /** Optional leading icon (16px). Inherits the label color. */\n  icon?: IconComponent;\n  /** Optional trailing count badge. */\n  count?: ReactNode;\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tab({ className, children, icon: Icon, count, ref, ...props }: TabProps) {\n  return (\n    <AriaTab\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"relative inline-flex cursor-pointer items-center gap-2.5 px-2.5 py-2 whitespace-nowrap\",\n          \"outline-none transition-colors duration-150 ease\",\n          \"focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          state.isDisabled && \"cursor-not-allowed opacity-50\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    >\n      {({ isSelected }) => (\n        <>\n          <span\n            className={cx(\n              \"inline-flex items-center gap-1.5\",\n              isSelected\n                ? \"text-body-medium text-text-primary\"\n                : \"text-body-regular text-text-primary\",\n            )}\n          >\n            {Icon && <Icon className=\"size-4 shrink-0\" aria-hidden />}\n            {children}\n          </span>\n          {count != null && (\n            <span\n              className={cx(\n                \"inline-flex items-center justify-center rounded-sm px-1 py-px text-caption-1-medium whitespace-nowrap\",\n                isSelected\n                  ? \"bg-tab-count-selected-background text-text-primary\"\n                  : \"bg-black/10 text-text-primary opacity-50\",\n              )}\n            >\n              {count}\n            </span>\n          )}\n        </>\n      )}\n    </AriaTab>\n  );\n}\n\nexport interface TabPanelProps extends AriaTabPanelProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function TabPanel({ className, ref, ...props }: TabPanelProps) {\n  return (\n    <AriaTabPanel\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"outline-none focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-evaluator",
      "type": "registry:block",
      "title": "Agent Evaluator",
      "description": "agent evaluator",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-evaluator.tsx",
          "target": "@components/agents-ui/agent-evaluator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Evaluator } from \"@/components/agents-ui/application/evaluator/evaluator\"\n\nexport interface EvalCriterion {\n  label: string\n  score: number\n  maxScore: number\n}\nexport interface EvalIteration {\n  id: string\n  number: number\n  output: string\n  score: number\n  feedback: string\n  criteria: EvalCriterion[]\n  status: \"passed\" | \"failed\" | \"in-progress\"\n}\nexport interface AgentEvaluatorProps {\n  taskDescription?: string\n  iterations?: EvalIteration[]\n  currentIteration?: number\n  qualityThreshold?: number\n  maxIterations?: number\n  isRunning?: boolean\n  className?: string\n  onRunNext?: () => void\n  onAccept?: () => void\n  onReset?: () => void\n  onAdjustThreshold?: (value: number) => void\n}\nexport function AgentEvaluator(props: AgentEvaluatorProps) {\n  return <Evaluator {...props} />\n}\n"
        },
        {
          "path": "components/agents-ui/application/evaluator/evaluator.tsx",
          "target": "@components/agents-ui/application/evaluator/evaluator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type {\n  AgentEvaluatorProps,\n  EvalIteration,\n} from \"@/components/agents-ui/agent-evaluator\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Slider } from \"@/components/boardui/base/slider/slider\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { ChevronDown, Play, RotateCcw } from \"lucide-react\"\nimport * as React from \"react\"\n\nconst data0: EvalIteration[] = [\n  {\n    id: \"1\",\n    number: 1,\n    output: \"Prepare a generic follow-up list.\",\n    score: 45,\n    feedback: \"The result does not prioritize renewal value.\",\n    criteria: [\n      { label: \"Evidence\", score: 52, maxScore: 100 },\n      { label: \"Clarity\", score: 43, maxScore: 100 },\n    ],\n    status: \"failed\",\n  },\n  {\n    id: \"2\",\n    number: 2,\n    output: \"Prioritize accounts using value and account health.\",\n    score: 72,\n    feedback: \"Add sponsor coverage and specify this week's actions.\",\n    criteria: [\n      { label: \"Evidence\", score: 76, maxScore: 100 },\n      { label: \"Clarity\", score: 68, maxScore: 100 },\n    ],\n    status: \"failed\",\n  },\n  {\n    id: \"3\",\n    number: 3,\n    output: \"Four accounts need executive outreach this week.\",\n    score: 91,\n    feedback: \"Specific, evidence-led, and actionable.\",\n    criteria: [\n      { label: \"Evidence\", score: 94, maxScore: 100 },\n      { label: \"Clarity\", score: 88, maxScore: 100 },\n    ],\n    status: \"passed\",\n  },\n]\nexport function Evaluator({\n  taskDescription = \"Evaluate the renewal briefing for evidence and clarity.\",\n  iterations = data0,\n  currentIteration,\n  qualityThreshold = 85,\n  maxIterations = 5,\n  isRunning = false,\n  onRunNext,\n  onAccept,\n  onReset,\n  onAdjustThreshold,\n  className,\n}: AgentEvaluatorProps) {\n  const latest = iterations.at(-1)\n  const [open, setOpen] = React.useState(latest?.id)\n  const passed = !!latest && latest.score >= qualityThreshold\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap justify-between gap-3 border-b p-5\">\n        <div>\n          <h2 className=\"text-lg font-semibold\">Evaluation results</h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">{taskDescription}</p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={RotateCcw}\n            onClick={onReset}\n          >\n            Reset\n          </Button>\n          {passed ? (\n            <Button size=\"small\" onClick={onAccept}>\n              Accept result\n            </Button>\n          ) : (\n            <Button\n              size=\"small\"\n              leadingIcon={Play}\n              onClick={onRunNext}\n              disabled={isRunning}\n            >\n              Run next\n            </Button>\n          )}\n        </div>\n      </header>\n      {latest ? (\n        <div className=\"border-separator-border grid gap-5 border-b p-5 lg:grid-cols-[220px_1fr]\">\n          <div>\n            <p className=\"text-text-secondary text-xs\">Latest score</p>\n            <p className=\"mt-1 text-4xl font-semibold tabular-nums\">\n              {latest.score}\n              <span className=\"text-text-secondary text-sm font-normal\">\n                {\" \"}\n                / 100\n              </span>\n            </p>\n            <Slider\n              value={qualityThreshold}\n              minValue={0}\n              maxValue={100}\n              showTooltip={false}\n              label=\"Quality threshold\"\n              onChange={onAdjustThreshold}\n              className=\"mt-4\"\n            />\n          </div>\n          <div>\n            <p className=\"text-base font-medium\">{latest.output}</p>\n            <p className=\"text-text-secondary mt-2 text-sm leading-6\">\n              {latest.feedback}\n            </p>\n            {latest.criteria.map((c) => (\n              <div key={c.label} className=\"mt-3\">\n                <div className=\"flex justify-between text-xs\">\n                  <span>{c.label}</span>\n                  <span>\n                    {c.score}/{c.maxScore}\n                  </span>\n                </div>\n                <div className=\"bg-background-secondary-default mt-1 h-1\">\n                  <div\n                    className=\"bg-accent-600 h-full\"\n                    style={{ width: `${(c.score / c.maxScore) * 100}%` }}\n                  />\n                </div>\n              </div>\n            ))}\n          </div>\n        </div>\n      ) : (\n        <p className=\"text-text-secondary p-8 text-center text-sm\">\n          No evaluation results yet.\n        </p>\n      )}\n      <div className=\"p-5\">\n        <h3 className=\"text-sm font-medium\">Iteration history</h3>\n        <div className=\"divide-separator-border border-separator-border mt-3 divide-y border-y\">\n          {iterations.map((x) => (\n            <div key={x.id}>\n              <button\n                className=\"flex min-h-14 w-full items-center gap-3 text-left\"\n                aria-expanded={open === x.id}\n                onClick={() => setOpen(open === x.id ? undefined : x.id)}\n              >\n                <span className=\"text-text-secondary w-20 text-xs\">\n                  Iteration {x.number}\n                </span>\n                <span className=\"flex-1 truncate text-sm\">{x.output}</span>\n                <span className=\"text-sm tabular-nums\">{x.score}</span>\n                <ChevronDown\n                  className={cx(\"size-4\", open === x.id && \"rotate-180\")}\n                />\n              </button>\n              {open === x.id && (\n                <div className=\"bg-background-secondary-default grid gap-4 p-4 lg:grid-cols-2\">\n                  <div>\n                    <p className=\"text-text-secondary text-xs font-medium\">\n                      Generator output\n                    </p>\n                    <p className=\"mt-2 text-sm leading-6\">{x.output}</p>\n                  </div>\n                  <div>\n                    <p className=\"text-text-secondary text-xs font-medium\">\n                      Evaluation criteria\n                    </p>\n                    <div className=\"mt-2 space-y-3\">\n                      {x.criteria.map((criterion) => {\n                        const percentage = criterion.maxScore\n                          ? (criterion.score / criterion.maxScore) * 100\n                          : 0\n                        return (\n                          <div key={criterion.label}>\n                            <div className=\"flex justify-between gap-3 text-xs\">\n                              <span>{criterion.label}</span>\n                              <span className=\"tabular-nums\">\n                                {criterion.score}/{criterion.maxScore}\n                              </span>\n                            </div>\n                            <div className=\"bg-background-primary-default mt-1 h-1 overflow-hidden rounded-full\">\n                              <div\n                                className=\"bg-accent-600 h-full\"\n                                style={{ width: `${percentage}%` }}\n                              />\n                            </div>\n                          </div>\n                        )\n                      })}\n                    </div>\n                  </div>\n                  <div className=\"border-separator-border border-t pt-3 lg:col-span-2\">\n                    <p className=\"text-text-secondary text-xs font-medium\">\n                      Evaluator feedback\n                    </p>\n                    <p className=\"text-text-secondary mt-2 text-sm leading-6\">\n                      {x.feedback}\n                    </p>\n                  </div>\n                </div>\n              )}\n            </div>\n          ))}\n        </div>\n        <p className=\"text-text-secondary mt-4 text-xs\">\n          {iterations.length} iterations · Threshold {qualityThreshold} ·{\" \"}\n          {currentIteration ?? latest?.number ?? 0} of {maxIterations}\n        </p>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/slider/slider.tsx",
          "target": "@components/boardui/base/slider/slider.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n  Label as AriaLabel,\n  Slider as AriaSlider,\n  SliderThumb as AriaSliderThumb,\n  SliderTrack as AriaSliderTrack,\n} from \"react-aria-components\";\nimport type { SliderProps as AriaSliderProps } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\ntype SliderValue = number | number[];\n\ntype SliderBaseProps<T extends SliderValue> = Omit<\n  AriaSliderProps<T>,\n  \"children\" | \"className\" | \"orientation\"\n> & {\n  /** Optional visible label associated with every thumb. */\n  label?: ReactNode;\n  /** Show the exact value in a persistent bubble above each thumb. Default `true`. */\n  showTooltip?: boolean;\n  /** Custom visual formatter for the value bubbles. */\n  formatValue?: (value: number, index: number) => ReactNode;\n  className?: string;\n};\n\nexport type SliderProps = SliderBaseProps<number> & {\n  /** Accessible name for the single thumb. */\n  thumbLabel?: string;\n};\n\nexport type RangeSliderProps = SliderBaseProps<number[]> & {\n  /** Accessible names for the lower and upper thumbs. */\n  thumbLabels?: [string, string];\n};\n\ntype SliderBaseInternalProps<T extends SliderValue> = SliderBaseProps<T> & {\n  thumbLabels: string[];\n};\n\n/**\n * Shared single and multi-thumb slider presentation.\n *\n * React Aria owns the value model, drag behavior, hidden range inputs,\n * keyboard controls, RTL handling, and collision rules. BoardUI owns the\n * visual track, selected range, thumbs, and exact-value bubbles.\n */\nfunction SliderBase<T extends SliderValue>({\n  className,\n  label,\n  showTooltip = true,\n  formatValue,\n  thumbLabels,\n  ...props\n}: SliderBaseInternalProps<T>) {\n  return (\n    <AriaSlider\n      {...props}\n      orientation=\"horizontal\"\n      className={({ isDisabled }) =>\n        cx(\n          \"group flex w-full min-w-0 flex-col gap-2\",\n          isDisabled && \"cursor-not-allowed opacity-50\",\n          className,\n        )\n      }\n    >\n      {({ state }) => {\n        const isRange = state.values.length > 1;\n        const startPercent = isRange ? state.getThumbPercent(0) : 0;\n        const endPercent = state.getThumbPercent(state.values.length - 1);\n\n        return (\n          <>\n            {label != null && (\n              <AriaLabel className=\"text-body-medium text-text-primary\">\n                {label}\n              </AriaLabel>\n            )}\n\n            <AriaSliderTrack\n              className={cx(\n                \"relative h-8 w-full touch-none\",\n                showTooltip && \"mt-8\",\n              )}\n            >\n              {({ isHovered }) => (\n                <>\n                  <span\n                    aria-hidden\n                    className={cx(\n                      \"absolute top-1/2 right-0 left-0 h-1.5 -translate-y-1/2 rounded-full\",\n                      \"bg-background-tertiary-default shadow-[inset_0_1px_1px_rgb(0_0_0/0.06)]\",\n                      \"transition-colors duration-150 ease\",\n                      isHovered && \"bg-background-tertiary-hover\",\n                    )}\n                  />\n                  <span\n                    aria-hidden\n                    className={cx(\n                      \"absolute top-1/2 h-1.5 -translate-y-1/2 rounded-full\",\n                      \"bg-linear-to-r from-accent-500 to-accent-600\",\n                      \"shadow-[inset_0_1px_0_rgb(255_255_255/0.24),0_1px_2px_rgb(4_80_226/0.16)]\",\n                    )}\n                    style={{\n                      insetInlineStart: `${startPercent * 100}%`,\n                      insetInlineEnd: `${(1 - endPercent) * 100}%`,\n                    }}\n                  />\n\n                  {state.values.map((value, index) => {\n                    const valueLabel =\n                      formatValue?.(value, index) ??\n                      state.getThumbValueLabel(index);\n\n                    return (\n                      <AriaSliderThumb\n                        key={index}\n                        index={index}\n                        aria-label={\n                          thumbLabels[index] ??\n                          (isRange ? `Value ${index + 1}` : \"Value\")\n                        }\n                        className={({\n                          isDragging,\n                          isHovered: isThumbHovered,\n                          isFocusVisible,\n                          isDisabled,\n                        }) =>\n                          cx(\n                            \"top-1/2 size-5 rounded-full border border-border-button-default outline-none\",\n                            \"flex items-center justify-center bg-control-indicator-background\",\n                            \"shadow-[0_2px_4px_rgb(0_0_0/0.10),inset_0_1px_0_rgb(255_255_255/0.8)]\",\n                            \"transition-[scale,box-shadow,border-color] duration-150 ease\",\n                            isThumbHovered && !isDragging && \"scale-105 border-border-button-hover\",\n                            isDragging && \"z-20 scale-110 border-accent-500 shadow-[0_3px_8px_color-mix(in_srgb,var(--color-accent-600)_22%,transparent)]\",\n                            isFocusVisible && \"ring-2 ring-border-focus-ring ring-offset-2\",\n                            isDisabled ? \"cursor-not-allowed\" : \"cursor-grab active:cursor-grabbing\",\n                          )\n                        }\n                      >\n                        {({ isDragging, isFocused }) => (\n                          <>\n                            {showTooltip && (\n                              <span\n                                aria-hidden\n                                className={cx(\n                                  \"pointer-events-none absolute bottom-[calc(100%+9px)] left-1/2 -translate-x-1/2\",\n                                  \"flex h-7 min-w-8 items-center justify-center rounded-lg border border-border-button-default\",\n                                  \"bg-background-primary-default px-2 text-caption-1-medium whitespace-nowrap text-text-primary shadow-xs\",\n                                  \"transition-[translate,box-shadow] duration-150 ease\",\n                                  (isDragging || isFocused) && \"-translate-y-0.5 shadow-dropdown\",\n                                )}\n                              >\n                                {valueLabel}\n                                <span\n                                  aria-hidden\n                                  className=\"absolute -bottom-[4.5px] left-1/2 size-2 -translate-x-1/2 rotate-45 border-r border-b border-border-button-default bg-background-primary-default\"\n                                />\n                              </span>\n                            )}\n                            <span\n                              aria-hidden\n                              className={cx(\n                                \"size-2 rounded-full bg-linear-to-b from-accent-500 to-accent-600\",\n                                \"shadow-[inset_0_1px_0_rgb(255_255_255/0.24)] transition-[filter] duration-150 ease\",\n                                (isDragging || isFocused) && \"brightness-110\",\n                              )}\n                            />\n                          </>\n                        )}\n                      </AriaSliderThumb>\n                    );\n                  })}\n                </>\n              )}\n            </AriaSliderTrack>\n          </>\n        );\n      }}\n    </AriaSlider>\n  );\n}\n\n/** A single-value slider with an exact-value bubble above the thumb. */\nexport function Slider({ thumbLabel = \"Value\", ...props }: SliderProps) {\n  return <SliderBase {...props} thumbLabels={[thumbLabel]} />;\n}\n\n/** A two-thumb slider for selecting a minimum and maximum value. */\nexport function RangeSlider({\n  thumbLabels = [\"Minimum\", \"Maximum\"],\n  ...props\n}: RangeSliderProps) {\n  return <SliderBase {...props} thumbLabels={thumbLabels} />;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-feedback",
      "type": "registry:block",
      "title": "Agent Feedback",
      "description": "agent feedback",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-feedback.tsx",
          "target": "@components/agents-ui/agent-feedback.tsx",
          "type": "registry:component",
          "content": "export { AgentFeedback } from \"./application/feedback/feedback\"\nexport type {\n  AgentFeedbackProps,\n  FeedbackCategory,\n  FeedbackData,\n  FeedbackType,\n} from \"./application/feedback/feedback\"\n"
        },
        {
          "path": "components/agents-ui/application/feedback/feedback.tsx",
          "target": "@components/agents-ui/application/feedback/feedback.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, ChevronDown, Flag, ThumbsDown, ThumbsUp } from \"lucide-react\"\nimport { useState } from \"react\"\n\nexport type FeedbackType = \"positive\" | \"negative\" | \"neutral\"\nexport type FeedbackCategory =\n  | \"accuracy\"\n  | \"helpfulness\"\n  | \"speed\"\n  | \"clarity\"\n  | \"other\"\nexport interface FeedbackData {\n  type: FeedbackType\n  rating?: number\n  categories?: FeedbackCategory[]\n  comment?: string\n  timestamp?: Date\n}\nexport interface AgentFeedbackProps {\n  onSubmit?: (feedback: FeedbackData) => void\n  onThumbsUp?: () => void\n  onThumbsDown?: () => void\n  onReport?: (reason: string) => void\n  showDetailedFeedback?: boolean\n  showQuickActions?: boolean\n  defaultExpanded?: boolean\n  className?: string\n}\nconst labels: Record<FeedbackCategory, string> = {\n  accuracy: \"Accuracy\",\n  helpfulness: \"Helpfulness\",\n  speed: \"Response speed\",\n  clarity: \"Clarity\",\n  other: \"Other\",\n}\nexport function AgentFeedback({\n  onSubmit,\n  onThumbsUp,\n  onThumbsDown,\n  onReport,\n  showDetailedFeedback = true,\n  showQuickActions = true,\n  defaultExpanded = false,\n  className,\n}: AgentFeedbackProps) {\n  const [type, setType] = useState<FeedbackType | null>(null)\n  const [expanded, setExpanded] = useState(defaultExpanded)\n  const [categories, setCategories] = useState<FeedbackCategory[]>([])\n  const [comment, setComment] = useState(\"\")\n  const [reportOpen, setReportOpen] = useState(false)\n  const [reason, setReason] = useState(\"\")\n  const choose = (next: FeedbackType) => {\n    setType(next)\n    if (next === \"positive\") onThumbsUp?.()\n    else onThumbsDown?.()\n    if (showDetailedFeedback) setExpanded(true)\n    else onSubmit?.({ type: next, timestamp: new Date() })\n  }\n  const toggle = (category: FeedbackCategory) =>\n    setCategories((current) =>\n      current.includes(category)\n        ? current.filter((item) => item !== category)\n        : [...current, category]\n    )\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      {showQuickActions && (\n        <header className=\"flex min-h-12 flex-wrap items-center justify-between gap-2 px-4 py-2\">\n          <p className=\"text-body-medium\">Was this response helpful?</p>\n          <div className=\"flex gap-1\">\n            <Button\n              size=\"small\"\n              variant={type === \"positive\" ? \"primary\" : \"ghost\"}\n              leadingIcon={ThumbsUp}\n              aria-pressed={type === \"positive\"}\n              onClick={() => choose(\"positive\")}\n            >\n              Helpful\n            </Button>\n            <Button\n              size=\"small\"\n              variant={type === \"negative\" ? \"primary\" : \"ghost\"}\n              leadingIcon={ThumbsDown}\n              aria-pressed={type === \"negative\"}\n              onClick={() => choose(\"negative\")}\n            >\n              Not helpful\n            </Button>\n            {showDetailedFeedback && (\n              <Button\n                size=\"small\"\n                variant=\"ghost\"\n                iconOnly\n                leadingIcon={ChevronDown}\n                aria-label=\"Toggle feedback details\"\n                aria-expanded={expanded}\n                onClick={() => setExpanded((open) => !open)}\n              />\n            )}\n            {onReport && (\n              <Button\n                size=\"small\"\n                variant=\"ghost\"\n                iconOnly\n                leadingIcon={Flag}\n                aria-label=\"Report response\"\n                aria-expanded={reportOpen}\n                onClick={() => setReportOpen((open) => !open)}\n              />\n            )}\n          </div>\n        </header>\n      )}\n      {showDetailedFeedback && expanded && (\n        <div className=\"border-separator-border space-y-4 border-t p-4\">\n          <fieldset>\n            <legend className=\"text-caption-1-medium text-text-secondary mb-2\">\n              What influenced your rating?\n            </legend>\n            <div className=\"flex flex-wrap gap-2\">\n              {(Object.keys(labels) as FeedbackCategory[]).map((category) => (\n                <Button\n                  key={category}\n                  size=\"small\"\n                  variant={\n                    categories.includes(category) ? \"primary\" : \"secondary\"\n                  }\n                  leadingIcon={\n                    categories.includes(category) ? Check : undefined\n                  }\n                  aria-pressed={categories.includes(category)}\n                  onClick={() => toggle(category)}\n                >\n                  {labels[category]}\n                </Button>\n              ))}\n            </div>\n          </fieldset>\n          <label className=\"block\">\n            <span className=\"text-caption-1-medium text-text-secondary mb-1.5 block\">\n              Additional comments\n            </span>\n            <textarea\n              value={comment}\n              onChange={(event) => setComment(event.target.value)}\n              rows={3}\n              className=\"bg-background-tertiary-default text-body-2-regular focus:ring-border-button-active w-full resize-y rounded-lg px-3 py-2 ring-2 ring-transparent outline-none\"\n              placeholder=\"Describe what worked or what should change\"\n            />\n          </label>\n          <div className=\"flex justify-end gap-2\">\n            <Button\n              size=\"small\"\n              variant=\"secondary\"\n              onClick={() => setExpanded(false)}\n            >\n              Cancel\n            </Button>\n            <Button\n              size=\"small\"\n              onClick={() => {\n                onSubmit?.({\n                  type: type ?? \"neutral\",\n                  categories,\n                  comment: comment.trim(),\n                  timestamp: new Date(),\n                })\n                setExpanded(false)\n              }}\n            >\n              Submit feedback\n            </Button>\n          </div>\n        </div>\n      )}\n      {onReport && reportOpen && (\n        <div className=\"border-separator-border space-y-3 border-t p-4\">\n          <label className=\"block\">\n            <span className=\"text-caption-1-medium mb-1.5 block\">\n              Report this response\n            </span>\n            <textarea\n              value={reason}\n              onChange={(event) => setReason(event.target.value)}\n              rows={3}\n              className=\"bg-background-tertiary-default text-body-2-regular focus:ring-border-button-active w-full resize-y rounded-lg px-3 py-2 ring-2 ring-transparent outline-none\"\n            />\n          </label>\n          <div className=\"flex justify-end gap-2\">\n            <Button\n              size=\"small\"\n              variant=\"secondary\"\n              onClick={() => setReportOpen(false)}\n            >\n              Cancel\n            </Button>\n            <Button\n              size=\"small\"\n              variant=\"danger\"\n              disabled={!reason.trim()}\n              onClick={() => {\n                onReport(reason.trim())\n                setReason(\"\")\n                setReportOpen(false)\n              }}\n            >\n              Submit report\n            </Button>\n          </div>\n        </div>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-form-generator",
      "type": "registry:block",
      "title": "Agent Form Generator",
      "description": "agent form generator",
      "dependencies": [
        "@remixicon/react@^4.9.0",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-form-generator.tsx",
          "target": "@components/agents-ui/agent-form-generator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { FormGenerator } from \"@/components/agents-ui/application/form-generator/form-generator\"\n\nexport type FormFieldType =\n  | \"text\"\n  | \"number\"\n  | \"select\"\n  | \"checkbox\"\n  | \"date\"\n  | \"email\"\n  | \"textarea\"\nexport interface FormFieldValidation {\n  minLength?: number\n  maxLength?: number\n  pattern?: string\n  min?: number\n  max?: number\n}\nexport interface FormField {\n  id: string\n  label: string\n  type: FormFieldType\n  placeholder?: string\n  required?: boolean\n  validation?: FormFieldValidation\n  options?: string[]\n}\nexport interface AgentFormGeneratorProps {\n  formTitle?: string\n  formDescription?: string\n  fields?: FormField[]\n  isGenerating?: boolean\n  showPreview?: boolean\n  className?: string\n  onAddField?: () => void\n  onRemoveField?: (fieldId: string) => void\n  onRegenerate?: () => void\n  onExportSchema?: () => void\n  onFieldReorder?: (fieldIds: string[]) => void\n}\nexport function AgentFormGenerator(props: AgentFormGeneratorProps) {\n  return <FormGenerator {...props} />\n}\n"
        },
        {
          "path": "components/agents-ui/application/form-generator/form-generator.tsx",
          "target": "@components/agents-ui/application/form-generator/form-generator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type {\n  AgentFormGeneratorProps,\n  FormField,\n  FormFieldValidation,\n} from \"@/components/agents-ui/agent-form-generator\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Checkbox } from \"@/components/boardui/base/checkbox/checkbox\"\nimport { InputBase, TextField } from \"@/components/boardui/base/input/input\"\nimport { Label } from \"@/components/boardui/base/input/label\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  AlignLeft,\n  ArrowDown,\n  ArrowUp,\n  Calendar,\n  CheckSquare,\n  FileJson,\n  Hash,\n  Mail,\n  Plus,\n  RefreshCw,\n  Trash2,\n  Type,\n} from \"lucide-react\"\n\nconst fields0: FormField[] = [\n  {\n    id: \"account\",\n    label: \"Account name\",\n    type: \"text\",\n    placeholder: \"Northwind\",\n    required: true,\n    validation: { minLength: 2, maxLength: 80 },\n  },\n  {\n    id: \"email\",\n    label: \"Account owner email\",\n    type: \"email\",\n    placeholder: \"owner@company.com\",\n    required: true,\n    validation: { pattern: \"^[^@]+@[^@]+$\" },\n  },\n  {\n    id: \"risk\",\n    label: \"Renewal risk\",\n    type: \"select\",\n    required: true,\n    options: [\"Low\", \"Medium\", \"High\"],\n  },\n  {\n    id: \"action\",\n    label: \"Recommended action\",\n    type: \"textarea\",\n    placeholder: \"Describe the next action\",\n    required: true,\n    validation: { maxLength: 500 },\n  },\n  { id: \"date\", label: \"Due date\", type: \"date\" },\n  { id: \"notify\", label: \"Notify account owner\", type: \"checkbox\" },\n]\nconst icons = {\n  text: Type,\n  email: Mail,\n  select: AlignLeft,\n  textarea: AlignLeft,\n  number: Hash,\n  date: Calendar,\n  checkbox: CheckSquare,\n}\nfunction rules(v?: FormFieldValidation) {\n  return [\n    v?.minLength != null ? `Minimum ${v.minLength} characters` : null,\n    v?.maxLength != null ? `Maximum ${v.maxLength} characters` : null,\n    v?.pattern ? \"Pattern validation\" : null,\n    v?.min != null ? `Minimum ${v.min}` : null,\n    v?.max != null ? `Maximum ${v.max}` : null,\n  ]\n    .filter(Boolean)\n    .join(\" · \")\n}\nfunction Preview({ f }: { f: FormField }) {\n  if (f.type === \"checkbox\") return <Checkbox size=\"sm\">{f.label}</Checkbox>\n  if (f.type === \"textarea\")\n    return (\n      <label className=\"block text-xs font-medium\">\n        {f.label}\n        <textarea\n          className=\"bg-background-tertiary-default mt-1 min-h-20 w-full rounded-lg p-3 text-sm\"\n          placeholder={f.placeholder}\n        />\n      </label>\n    )\n  if (f.type === \"select\")\n    return (\n      <label className=\"block text-xs font-medium\">\n        {f.label}\n        <select className=\"border-separator-border bg-background-primary-default mt-1 h-9 w-full rounded-lg border px-3 text-sm\">\n          {f.options?.map((x) => <option key={x}>{x}</option>)}\n        </select>\n      </label>\n    )\n  return (\n    <TextField isRequired={f.required}>\n      <Label isRequired={f.required}>{f.label}</Label>\n      <InputBase\n        type={f.type}\n        placeholder={f.placeholder}\n        minLength={f.validation?.minLength}\n        maxLength={f.validation?.maxLength}\n        pattern={f.validation?.pattern}\n        min={f.validation?.min}\n        max={f.validation?.max}\n      />\n    </TextField>\n  )\n}\nexport function FormGenerator({\n  formTitle = \"Renewal action request\",\n  formDescription = \"Collect the owner, risk level, and next action.\",\n  fields,\n  isGenerating = false,\n  showPreview = true,\n  onAddField,\n  onRemoveField,\n  onRegenerate,\n  onExportSchema,\n  onFieldReorder,\n  className,\n}: AgentFormGeneratorProps) {\n  const data = fields?.length ? fields : fields0\n  const move = (i: number, d: number) => {\n    const j = i + d\n    if (j < 0 || j >= data.length) return\n    const ids = data.map((x) => x.id)\n    ;[ids[i], ids[j]] = [ids[j], ids[i]]\n    onFieldReorder?.(ids)\n  }\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap justify-between gap-3 border-b p-5\">\n        <div>\n          <h2 className=\"text-lg font-semibold\">Form builder</h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">\n            {formTitle} · {formDescription}\n          </p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={RefreshCw}\n            onClick={onRegenerate}\n          >\n            Regenerate\n          </Button>\n          <Button\n            variant=\"secondary\"\n            size=\"small\"\n            leadingIcon={FileJson}\n            onClick={onExportSchema}\n          >\n            Export schema\n          </Button>\n        </div>\n      </header>\n      {isGenerating && (\n        <p className=\"border-separator-border text-text-secondary border-b px-5 py-2 text-xs\">\n          Generating schema\n        </p>\n      )}\n      <div className={cx(\"grid\", showPreview && \"lg:grid-cols-[3fr_2fr]\")}>\n        <div className=\"p-5\">\n          <div className=\"flex justify-between\">\n            <div>\n              <h3 className=\"text-sm font-medium\">Fields</h3>\n              <p className=\"text-text-secondary text-xs\">\n                Order and validation\n              </p>\n            </div>\n            <Button\n              variant=\"secondary\"\n              size=\"small\"\n              leadingIcon={Plus}\n              onClick={onAddField}\n            >\n              Add field\n            </Button>\n          </div>\n          <div className=\"divide-separator-border border-separator-border mt-3 divide-y border-y\">\n            {data.map((f, i) => {\n              const I = icons[f.type]\n              return (\n                <div\n                  key={f.id}\n                  className=\"grid grid-cols-[20px_1fr_auto] gap-3 py-3\"\n                >\n                  <I className=\"text-text-secondary mt-1 size-4\" />\n                  <div>\n                    <p className=\"text-sm font-medium\">\n                      {f.label}{\" \"}\n                      <span className=\"border-separator-border text-text-secondary ml-2 rounded-sm border px-1.5 py-0.5 text-xs font-normal\">\n                        {f.type}\n                      </span>\n                    </p>\n                    <p className=\"text-text-secondary mt-1 text-xs\">\n                      {f.required ? \"Required\" : \"Optional\"}\n                      {rules(f.validation) ? ` · ${rules(f.validation)}` : \"\"}\n                    </p>\n                  </div>\n                  <div className=\"flex\">\n                    <Button\n                      variant=\"ghost\"\n                      size=\"xs\"\n                      iconOnly\n                      disabled={i === 0}\n                      onClick={() => move(i, -1)}\n                      aria-label={`Move ${f.label} up`}\n                    >\n                      <ArrowUp />\n                    </Button>\n                    <Button\n                      variant=\"ghost\"\n                      size=\"xs\"\n                      iconOnly\n                      disabled={i === data.length - 1}\n                      onClick={() => move(i, 1)}\n                      aria-label={`Move ${f.label} down`}\n                    >\n                      <ArrowDown />\n                    </Button>\n                    <Button\n                      variant=\"ghost\"\n                      size=\"xs\"\n                      iconOnly\n                      onClick={() => onRemoveField?.(f.id)}\n                      aria-label={`Remove ${f.label}`}\n                    >\n                      <Trash2 />\n                    </Button>\n                  </div>\n                </div>\n              )\n            })}\n          </div>\n        </div>\n        {showPreview && (\n          <aside className=\"border-separator-border border-t p-5 lg:border-t-0 lg:border-l\">\n            <h3 className=\"text-base font-semibold\">{formTitle}</h3>\n            <p className=\"text-text-secondary mt-1 text-sm\">\n              {formDescription}\n            </p>\n            <form\n              className=\"mt-5 space-y-4\"\n              onSubmit={(e) => e.preventDefault()}\n            >\n              {data.map((f) => (\n                <div key={f.id}>\n                  <Preview f={f} />\n                </div>\n              ))}\n              <div className=\"border-separator-border flex justify-end border-t pt-4\">\n                <Button type=\"submit\">Submit</Button>\n              </div>\n            </form>\n          </aside>\n        )}\n      </div>\n      <p className=\"border-separator-border text-text-secondary border-t p-4 text-xs\">\n        {data.length} fields · {data.filter((x) => x.required).length} required\n        · Schema version 1\n      </p>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/checkbox/checkbox.tsx",
          "target": "@components/boardui/base/checkbox/checkbox.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport { Checkbox as AriaCheckbox } from \"react-aria-components\";\nimport type { CheckboxProps as AriaCheckboxProps } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\nimport { CheckboxGlyph, checkboxSizes } from \"./checkbox-glyph\";\nimport type { CheckboxSize } from \"./checkbox-glyph\";\n\n/**\n * Figma source: Board UI → Checkbox (node 3699:2557 family; used in\n * dashboard 1 table, nodes 3731:3258 etc.).\n *\n * radius/sm (4px). Two sizes:\n *   md  16×16, label Body 1/Medium (14)\n *   sm  14×14, label Body 2/Medium (13)\n *\n * States (per Figma):\n *   default        bg background/primary/default, 1px border/checkbox/default,\n *                  shadow/xs\n *   hover          border darkens to neutral/400\n *   checked /      Button/Primary gradient (blue/500 → blue/600) with the\n *   indeterminate  checkbox inner highlight (see --shadow-checkbox-selected),\n *                  white 2px rounded stroke glyph; on hover the gradient\n *                  lightens to blue/400 → blue/500\n *\n * Built on react-aria Checkbox: keyboard toggling, aria-checked=\"mixed\" for\n * indeterminate, label association when `children` is passed.\n */\n\nexport interface CheckboxProps extends Omit<AriaCheckboxProps, \"children\"> {\n  children?: ReactNode;\n  size?: CheckboxSize;\n  ref?: Ref<HTMLLabelElement>;\n}\n\nexport function Checkbox({ className, children, size = \"md\", ref, ...props }: CheckboxProps) {\n  const s = checkboxSizes[size];\n\n  return (\n    <AriaCheckbox\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"group inline-flex items-center select-none\",\n          s.gap,\n          state.isDisabled ? \"cursor-not-allowed\" : \"cursor-pointer\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    >\n      {(state) => (\n        <>\n          <CheckboxGlyph state={state} size={size} />\n          {children !== undefined && children !== null && (\n            <span className={cx(s.label, \"text-text-primary\")}>{children}</span>\n          )}\n        </>\n      )}\n    </AriaCheckbox>\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/checkbox/checkbox-glyph.tsx",
          "target": "@components/boardui/base/checkbox/checkbox-glyph.tsx",
          "type": "registry:component",
          "content": "import { cx } from \"@/components/boardui/utils/cx\"\n\nexport type CheckboxSize = \"sm\" | \"md\"\n\nexport const checkboxSizes: Record<\n  CheckboxSize,\n  { box: string; glyph: string; label: string; gap: string }\n> = {\n  md: {\n    box: \"size-4\",\n    glyph: \"size-4\",\n    label: \"text-body-medium\",\n    gap: \"gap-2\",\n  },\n  sm: {\n    box: \"size-3.5\",\n    glyph: \"size-3.5\",\n    label: \"text-body-2-medium\",\n    gap: \"gap-1.5\",\n  },\n}\n\nexport interface CheckboxGlyphState {\n  isSelected: boolean\n  isIndeterminate: boolean\n  isFocusVisible: boolean\n  isDisabled: boolean\n  isHovered: boolean\n}\n\n/**\n * The 16px (or 14px) checkbox box + tick/indeterminate glyph. Shared by the\n * standalone Checkbox and the CheckboxCard so their visuals stay identical.\n */\nexport function CheckboxGlyph({\n  state,\n  size = \"md\",\n}: {\n  state: CheckboxGlyphState\n  size?: CheckboxSize\n}) {\n  const { isSelected, isIndeterminate, isFocusVisible, isDisabled, isHovered } =\n    state\n  const s = checkboxSizes[size]\n  const isMarked = isSelected || isIndeterminate\n  const hover = isHovered && !isDisabled\n\n  return (\n    <span\n      aria-hidden\n      className={cx(\n        \"flex shrink-0 items-center justify-center rounded-sm\",\n        \"ease transition-[background-color,border-color,box-shadow] duration-150\",\n        s.box,\n        isMarked\n          ? cx(\"bg-accent-500\", hover ? \"bg-accent-400\" : \"bg-accent-500\")\n          : cx(\n              \"bg-background-primary-default border shadow-xs\",\n              hover\n                ? \"border-border-checkbox-hover\"\n                : \"border-border-checkbox-default\"\n            ),\n        isDisabled && \"opacity-50\",\n        isFocusVisible && \"ring-border-focus-ring ring-2 ring-offset-2\"\n      )}\n    >\n      <svg viewBox=\"0 0 16 16\" fill=\"none\" className={s.glyph}>\n        {isIndeterminate ? (\n          <path\n            d=\"M4.5 8H8H11.5\"\n            stroke=\"white\"\n            strokeWidth=\"2\"\n            strokeLinecap=\"round\"\n          />\n        ) : isSelected ? (\n          <path\n            d=\"M4 7.7002L6.64645 10.3466C6.84171 10.5419 7.15829 10.5419 7.35355 10.3466L12 5.7002\"\n            stroke=\"white\"\n            strokeWidth=\"2\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n            pathLength={1}\n            className=\"animate-check-draw\"\n          />\n        ) : null}\n      </svg>\n    </span>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/input/input.tsx",
          "target": "@components/boardui/base/input/input.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  createContext,\n  useContext,\n  type ComponentType,\n  type ReactNode,\n  type Ref,\n} from \"react\";\nimport {\n  Group as AriaGroup,\n  Input as AriaInput,\n  TextField as AriaTextField,\n} from \"react-aria-components\";\nimport type {\n  InputProps as AriaInputProps,\n  TextFieldProps as AriaTextFieldProps,\n} from \"react-aria-components\";\nimport { Label } from \"./label\";\nimport { HintText } from \"./hint-text\";\nimport { cx, sortCx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Figma source: Board UI → Input (node 3665:1849).\n *\n * Architecture (mirrors the Untitled UI / React Aria pattern):\n *\n *   InputBase   - the styled field shell. Renders <AriaGroup> + adornments\n *                 + <AriaInput>. State (hover / focus / disabled / invalid)\n *                 arrives as render-prop booleans from Aria.\n *   TextField   - wraps <AriaTextField> and a TextFieldContext so size /\n *                 classes can flow from the composer down into InputBase\n *                 without prop drilling.\n *   Input       - opinionated composition: TextField → Label → InputBase\n *                 → HintText. The component most consumers use.\n *\n * Why React Aria:\n *   - Label ↔ input ↔ hint association via aria-labelledby / aria-describedby\n *   - aria-required, aria-invalid auto-applied\n *   - Form library / native validation integration\n *   - i18n, RTL, autofill edge cases handled\n *   - Render-prop state surfaces `isFocusWithin`, `isHovered`, `isDisabled`,\n *     `isInvalid`, `isRequired` - no CSS pseudo gymnastics\n *\n * Visuals stay 1:1 with Figma - see `styles/theme.css` for the tokens.\n */\n\ntype InputSize = \"medium\" | \"small\";\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\n/* -------------------------------------------------------------------------- */\n/*  TextFieldContext                                                           */\n/* -------------------------------------------------------------------------- */\n\ninterface TextFieldContextValue {\n  size?: InputSize;\n  fieldClassName?: string;\n  inputClassName?: string;\n}\n\nconst TextFieldContext = createContext<TextFieldContextValue>({});\n\n/* -------------------------------------------------------------------------- */\n/*  TextField                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface TextFieldProps\n  extends Omit<AriaTextFieldProps, \"className\">,\n    TextFieldContextValue {\n  className?: string;\n  children?: ReactNode | ((state: { isRequired: boolean; isInvalid: boolean; isDisabled: boolean; isReadOnly: boolean }) => ReactNode);\n}\n\nexport function TextField({\n  size = \"medium\",\n  fieldClassName,\n  inputClassName,\n  className,\n  children,\n  ...props\n}: TextFieldProps) {\n  return (\n    <TextFieldContext.Provider value={{ size, fieldClassName, inputClassName }}>\n      <AriaTextField\n        {...props}\n        data-input-size={size}\n        className={cx(\n          \"group flex h-max w-full flex-col items-start gap-1\",\n          className,\n        )}\n      >\n        {children as never /* RAC accepts render-prop children */}\n      </AriaTextField>\n    </TextFieldContext.Provider>\n  );\n}\n\nTextField.displayName = \"TextField\";\n\n/* -------------------------------------------------------------------------- */\n/*  InputBase                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputBaseProps extends Omit<AriaInputProps, \"size\" | \"className\"> {\n  size?: InputSize;\n  className?: string;\n  leadingIcon?: IconComponent;\n  trailingIcon?: IconComponent;\n  /** Custom element rendered in the leading slot (Phone basic uses this). */\n  leadingAddon?: ReactNode;\n  /** Class for the field shell. */\n  fieldClassName?: string;\n  /** Ref to the <input> element. */\n  ref?: Ref<HTMLInputElement>;\n  /** Ref to the field shell wrapper. */\n  groupRef?: Ref<HTMLDivElement>;\n}\n\nconst inputStyles = sortCx({\n  field: [\n    \"relative flex w-full items-center\",\n    \"rounded-2lg\",\n    \"bg-background-tertiary-default text-foreground-icon-tertiary\",\n    \"ring-2 ring-inset ring-transparent\",\n    \"transition-[background-color,box-shadow,color] duration-[var(--input-transition-ms)] ease\",\n  ].join(\" \"),\n\n  fieldSize: {\n    medium: \"p-2\",                // 8px all sides → h auto = 36\n    small:  \"h-8 px-1.5 py-2\",    // 32 / 6 / 8\n  },\n\n  // When a leadingAddon is present (Phone basic): tighten left padding.\n  fieldWithAddonSize: {\n    medium: \"h-9 pl-1 pr-2 py-2\", // 36 / 4 / 8 / 8\n    small:  \"h-8 pl-1 pr-1.5 py-2\",\n  },\n\n  content: \"flex w-full items-center gap-2 min-w-0\",\n  leftSection: \"flex flex-1 items-center gap-0.5 min-w-0\",\n\n  input: [\n    \"min-w-0 flex-1 bg-transparent border-0 outline-none p-0 m-0\",\n    \"font-sans text-body-regular text-text-primary pl-1\",\n    \"placeholder:text-text-tertiary\",\n    \"focus:placeholder:text-text-primary\",\n    \"disabled:text-input-disabled-text disabled:placeholder:text-input-disabled-text\",\n    \"disabled:cursor-not-allowed\",\n    \"aria-invalid:placeholder:text-text-error-placeholder\",\n  ].join(\" \"),\n\n  icon: \"size-5 shrink-0\",\n});\n\nexport function InputBase({\n  size: sizeProp,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  leadingAddon,\n  fieldClassName,\n  className,\n  ref,\n  groupRef,\n  ...inputProps\n}: InputBaseProps) {\n  const ctx = useContext(TextFieldContext);\n  const size: InputSize = sizeProp ?? ctx.size ?? \"medium\";\n  const hasAddon = leadingAddon !== undefined && leadingAddon !== null;\n\n  return (\n    <AriaGroup\n      ref={groupRef}\n      className={({ isFocusWithin, isHovered, isDisabled, isInvalid }) =>\n        cx(\n          inputStyles.field,\n          hasAddon\n            ? inputStyles.fieldWithAddonSize[size]\n            : inputStyles.fieldSize[size],\n          // Hover: idle, no focus, no disabled, no invalid\n          isHovered &&\n            !isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-hover\",\n          // Focus wins over hover\n          isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-active\",\n          // Disabled\n          isDisabled &&\n            \"bg-input-disabled-background text-input-disabled-foreground\",\n          // Invalid\n          isInvalid && \"bg-background-tertiary-error text-foreground-icon-error\",\n          ctx.fieldClassName,\n          fieldClassName,\n        )\n      }\n    >\n      <div className={inputStyles.content}>\n        <div className={inputStyles.leftSection}>\n          {hasAddon ? (\n            leadingAddon\n          ) : Leading ? (\n            <Leading className={inputStyles.icon} aria-hidden />\n          ) : null}\n          <AriaInput\n            ref={ref}\n            {...inputProps}\n            className={cx(inputStyles.input, ctx.inputClassName, className)}\n          />\n        </div>\n        {Trailing ? (\n          <Trailing className={inputStyles.icon} aria-hidden />\n        ) : null}\n      </div>\n    </AriaGroup>\n  );\n}\n\nInputBase.displayName = \"InputBase\";\n\n/* -------------------------------------------------------------------------- */\n/*  Input (composed)                                                           */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputProps\n  extends Omit<TextFieldProps, \"children\">,\n    Pick<\n      InputBaseProps,\n      | \"leadingIcon\"\n      | \"trailingIcon\"\n      | \"leadingAddon\"\n      | \"fieldClassName\"\n      | \"groupRef\"\n      | \"ref\"\n    > {\n  label?: ReactNode;\n  hint?: ReactNode;\n  /** Show an info icon next to the label. Replace with tooltip when Tooltip lands. */\n  tooltip?: boolean | string;\n  placeholder?: string;\n}\n\nexport function Input({\n  label,\n  hint,\n  tooltip,\n  placeholder,\n  leadingIcon,\n  trailingIcon,\n  leadingAddon,\n  fieldClassName,\n  ref,\n  groupRef,\n  className,\n  ...textFieldProps\n}: InputProps) {\n  return (\n    <TextField\n      {...textFieldProps}\n      className={className}\n      // Don't clobber an explicit aria-label; fall back to the placeholder\n      // only for unlabelled fields that don't provide one.\n      aria-label={\n        textFieldProps[\"aria-label\"] ??\n        (!label && typeof placeholder === \"string\" ? placeholder : undefined)\n      }\n    >\n      {({ isRequired, isInvalid }) => (\n        <>\n          {label && (\n            <Label\n              isRequired={isRequired}\n              isInvalid={isInvalid}\n              tooltip={tooltip}\n            >\n              {label}\n            </Label>\n          )}\n          <InputBase\n            ref={ref}\n            groupRef={groupRef}\n            placeholder={placeholder}\n            leadingIcon={leadingIcon}\n            trailingIcon={trailingIcon}\n            leadingAddon={leadingAddon}\n            fieldClassName={fieldClassName}\n          />\n          {hint && <HintText isInvalid={isInvalid}>{hint}</HintText>}\n        </>\n      )}\n    </TextField>\n  );\n}\n\nInput.displayName = \"Input\";\n"
        },
        {
          "path": "components/boardui/base/input/label.tsx",
          "target": "@components/boardui/base/input/label.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport { RiInformationFill } from \"@remixicon/react\";\nimport type { LabelProps as AriaLabelProps } from \"react-aria-components\";\nimport { Label as AriaLabel } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Field label. Wraps `react-aria-components`' Label so the parent `TextField`\n * automatically wires `htmlFor` / `aria-labelledby`.\n *\n * Visuals come from Figma:\n *   - Inter Medium 14/20, color text/primary\n *   - 2px gap between label + required asterisk + info icon\n *   - asterisk is text/error-primary (red/500)\n *   - info icon is 16×16 in foreground/icon/quaternary\n *\n * Pass `isRequired` to show the asterisk. Pass `tooltip` to show the info\n * icon (currently a static glyph - when the Tooltip component lands it'll\n * wire up here).\n */\n\nexport interface LabelProps extends AriaLabelProps {\n  children: ReactNode;\n  isRequired?: boolean;\n  /** Reserved for invalid-aware styling (asterisk color, etc.) once we need it. */\n  isInvalid?: boolean;\n  /** Show the info icon next to the label. */\n  tooltip?: boolean | string;\n  ref?: Ref<HTMLLabelElement>;\n}\n\nexport function Label({\n  isRequired = false,\n  isInvalid: _isInvalid,\n  tooltip,\n  className,\n  children,\n  ...props\n}: LabelProps) {\n  void _isInvalid;\n  return (\n    <AriaLabel\n      data-label=\"true\"\n      {...props}\n      className={cx(\n        \"flex cursor-default items-center gap-0.5\",\n        \"text-body-medium text-text-primary\",\n        className,\n      )}\n    >\n      {children}\n      {isRequired && (\n        <span\n          aria-hidden=\"true\"\n          className=\"text-body-medium text-text-error-primary\"\n        >\n          *\n        </span>\n      )}\n      {tooltip && (\n        <RiInformationFill\n          className=\"size-4 shrink-0 text-foreground-icon-quaternary\"\n          aria-hidden\n        />\n      )}\n    </AriaLabel>\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/input/hint-text.tsx",
          "target": "@components/boardui/base/input/hint-text.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport type { TextProps as AriaTextProps } from \"react-aria-components\";\nimport { Text as AriaText } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Caption text rendered below a field. Wraps `react-aria-components`' Text\n * so the parent `TextField` automatically wires `aria-describedby` (when\n * `slot=\"description\"`) or `aria-errormessage` (when `slot=\"errorMessage\"`).\n *\n * Visuals come from Figma:\n *   - Inter Medium 12/16, letter-spacing 0.15px\n *   - color text/secondary (default) or text/error-primary (invalid)\n *   - 1px top padding to align with the field's bottom edge\n */\n\nexport interface HintTextProps extends AriaTextProps {\n  children: ReactNode;\n  isInvalid?: boolean;\n  ref?: Ref<HTMLElement>;\n}\n\nexport function HintText({\n  isInvalid = false,\n  className,\n  ...props\n}: HintTextProps) {\n  return (\n    <AriaText\n      slot={isInvalid ? \"errorMessage\" : \"description\"}\n      {...props}\n      className={cx(\n        \"pt-px text-caption-1-medium text-text-secondary\",\n        isInvalid && \"text-text-error-primary\",\n        className,\n      )}\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-generative-surface",
      "type": "registry:block",
      "title": "Agent Generative Surface",
      "description": "agent generative surface",
      "dependencies": [
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-generative-surface.tsx",
          "target": "@components/agents-ui/agent-generative-surface.tsx",
          "type": "registry:component",
          "content": "export { AgentGenerativeSurface } from \"./application/generative-surface/generative-surface\"\nexport type {\n  AgentGenerativeSurfaceProps,\n  GeneratedContent,\n} from \"./application/generative-surface/generative-surface\"\nexport { ResultActions } from \"./application/generative-surface/result-actions\"\nexport type {\n  ResultActionsProps,\n  ResultActionState,\n} from \"./application/generative-surface/result-actions\"\n"
        },
        {
          "path": "components/agents-ui/application/generative-surface/generative-surface.tsx",
          "target": "@components/agents-ui/application/generative-surface/generative-surface.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  ArrowUpRight,\n  Calendar,\n  Check,\n  MapPin,\n  Pause,\n  Play,\n  RotateCcw,\n  Search,\n  SkipBack,\n  SkipForward,\n  Sun,\n} from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport * as React from \"react\"\nimport { type ReactNode } from \"react\"\nimport {\n  GeneratedWorkCardContent,\n  type GeneratedWorkContent,\n} from \"./work-content\"\n\ntype MediaItem = { id: string; src: string; alt: string }\nexport type GeneratedContent =\n  | GeneratedWorkContent\n  | {\n      type: \"audio\"\n      title: string\n      creator: string\n      cover?: string\n      playing: boolean\n      position: number\n      duration: number\n    }\n  | {\n      type: \"focus\"\n      title: string\n      remaining: number\n      duration: number\n      running: boolean\n    }\n  | {\n      type: \"flight\"\n      origin: string\n      originName: string\n      destination: string\n      destinationName: string\n      departure: string\n      arrival: string\n      progress: number\n      status: string\n    }\n  | {\n      type: \"location\"\n      title: string\n      subtitle: string\n      image?: string\n      mapUrl?: string\n    }\n  | {\n      type: \"weather\"\n      location: string\n      temperature: number\n      unit: string\n      condition: string\n      forecast: { day: string; temperature: number }[]\n    }\n  | {\n      type: \"stories\"\n      title: string\n      items: {\n        id: string\n        title: string\n        source: string\n        image?: string\n        href?: string\n      }[]\n    }\n  | {\n      type: \"inbox\"\n      title: string\n      items: {\n        id: string\n        sender: string\n        text: string\n        time: string\n        unread: boolean\n        images?: MediaItem[]\n      }[]\n    }\n  | { type: \"note\"; title: string; body: string; status: string }\n  | {\n      type: \"collection\"\n      title: string\n      description: string\n      images: MediaItem[]\n    }\n  | {\n      type: \"event\"\n      title: string\n      time: string\n      timezone: string\n      date: string\n      location: string\n      attendees: string[]\n    }\n  | {\n      type: \"activity\"\n      title: string\n      value: string\n      unit: string\n      description: string\n      points: { label: string; value: number }[]\n    }\n\nexport interface AgentGenerativeSurfaceProps {\n  content: GeneratedContent\n  status?: \"ready\" | \"loading\" | \"error\"\n  error?: string\n  onAction?: (action: string, id?: string) => void\n  onSeek?: (seconds: number) => void\n  onRetry?: () => void\n  className?: string\n  animate?: boolean\n}\n\nconst clamp = (value: number, max = 100) =>\n  Math.max(0, Math.min(max, Number.isFinite(value) ? value : 0))\nconst clock = (seconds: number) =>\n  `${Math.floor(Math.max(0, seconds) / 60)}:${String(Math.floor(Math.max(0, seconds) % 60)).padStart(2, \"0\")}`\nconst caption = \"text-[13px] leading-[1.55] text-text-secondary\"\nconst heading = \"text-sm font-medium tracking-tight\"\nfunction Header({ title, children }: { title: string; children?: ReactNode }) {\n  return (\n    <header className=\"mb-4 flex items-center justify-between gap-3\">\n      <h3 className={heading}>{title}</h3>\n      {children}\n    </header>\n  )\n}\nfunction Picture({\n  src,\n  alt,\n  className,\n}: {\n  src: string\n  alt: string\n  className?: string\n}) {\n  // Caller-provided media stays an ordinary image, without a framework loader.\n  return (\n    // eslint-disable-next-line @next/next/no-img-element\n    <img\n      src={src}\n      alt={alt}\n      className={cx(\"object-cover\", className)}\n      loading=\"lazy\"\n    />\n  )\n}\n\nfunction Content({\n  content: c,\n  onAction,\n  onSeek,\n}: AgentGenerativeSurfaceProps) {\n  switch (c.type) {\n    case \"comparison\":\n    case \"recommendation\":\n    case \"document\":\n    case \"checklist\":\n    case \"source-brief\":\n      return <GeneratedWorkCardContent content={c} onAction={onAction} />\n    case \"audio\":\n      return (\n        <>\n          <div className=\"flex gap-4\">\n            {c.cover && (\n              <Picture\n                src={c.cover}\n                alt={`${c.title} cover`}\n                className=\"size-24 shrink-0 rounded-xl\"\n              />\n            )}\n            <div className=\"min-w-0 flex-1\">\n              <h3 className={heading}>{c.title}</h3>\n              <p className={caption}>{c.creator}</p>\n              <div className=\"mt-3 flex items-center gap-3\">\n                <Button\n                  variant=\"ghost\"\n                  iconOnly\n                  leadingIcon={SkipBack}\n                  aria-label=\"Previous track\"\n                  disabled={!onAction}\n                  onClick={() => onAction?.(\"previous\")}\n                />\n                <Button\n                  iconOnly\n                  leadingIcon={c.playing ? Pause : Play}\n                  aria-label={c.playing ? \"Pause audio\" : \"Play audio\"}\n                  disabled={!onAction}\n                  className=\"rounded-full\"\n                  onClick={() => onAction?.(c.playing ? \"pause\" : \"play\")}\n                />\n                <Button\n                  variant=\"ghost\"\n                  iconOnly\n                  leadingIcon={SkipForward}\n                  aria-label=\"Next track\"\n                  disabled={!onAction}\n                  onClick={() => onAction?.(\"next\")}\n                />\n              </div>\n            </div>\n          </div>\n          <input\n            aria-label=\"Audio position\"\n            type=\"range\"\n            min={0}\n            max={Math.max(1, c.duration)}\n            value={clamp(c.position, c.duration)}\n            onChange={(event) => onSeek?.(Number(event.target.value))}\n            disabled={!onSeek}\n            className=\"mt-5 h-1 w-full accent-current\"\n          />\n          <div className=\"text-text-secondary mt-2 flex justify-between text-xs tabular-nums\">\n            <span>{clock(c.position)}</span>\n            <span>{clock(Math.max(0, c.duration - c.position))} remaining</span>\n          </div>\n        </>\n      )\n    case \"focus\": {\n      const progress = clamp(c.remaining / Math.max(1, c.duration), 1)\n      return (\n        <>\n          <Header title={c.title}>\n            <span className=\"text-[13px] text-white/65\">\n              {c.running\n                ? \"In progress\"\n                : c.remaining === 0\n                  ? \"Complete\"\n                  : \"Paused\"}\n            </span>\n          </Header>\n          <div className=\"relative mx-auto my-5 size-44\">\n            <svg\n              viewBox=\"0 0 180 180\"\n              className=\"size-full -rotate-90\"\n              aria-hidden=\"true\"\n            >\n              {Array.from({ length: 60 }, (_, index) => (\n                <line\n                  key={index}\n                  x1=\"90\"\n                  y1=\"8\"\n                  x2=\"90\"\n                  y2={index % 5 === 0 ? \"20\" : \"16\"}\n                  transform={`rotate(${index * 6} 90 90)`}\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  opacity={index / 60 <= progress ? 0.88 : 0.16}\n                />\n              ))}\n            </svg>\n            <p\n              className=\"absolute inset-0 flex items-center justify-center text-4xl font-normal tracking-tight tabular-nums\"\n              aria-live=\"off\"\n            >\n              {clock(c.remaining)}\n            </p>\n          </div>\n          <div className=\"flex justify-center gap-3\">\n            <Button\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={RotateCcw}\n              aria-label=\"Reset timer\"\n              className=\"rounded-full bg-white/10 text-white\"\n              disabled={!onAction}\n              onClick={() => onAction?.(\"reset\")}\n            />\n            <Button\n              variant=\"ghost\"\n              leadingIcon={c.running ? Pause : Play}\n              className=\"rounded-full bg-white/10 px-5 text-white\"\n              disabled={!onAction}\n              onClick={() => onAction?.(c.running ? \"pause\" : \"start\")}\n            >\n              {c.running ? \"Pause\" : \"Start\"}\n            </Button>\n          </div>\n        </>\n      )\n    }\n    case \"flight\":\n      return (\n        <>\n          <Header title=\"Flight\">\n            <span className=\"text-text-secondary text-xs\">{c.status}</span>\n          </Header>\n          <div className=\"flex justify-between gap-4\">\n            <div>\n              <p className=\"text-3xl tracking-tight\">{c.origin}</p>\n              <p className={caption}>{c.originName}</p>\n            </div>\n            <div className=\"text-right\">\n              <p className=\"text-3xl tracking-tight\">{c.destination}</p>\n              <p className={caption}>{c.destinationName}</p>\n            </div>\n          </div>\n          <div\n            className=\"bg-background-secondary-default my-5 h-1 overflow-hidden rounded-full\"\n            role=\"progressbar\"\n            aria-label=\"Flight progress\"\n            aria-valuenow={clamp(c.progress)}\n            aria-valuemin={0}\n            aria-valuemax={100}\n          >\n            <div\n              className=\"h-full rounded-full bg-cyan-600\"\n              style={{ width: `${clamp(c.progress)}%` }}\n            />\n          </div>\n          <div className=\"flex justify-between text-[13px] tabular-nums\">\n            <div>\n              {c.departure}\n              <p className=\"text-text-secondary mt-1 text-xs\">Departure</p>\n            </div>\n            <div className=\"text-right\">\n              {c.arrival}\n              <p className=\"text-text-secondary mt-1 text-xs\">Arrival</p>\n            </div>\n          </div>\n        </>\n      )\n    case \"location\":\n      return (\n        <>\n          {c.image && (\n            <Picture\n              src={c.image}\n              alt={c.title}\n              className=\"mb-5 aspect-[4/3] w-full rounded-xl\"\n            />\n          )}\n          <div className=\"flex items-start justify-between gap-3\">\n            <div>\n              <h3 className={heading}>{c.title}</h3>\n              <p className={caption}>{c.subtitle}</p>\n            </div>\n            {c.mapUrl && (\n              <a\n                href={c.mapUrl}\n                target=\"_blank\"\n                rel=\"noreferrer\"\n                aria-label={`Open map for ${c.title}`}\n                className=\"rounded-lg p-2 focus-visible:outline-2\"\n              >\n                <MapPin className=\"size-4\" />\n              </a>\n            )}\n          </div>\n        </>\n      )\n    case \"weather\":\n      return (\n        <>\n          <Header title={c.location}>\n            <Sun className=\"text-text-secondary size-5\" aria-hidden=\"true\" />\n          </Header>\n          <div className=\"mb-4 flex items-center justify-between\">\n            <p className=\"text-5xl font-normal tracking-tight tabular-nums\">\n              {c.temperature}°\n              <span className=\"text-text-secondary ml-2 text-sm\">{c.unit}</span>\n            </p>\n            <span className={caption}>{c.condition}</span>\n          </div>\n          <div\n            className=\"grid gap-3\"\n            style={{\n              gridTemplateColumns: `repeat(${Math.max(1, c.forecast.length)}, minmax(0, 1fr))`,\n            }}\n          >\n            {c.forecast.map((day) => (\n              <div key={day.day} className=\"text-[13px]\">\n                <p className=\"text-text-secondary\">{day.day}</p>\n                <p className=\"mt-2 tabular-nums\">{day.temperature}°</p>\n              </div>\n            ))}\n          </div>\n        </>\n      )\n    case \"stories\":\n      return (\n        <>\n          <Header title={c.title} />\n          <div className=\"space-y-5\">\n            {c.items.map((item) => (\n              <article key={item.id} className=\"flex gap-4\">\n                {item.image && (\n                  <Picture\n                    src={item.image}\n                    alt=\"\"\n                    className=\"size-12 shrink-0 rounded-lg\"\n                  />\n                )}\n                <div className=\"min-w-0\">\n                  <h4 className=\"text-[13px] leading-5 font-medium\">\n                    {item.href ? (\n                      <a\n                        href={item.href}\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                        className=\"hover:underline focus-visible:outline-2\"\n                      >\n                        {item.title}\n                      </a>\n                    ) : (\n                      item.title\n                    )}\n                  </h4>\n                  <p className=\"text-text-secondary mt-1 text-xs leading-5\">\n                    {item.source}\n                  </p>\n                </div>\n              </article>\n            ))}\n          </div>\n        </>\n      )\n    case \"inbox\":\n      return (\n        <>\n          <Header title={c.title}>\n            <span className=\"text-text-secondary mr-auto text-[13px]\">\n              {c.items.filter((item) => item.unread).length} unread\n            </span>\n            <Button\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={Search}\n              aria-label=\"Search inbox\"\n              disabled={!onAction}\n              onClick={() => onAction?.(\"search\")}\n            />\n          </Header>\n          <div className=\"space-y-4\">\n            {c.items.map((item) => (\n              <article key={item.id} className=\"relative pl-4\">\n                <span\n                  aria-label={item.unread ? \"Unread\" : \"Read\"}\n                  className={cx(\n                    \"absolute top-1.5 left-0 size-1.5 rounded-full\",\n                    item.unread && \"bg-cyan-600\"\n                  )}\n                />\n                <div className=\"flex justify-between gap-3\">\n                  <button\n                    className=\"text-left text-[13px] font-medium focus-visible:outline-2\"\n                    disabled={!onAction}\n                    onClick={() => onAction?.(\"open\", item.id)}\n                  >\n                    {item.sender}\n                  </button>\n                  <time className=\"text-text-secondary shrink-0 text-xs tabular-nums\">\n                    {item.time}\n                  </time>\n                </div>\n                <p className=\"text-text-secondary mt-1 text-[13px] leading-[1.55]\">\n                  {item.text}\n                </p>\n                {item.images && (\n                  <div className=\"mt-3 flex -space-x-1\">\n                    {item.images.map((image) => (\n                      <Picture\n                        key={image.id}\n                        src={image.src}\n                        alt={image.alt}\n                        className=\"ring-background-primary-default size-10 rounded-lg ring-2\"\n                      />\n                    ))}\n                  </div>\n                )}\n              </article>\n            ))}\n          </div>\n        </>\n      )\n    case \"note\":\n      return (\n        <>\n          <Header title={c.title} />\n          <p className=\"mb-9 font-serif text-2xl leading-[1.3] tracking-tight\">\n            {c.body}\n          </p>\n          <span className=\"rounded bg-amber-100 px-2 py-1 text-xs text-amber-950 dark:bg-amber-950/40 dark:text-amber-200\">\n            {c.status}\n          </span>\n        </>\n      )\n    case \"collection\":\n      return (\n        <>\n          <div className=\"mb-5 grid grid-cols-2 gap-2\">\n            {c.images.map((image, i) => (\n              <Picture\n                key={image.id}\n                src={image.src}\n                alt={image.alt}\n                className={cx(\n                  \"w-full rounded-xl\",\n                  c.images.length === 3 && i === 0\n                    ? \"row-span-2 h-full\"\n                    : \"aspect-square\"\n                )}\n              />\n            ))}\n          </div>\n          <div className=\"items-center-start flex justify-between gap-3\">\n            <div>\n              <h3 className={heading}>{c.title}</h3>\n              <p className={caption}>{c.description}</p>\n            </div>\n            <span className=\"text-text-secondary mt-1 shrink-0 text-xs\">\n              {c.images.length} items\n            </span>\n          </div>\n        </>\n      )\n    case \"event\":\n      return (\n        <>\n          <Header title=\"Up next\">\n            <Calendar className=\"text-text-secondary size-4\" />\n          </Header>\n          <p className=\"text-4xl tracking-tight tabular-nums\">\n            {c.time}\n            <span className=\"text-text-secondary ml-2 text-[13px]\">\n              {c.timezone}\n            </span>\n          </p>\n          <h3 className=\"mt-4 text-sm font-medium\">{c.title}</h3>\n          <p className={caption}>\n            {c.date} · {c.location}\n          </p>\n          <div className=\"mt-5 flex flex-wrap items-center justify-between gap-3\">\n            <div className=\"flex -space-x-1\">\n              {c.attendees.map((name) => (\n                <span\n                  key={name}\n                  title={name}\n                  className=\"bg-background-secondary-default ring-background-primary-default flex size-7 items-center justify-center rounded-full text-[10px] ring-2\"\n                >\n                  {name\n                    .split(\" \")\n                    .map((word) => word[0])\n                    .slice(0, 2)\n                    .join(\"\")}\n                </span>\n              ))}\n            </div>\n            <Button\n              size=\"small\"\n              variant=\"secondary\"\n              leadingIcon={ArrowUpRight}\n              disabled={!onAction}\n              onClick={() => onAction?.(\"open\")}\n            >\n              View event\n            </Button>\n          </div>\n        </>\n      )\n    case \"activity\": {\n      const max = Math.max(1, ...c.points.map((point) => point.value))\n      return (\n        <>\n          <Header title={c.title}>\n            <Check className=\"text-text-secondary size-4\" />\n          </Header>\n          <p className=\"text-4xl tracking-tight tabular-nums\">\n            {c.value}\n            <span className=\"text-text-secondary ml-2 text-[13px]\">\n              {c.unit}\n            </span>\n          </p>\n          <p className=\"text-text-secondary mt-2 text-xs\">{c.description}</p>\n          <div className=\"mt-4 flex h-20 items-end gap-3\">\n            {c.points.map((point, index) => (\n              <div\n                key={`${point.label}-${index}`}\n                className=\"flex h-full min-w-0 flex-1 flex-col justify-end gap-2\"\n              >\n                <div className=\"min-h-0 flex-1 content-end\">\n                  <div\n                    className=\"w-full rounded-t-sm bg-cyan-600/35\"\n                    style={{ height: `${clamp(point.value / max, 1) * 100}%` }}\n                    title={`${point.label}: ${point.value}`}\n                  />\n                </div>\n                <span className=\"text-text-secondary text-center text-xs\">\n                  {point.label}\n                </span>\n              </div>\n            ))}\n          </div>\n          <details className=\"text-text-secondary mt-4 text-xs\">\n            <summary className=\"cursor-pointer\">View values</summary>\n            <ul className=\"mt-2 space-y-1\">\n              {c.points.map((point, index) => (\n                <li key={`${point.label}-${index}`}>\n                  {point.label}: {point.value}\n                </li>\n              ))}\n            </ul>\n          </details>\n        </>\n      )\n    }\n  }\n}\n\nexport function AgentGenerativeSurface({\n  content,\n  status = \"ready\",\n  error,\n  onRetry,\n  className,\n  animate = true,\n  ...props\n}: AgentGenerativeSurfaceProps) {\n  const reduced = useReducedMotion()\n  const key = status === \"ready\" ? content.type : status\n  return (\n    <motion.section\n      layout={animate && !reduced}\n      transition={{ layout: { type: \"spring\", stiffness: 350, damping: 38 } }}\n      aria-busy={status === \"loading\"}\n      className={cx(\n        \"generated-result border-separator-border bg-background-primary-default text-text-primary w-full min-w-0 overflow-hidden rounded-window border p-4 shadow-sm\",\n        status === \"ready\" &&\n          content.type === \"focus\" &&\n          \"border-transparent bg-[#202a3a] text-white\",\n        className\n      )}\n    >\n      <AnimatePresence initial={false} mode=\"popLayout\">\n        <motion.div\n          key={key}\n          initial={{ opacity: reduced || !animate ? 1 : 0 }}\n          animate={{ opacity: 1 }}\n          exit={{ opacity: 0 }}\n          transition={{ duration: reduced || !animate ? 0 : 0.16 }}\n        >\n          {status === \"loading\" ? (\n            <div role=\"status\" className=\"min-h-40 space-y-4\">\n              <p className=\"text-text-secondary text-[13px]\">\n                Preparing your result\n              </p>\n              <div className=\"bg-background-secondary-default h-5 w-2/3 rounded\" />\n              <div className=\"bg-background-secondary-default h-16 rounded-xl\" />\n            </div>\n          ) : status === \"error\" ? (\n            <div role=\"alert\" className=\"min-h-36\">\n              <h3 className={heading}>This result could not be rendered</h3>\n              <p className=\"text-text-secondary mt-2 text-[13px]\">\n                {error || \"Try the request again.\"}\n              </p>\n              {onRetry && (\n                <Button\n                  variant=\"secondary\"\n                  size=\"small\"\n                  className=\"mt-5\"\n                  onClick={onRetry}\n                >\n                  Retry\n                </Button>\n              )}\n            </div>\n          ) : (\n            <Content content={content} {...props} />\n          )}\n        </motion.div>\n      </AnimatePresence>\n    </motion.section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/agents-ui/application/generative-surface/work-content.tsx",
          "target": "@components/agents-ui/application/generative-surface/work-content.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Circle, Download, ExternalLink, FileText } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport interface GeneratedComparisonAttribute {\n  label: string\n  value: string\n}\n\nexport interface GeneratedComparisonOption {\n  id: string\n  title: string\n  description?: string\n  attributes: GeneratedComparisonAttribute[]\n  recommended?: boolean\n}\n\nexport interface GeneratedRecommendationAlternative {\n  id: string\n  label: string\n}\n\nexport interface GeneratedChecklistItem {\n  id: string\n  label: string\n  detail?: string\n  completed: boolean\n}\n\nexport interface GeneratedBriefSource {\n  id: string\n  title: string\n  origin?: string\n  url?: string\n}\n\nexport type GeneratedWorkContent =\n  | {\n      type: \"comparison\"\n      title: string\n      description?: string\n      options: GeneratedComparisonOption[]\n      selectedId?: string\n    }\n  | {\n      type: \"recommendation\"\n      id: string\n      title: string\n      summary: string\n      reasoning?: string[]\n      confidence?: number\n      acceptLabel?: string\n      alternatives?: GeneratedRecommendationAlternative[]\n    }\n  | {\n      type: \"document\"\n      id: string\n      title: string\n      format: string\n      size: string\n      excerpt: string\n      updated?: string\n    }\n  | {\n      type: \"checklist\"\n      title: string\n      description?: string\n      items: GeneratedChecklistItem[]\n    }\n  | {\n      type: \"source-brief\"\n      title: string\n      summary: string\n      sources: GeneratedBriefSource[]\n    }\n\nexport interface GeneratedWorkCardContentProps {\n  content: GeneratedWorkContent\n  onAction?: (action: string, id?: string) => void\n}\n\nconst secondary = \"text-[13px] leading-[1.55] text-text-secondary\"\n\nfunction ComparisonContent({\n  content,\n  onAction,\n}: {\n  content: Extract<GeneratedWorkContent, { type: \"comparison\" }>\n  onAction?: GeneratedWorkCardContentProps[\"onAction\"]\n}) {\n  return (\n    <div>\n      <header className=\"mb-5\">\n        <h3 className=\"text-sm font-medium tracking-tight\">\n          {content.title}\n        </h3>\n        {content.description && (\n          <p className={cx(\"mt-1\", secondary)}>{content.description}</p>\n        )}\n      </header>\n      <div className=\"result-comparison-grid grid gap-3\">\n        {content.options.map((option) => {\n          const selected = option.id === content.selectedId\n          return (\n            <button\n              key={option.id}\n              type=\"button\"\n              aria-pressed={selected}\n              onClick={() => onAction?.(\"select\", option.id)}\n              className={cx(\n                \"min-w-0 rounded-card border p-3 text-left transition-colors\",\n                selected\n                  ? \"border-border-focus-ring bg-background-secondary-default\"\n                  : \"border-separator-border hover:bg-background-secondary-hover\"\n              )}\n            >\n              <div className=\"flex flex-col items-start gap-1\">\n                <div>\n                  <h4 className=\"text-[13px] font-medium\">{option.title}</h4>\n                  {option.description && (\n                    <p className=\"text-text-secondary mt-1 text-xs leading-5\">\n                      {option.description}\n                    </p>\n                  )}\n                </div>\n                {option.recommended && (\n                  <span className=\"text-text-secondary bg-background-secondary-default rounded-md px-1.5 py-0.5 text-[11px] font-medium\">\n                    Recommended\n                  </span>\n                )}\n              </div>\n              <dl className=\"divide-separator-border border-separator-border mt-4 divide-y border-y\">\n                {option.attributes.map((attribute) => (\n                  <div\n                    key={attribute.label}\n                    className=\"flex justify-between gap-4 py-2 text-xs\"\n                  >\n                    <dt className=\"text-text-secondary\">{attribute.label}</dt>\n                    <dd className=\"text-right font-medium\">\n                      {attribute.value}\n                    </dd>\n                  </div>\n                ))}\n              </dl>\n            </button>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n\nfunction RecommendationContent({\n  content,\n  onAction,\n}: {\n  content: Extract<GeneratedWorkContent, { type: \"recommendation\" }>\n  onAction?: GeneratedWorkCardContentProps[\"onAction\"]\n}) {\n  const confidence =\n    content.confidence === undefined\n      ? undefined\n      : Math.max(0, Math.min(100, content.confidence))\n  return (\n    <div>\n      <header className=\"flex flex-wrap items-start justify-between gap-3\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">\n            Recommendation\n          </p>\n          <h3 className=\"mt-1 text-sm font-medium tracking-tight\">\n            {content.title}\n          </h3>\n        </div>\n        {confidence !== undefined && (\n          <span className=\"text-text-secondary text-xs tabular-nums\">\n            {confidence}% confidence\n          </span>\n        )}\n      </header>\n      <p className=\"mt-4 text-[13px] leading-[1.55]\">{content.summary}</p>\n      {content.reasoning?.length ? (\n        <div className=\"border-separator-border mt-5 border-y py-3\">\n          <p className=\"text-text-secondary text-xs font-medium\">\n            Reasoning summary\n          </p>\n          <ul className=\"mt-2 space-y-2\">\n            {content.reasoning.map((reason) => (\n              <li key={reason} className=\"flex gap-2 text-[13px] leading-5\">\n                <span\n                  aria-hidden=\"true\"\n                  className=\"bg-text-secondary mt-2 size-1 shrink-0 rounded-full\"\n                />\n                {reason}\n              </li>\n            ))}\n          </ul>\n        </div>\n      ) : null}\n      <footer className=\"mt-5 flex flex-wrap gap-2\">\n        <Button\n          size=\"small\"\n          onClick={() => onAction?.(\"accept\", content.id)}\n          disabled={!onAction}\n        >\n          {content.acceptLabel ?? \"Accept recommendation\"}\n        </Button>\n        {content.alternatives?.map((alternative) => (\n          <Button\n            key={alternative.id}\n            size=\"small\"\n            variant=\"secondary\"\n            onClick={() => onAction?.(\"alternative\", alternative.id)}\n            disabled={!onAction}\n          >\n            {alternative.label}\n          </Button>\n        ))}\n      </footer>\n    </div>\n  )\n}\n\nfunction DocumentContent({\n  content,\n  onAction,\n}: {\n  content: Extract<GeneratedWorkContent, { type: \"document\" }>\n  onAction?: GeneratedWorkCardContentProps[\"onAction\"]\n}) {\n  return (\n    <div>\n      <header className=\"flex flex-wrap items-start gap-3\">\n        <FileText\n          aria-hidden=\"true\"\n          className=\"text-text-secondary mt-0.5 size-5 shrink-0\"\n        />\n        <div className=\"min-w-0 flex-1\">\n          <h3 className=\"text-sm font-medium tracking-tight break-words\">\n            {content.title}\n          </h3>\n          <p className=\"text-text-secondary mt-1 text-xs leading-5\">\n            {content.format} | {content.size}\n            {content.updated ? `  |  ${content.updated}` : \"\"}\n          </p>\n        </div>\n        <div className=\"flex w-full flex-wrap gap-2 pl-7\">\n          <Button\n            size=\"small\"\n            variant=\"ghost\"\n            leadingIcon={ExternalLink}\n            onClick={() => onAction?.(\"open\", content.id)}\n            disabled={!onAction}\n          >\n            Open\n          </Button>\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={Download}\n            onClick={() => onAction?.(\"download\", content.id)}\n            disabled={!onAction}\n          >\n            Download\n          </Button>\n        </div>\n      </header>\n      <div className=\"border-separator-border mt-5 border-t pt-4\">\n        <p className=\"text-text-secondary line-clamp-5 text-[13px] leading-[1.55] whitespace-pre-wrap\">\n          {content.excerpt}\n        </p>\n      </div>\n    </div>\n  )\n}\n\nfunction ChecklistContent({\n  content,\n  onAction,\n}: {\n  content: Extract<GeneratedWorkContent, { type: \"checklist\" }>\n  onAction?: GeneratedWorkCardContentProps[\"onAction\"]\n}) {\n  const complete = content.items.filter((item) => item.completed).length\n  return (\n    <div>\n      <header className=\"mb-4 flex items-start justify-between gap-3\">\n        <div>\n          <h3 className=\"text-sm font-medium tracking-tight\">\n            {content.title}\n          </h3>\n          {content.description && (\n            <p className={cx(\"mt-1\", secondary)}>{content.description}</p>\n          )}\n        </div>\n        <span className=\"text-text-secondary shrink-0 text-xs tabular-nums\">\n          {complete} of {content.items.length}\n        </span>\n      </header>\n      <div className=\"divide-separator-border border-separator-border divide-y border-y\">\n        {content.items.map((item) => (\n          <button\n            key={item.id}\n            type=\"button\"\n            aria-pressed={item.completed}\n            onClick={() => onAction?.(\"toggle\", item.id)}\n            disabled={!onAction}\n            className=\"flex min-h-10 w-full items-start gap-3 py-3 text-left disabled:cursor-default\"\n          >\n            <span\n              className={cx(\n                \"mt-0.5 grid size-5 shrink-0 place-items-center rounded-full border\",\n                item.completed\n                  ? \"border-button-primary bg-button-primary text-text-white\"\n                  : \"border-border-button-default text-text-tertiary\"\n              )}\n            >\n              {item.completed ? (\n                <Check className=\"size-3.5\" />\n              ) : (\n                <Circle className=\"size-3\" />\n              )}\n            </span>\n            <span className=\"min-w-0\">\n              <span\n                className={cx(\n                  \"block text-[13px] font-medium\",\n                  item.completed && \"text-text-secondary line-through\"\n                )}\n              >\n                {item.label}\n              </span>\n              {item.detail && (\n                <span className=\"text-text-secondary mt-1 block text-xs leading-5\">\n                  {item.detail}\n                </span>\n              )}\n            </span>\n          </button>\n        ))}\n      </div>\n    </div>\n  )\n}\n\nfunction SourceBriefContent({\n  content,\n  onAction,\n}: {\n  content: Extract<GeneratedWorkContent, { type: \"source-brief\" }>\n  onAction?: GeneratedWorkCardContentProps[\"onAction\"]\n}) {\n  return (\n    <div>\n      <header>\n        <p className=\"text-text-secondary text-xs font-medium\">Source brief</p>\n        <h3 className=\"mt-1 text-sm font-medium tracking-tight\">\n          {content.title}\n        </h3>\n      </header>\n      <p className=\"mt-4 text-[13px] leading-[1.55]\">{content.summary}</p>\n      <div className=\"divide-separator-border border-separator-border mt-5 divide-y border-y\">\n        {content.sources.map((source, index) => (\n          <button\n            key={source.id}\n            type=\"button\"\n            onClick={() => onAction?.(\"source\", source.id)}\n            disabled={!onAction}\n            className=\"flex min-h-10 w-full items-center gap-3 py-3 text-left disabled:cursor-default\"\n          >\n            <span className=\"text-text-tertiary text-xs tabular-nums\">\n              {index + 1}\n            </span>\n            <span className=\"min-w-0 flex-1\">\n              <span className=\"block truncate text-[13px] font-medium\">\n                {source.title}\n              </span>\n              {source.origin && (\n                <span className=\"text-text-secondary mt-0.5 block truncate text-xs\">\n                  {source.origin}\n                </span>\n              )}\n            </span>\n            {source.url && (\n              <ExternalLink\n                aria-hidden=\"true\"\n                className=\"text-text-tertiary size-4 shrink-0\"\n              />\n            )}\n          </button>\n        ))}\n      </div>\n    </div>\n  )\n}\n\nexport function GeneratedWorkCardContent({\n  content,\n  onAction,\n}: GeneratedWorkCardContentProps) {\n  switch (content.type) {\n    case \"comparison\":\n      return <ComparisonContent content={content} onAction={onAction} />\n    case \"recommendation\":\n      return <RecommendationContent content={content} onAction={onAction} />\n    case \"document\":\n      return <DocumentContent content={content} onAction={onAction} />\n    case \"checklist\":\n      return <ChecklistContent content={content} onAction={onAction} />\n    case \"source-brief\":\n      return <SourceBriefContent content={content} onAction={onAction} />\n  }\n}\n"
        },
        {
          "path": "components/agents-ui/application/generative-surface/result-actions.tsx",
          "target": "@components/agents-ui/application/generative-surface/result-actions.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  Check,\n  Copy,\n  GitCompare,\n  Maximize2,\n  Pencil,\n  Save,\n  Share2,\n} from \"lucide-react\"\n\nexport type ResultActionState = \"view\" | \"expanded\" | \"editing\" | \"comparing\"\n\nexport interface ResultActionsProps {\n  state?: ResultActionState\n  saved?: boolean\n  onExpand?: () => void\n  onEdit?: () => void\n  onCompare?: () => void\n  onSave?: () => void\n  onShare?: () => void\n  onCopy?: () => void\n  className?: string\n}\n\nexport function ResultActions({\n  state = \"view\",\n  saved = false,\n  onExpand,\n  onEdit,\n  onCompare,\n  onSave,\n  onShare,\n  onCopy,\n  className,\n}: ResultActionsProps) {\n  return (\n    <div\n      className={cx(\"flex flex-wrap items-center gap-1\", className)}\n      role=\"group\"\n      aria-label=\"Result actions\"\n    >\n      <Button\n        size=\"xs\"\n        variant={state === \"expanded\" ? \"secondary\" : \"ghost\"}\n        leadingIcon={Maximize2}\n        onClick={onExpand}\n        disabled={!onExpand}\n      >\n        {state === \"expanded\" ? \"Collapse\" : \"Expand\"}\n      </Button>\n      <Button\n        size=\"xs\"\n        variant={state === \"editing\" ? \"secondary\" : \"ghost\"}\n        leadingIcon={Pencil}\n        onClick={onEdit}\n        disabled={!onEdit}\n      >\n        Edit\n      </Button>\n      <Button\n        size=\"xs\"\n        variant={state === \"comparing\" ? \"secondary\" : \"ghost\"}\n        leadingIcon={GitCompare}\n        onClick={onCompare}\n        disabled={!onCompare}\n      >\n        Compare\n      </Button>\n      <Button\n        size=\"xs\"\n        variant=\"ghost\"\n        leadingIcon={saved ? Check : Save}\n        onClick={onSave}\n        disabled={!onSave}\n      >\n        {saved ? \"Saved\" : \"Save\"}\n      </Button>\n      <Button\n        size=\"xs\"\n        variant=\"ghost\"\n        leadingIcon={Share2}\n        onClick={onShare}\n        disabled={!onShare}\n      >\n        Share\n      </Button>\n      <Button\n        size=\"xs\"\n        variant=\"ghost\"\n        leadingIcon={Copy}\n        onClick={onCopy}\n        disabled={!onCopy}\n      >\n        Copy\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-grammar-checker",
      "type": "registry:block",
      "title": "Agent Grammar Checker",
      "description": "agent grammar checker",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-grammar-checker.tsx",
          "target": "@components/agents-ui/agent-grammar-checker.tsx",
          "type": "registry:component",
          "content": "export { AgentGrammarChecker } from \"./application/grammar-checker/grammar-checker\"\nexport type {\n  AgentGrammarCheckerProps,\n  GrammarIssue,\n  GrammarIssueType,\n  GrammarStats,\n} from \"./application/grammar-checker/grammar-checker\"\n"
        },
        {
          "path": "components/agents-ui/application/grammar-checker/grammar-checker.tsx",
          "target": "@components/agents-ui/application/grammar-checker/grammar-checker.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { AlertCircle, Check, Copy, RefreshCw } from \"lucide-react\"\nimport { useState } from \"react\"\n\nexport type GrammarIssueType =\n  | \"grammar\"\n  | \"spelling\"\n  | \"style\"\n  | \"clarity\"\n  | \"punctuation\"\nexport interface GrammarIssue {\n  id: string\n  type: GrammarIssueType\n  message: string\n  suggestion: string\n  position: { start: number; end: number }\n  severity: \"error\" | \"warning\" | \"info\"\n}\nexport interface GrammarStats {\n  wordsCount: number\n  readabilityScore: number\n  issuesFixed: number\n  totalIssues: number\n}\nexport interface AgentGrammarCheckerProps {\n  text?: string\n  originalText?: string\n  issues?: GrammarIssue[]\n  stats?: GrammarStats\n  isAnalyzing?: boolean\n  onTextChange?: (text: string) => void\n  onAcceptSuggestion?: (issueId: string) => void\n  onRejectSuggestion?: (issueId: string) => void\n  onCopy?: () => void\n  onReanalyze?: () => void\n  onRegenerateResponse?: () => void\n  className?: string\n  timestamp?: string\n}\nfunction Stat({ label, value }: { label: string; value: string | number }) {\n  return (\n    <div className=\"flex items-baseline gap-1.5\">\n      <dt className=\"text-text-secondary\">{label}</dt>\n      <dd className=\"font-medium tabular-nums\">{value}</dd>\n    </div>\n  )\n}\nexport function AgentGrammarChecker({\n  text = \"\",\n  originalText = \"\",\n  issues = [],\n  stats,\n  isAnalyzing = false,\n  onTextChange,\n  onAcceptSuggestion,\n  onRejectSuggestion,\n  onCopy,\n  onReanalyze,\n  onRegenerateResponse,\n  className,\n  timestamp = \"Just now\",\n}: AgentGrammarCheckerProps) {\n  const [selected, setSelected] = useState<string | null>(issues[0]?.id ?? null)\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3\">\n        <div>\n          <h3 className=\"text-headline-semibold\">Writing review</h3>\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {isAnalyzing\n              ? \"Analyzing text\"\n              : `${issues.length} suggestions  |  ${timestamp}`}\n          </p>\n        </div>\n        <Button\n          size=\"small\"\n          variant=\"secondary\"\n          leadingIcon={RefreshCw}\n          onClick={onReanalyze}\n          disabled={isAnalyzing}\n        >\n          Analyze again\n        </Button>\n      </header>\n      {stats && (\n        <dl className=\"border-separator-border text-caption-1-regular flex flex-wrap gap-x-5 gap-y-2 border-b px-4 py-2.5\">\n          <Stat label=\"Words\" value={stats.wordsCount} />\n          <Stat label=\"Readability\" value={`${stats.readabilityScore}/100`} />\n          <Stat label=\"Fixed\" value={stats.issuesFixed} />\n          <Stat label=\"Remaining\" value={stats.totalIssues} />\n        </dl>\n      )}\n      <div className=\"grid md:grid-cols-[minmax(0,1fr)_300px]\">\n        <div className=\"p-4\">\n          <label className=\"block\">\n            <span className=\"text-caption-1-medium text-text-secondary mb-2 block\">\n              Edited text\n            </span>\n            <textarea\n              value={text}\n              onChange={(event) => onTextChange?.(event.target.value)}\n              rows={10}\n              className=\"bg-background-tertiary-default text-body-regular focus:ring-border-button-active w-full resize-y rounded-lg px-3 py-2.5 leading-6 ring-2 ring-transparent outline-none\"\n              placeholder=\"Your reviewed text appears here\"\n            />\n          </label>\n          {originalText && originalText !== text && (\n            <details className=\"bg-background-secondary-default mt-3 rounded-lg px-3 py-2\">\n              <summary className=\"text-caption-1-medium text-text-secondary cursor-pointer\">\n                Original text\n              </summary>\n              <p className=\"text-body-2-regular text-text-secondary mt-2 leading-5 whitespace-pre-wrap\">\n                {originalText}\n              </p>\n            </details>\n          )}\n        </div>\n        <aside className=\"border-separator-border border-t md:border-t-0 md:border-l\">\n          <header className=\"border-separator-border flex min-h-10 items-center gap-2 border-b px-3\">\n            <AlertCircle className=\"text-text-secondary size-4\" />\n            <span className=\"text-caption-1-medium\">Suggestions</span>\n          </header>\n          <div className=\"max-h-[420px] overflow-y-auto\">\n            {issues.map((issue) => (\n              <article\n                key={issue.id}\n                className={cx(\n                  \"border-separator-border border-b p-3\",\n                  selected === issue.id && \"bg-background-secondary-default\"\n                )}\n              >\n                <button\n                  type=\"button\"\n                  onClick={() => setSelected(issue.id)}\n                  className=\"w-full text-left\"\n                >\n                  <div className=\"flex justify-between gap-2\">\n                    <span className=\"text-caption-1-medium capitalize\">\n                      {issue.type}\n                    </span>\n                    <span\n                      className={cx(\n                        \"text-caption-1-regular capitalize\",\n                        issue.severity === \"error\"\n                          ? \"text-text-error-placeholder\"\n                          : \"text-text-secondary\"\n                      )}\n                    >\n                      {issue.severity}\n                    </span>\n                  </div>\n                  <p className=\"text-body-2-regular text-text-secondary mt-1 leading-5\">\n                    {issue.message}\n                  </p>\n                  <p className=\"text-body-medium mt-2\">{issue.suggestion}</p>\n                </button>\n                <div className=\"mt-3 flex gap-2\">\n                  <Button\n                    size=\"small\"\n                    leadingIcon={Check}\n                    onClick={() => {\n                      onAcceptSuggestion?.(issue.id)\n                      setSelected(null)\n                    }}\n                  >\n                    Accept\n                  </Button>\n                  <Button\n                    size=\"small\"\n                    variant=\"ghost\"\n                    onClick={() => {\n                      onRejectSuggestion?.(issue.id)\n                      setSelected(null)\n                    }}\n                  >\n                    Ignore\n                  </Button>\n                </div>\n              </article>\n            ))}\n            {issues.length === 0 && (\n              <p className=\"text-body-2-regular text-text-secondary p-6 text-center\">\n                No suggestions found.\n              </p>\n            )}\n          </div>\n        </aside>\n      </div>\n      {(onCopy || onRegenerateResponse) && (\n        <footer className=\"border-separator-border flex gap-1 border-t px-3 py-2\">\n          {onCopy && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Copy}\n              onClick={onCopy}\n            >\n              Copy\n            </Button>\n          )}\n          {onRegenerateResponse && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={RefreshCw}\n              onClick={onRegenerateResponse}\n            >\n              Regenerate\n            </Button>\n          )}\n        </footer>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-image-editor",
      "type": "registry:block",
      "title": "Agent Image Editor",
      "description": "agent image editor",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-image-editor.tsx",
          "target": "@components/agents-ui/agent-image-editor.tsx",
          "type": "registry:component",
          "content": "export { AgentImageEditor } from \"./application/media/image-editor\"\nexport type {\n  AgentImageEditorProps,\n  ImageVariation,\n} from \"./application/media/image-editor\"\n"
        },
        {
          "path": "components/agents-ui/application/media/image-editor.tsx",
          "target": "@components/agents-ui/application/media/image-editor.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n/* eslint-disable @next/next/no-img-element */\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  Copy,\n  Download,\n  Image as ImageIcon,\n  Plus,\n  RefreshCw,\n  Sliders,\n  Wand2,\n} from \"lucide-react\"\nimport { useState } from \"react\"\n\nexport interface ImageVariation {\n  id: string\n  url: string\n  label: string\n  timestamp: string\n}\nexport interface AgentImageEditorProps {\n  imageUrl?: string\n  variations?: ImageVariation[]\n  currentVariation?: string\n  isGenerating?: boolean\n  onExport?: (format?: \"png\" | \"jpg\" | \"webp\") => void\n  onCopy?: () => void\n  onCreateVariation?: () => void\n  onAdjust?: () => void\n  onEnhance?: () => void\n  onRegenerateResponse?: () => void\n  className?: string\n  agentAvatar?: string\n  timestamp?: string\n}\n\nexport function AgentImageEditor({\n  imageUrl,\n  variations = [],\n  currentVariation,\n  isGenerating = false,\n  onExport,\n  onCopy,\n  onCreateVariation,\n  onAdjust,\n  onEnhance,\n  onRegenerateResponse,\n  className,\n  timestamp = \"Just now\",\n}: AgentImageEditorProps) {\n  const [isExporting, setIsExporting] = useState(false)\n  const [isCreatingVariation, setIsCreatingVariation] = useState(false)\n  const current =\n    variations.find((item) => item.id === currentVariation) ?? variations[0]\n  const handleExport = async () => {\n    if (!imageUrl || isGenerating || isExporting) return\n    setIsExporting(true)\n    try {\n      await onExport?.()\n    } finally {\n      setIsExporting(false)\n    }\n  }\n  const handleVariation = async () => {\n    if (isGenerating || isCreatingVariation) return\n    setIsCreatingVariation(true)\n    try {\n      await onCreateVariation?.()\n    } finally {\n      setIsCreatingVariation(false)\n    }\n  }\n\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-2 border-b px-4 py-3\">\n        <div>\n          <h3 className=\"text-headline-semibold\">\n            {current?.label ?? \"Image output\"}\n          </h3>\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {isGenerating\n              ? \"Generating image\"\n              : isExporting\n                ? \"Preparing export\"\n                : isCreatingVariation\n                  ? \"Creating variation\"\n                  : `${variations.length || 1} versions  |  ${timestamp}`}\n          </p>\n        </div>\n        <div className=\"flex gap-1\">\n          {onAdjust && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Sliders}\n              onClick={onAdjust}\n            >\n              Adjust\n            </Button>\n          )}\n          {onEnhance && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Wand2}\n              onClick={onEnhance}\n            >\n              Enhance\n            </Button>\n          )}\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={isExporting ? RefreshCw : Download}\n            onClick={handleExport}\n            disabled={!imageUrl || isGenerating || isExporting}\n          >\n            {isExporting ? \"Exporting\" : \"Export\"}\n          </Button>\n        </div>\n      </header>\n      <div className=\"bg-background-secondary-default relative p-4\">\n        <div className=\"bg-background-primary-default grid min-h-72 place-items-center overflow-hidden rounded-lg\">\n          {imageUrl ? (\n            <img\n              src={imageUrl}\n              alt={current?.label || \"Generated image\"}\n              className=\"max-h-[520px] w-full object-contain\"\n            />\n          ) : (\n            <div className=\"text-text-secondary text-center\">\n              <ImageIcon className=\"mx-auto size-8\" />\n              <p className=\"text-body-2-regular mt-2\">\n                {isGenerating ? \"Generating preview\" : \"No image available\"}\n              </p>\n            </div>\n          )}\n        </div>\n        {isGenerating && (\n          <div className=\"bg-border-button-default absolute inset-x-4 top-4 h-0.5\">\n            <span className=\"bg-text-primary block h-full w-1/2 animate-pulse\" />\n          </div>\n        )}\n      </div>\n      <footer className=\"border-separator-border flex flex-wrap gap-1 border-t px-3 py-2\">\n        {onCreateVariation && (\n          <Button\n            size=\"small\"\n            variant=\"ghost\"\n            leadingIcon={isCreatingVariation ? RefreshCw : Plus}\n            onClick={handleVariation}\n            disabled={isGenerating || isCreatingVariation}\n          >\n            {isCreatingVariation ? \"Creating variation\" : \"Create variation\"}\n          </Button>\n        )}\n        {onCopy && (\n          <Button\n            size=\"small\"\n            variant=\"ghost\"\n            leadingIcon={Copy}\n            onClick={onCopy}\n          >\n            Copy\n          </Button>\n        )}\n        {onRegenerateResponse && (\n          <Button\n            size=\"small\"\n            variant=\"ghost\"\n            leadingIcon={RefreshCw}\n            onClick={onRegenerateResponse}\n          >\n            Regenerate\n          </Button>\n        )}\n      </footer>\n      {variations.length > 0 && (\n        <div className=\"border-separator-border border-t px-4 py-3\">\n          <h4 className=\"text-caption-1-medium text-text-secondary mb-2\">\n            Versions\n          </h4>\n          <div className=\"flex gap-2 overflow-x-auto\">\n            {variations.map((item) => (\n              <figure\n                key={item.id}\n                className={cx(\n                  \"bg-background-secondary-default w-28 shrink-0 overflow-hidden rounded-lg border\",\n                  item.id === current?.id\n                    ? \"border-border-focus-ring\"\n                    : \"border-separator-border\"\n                )}\n              >\n                <img\n                  src={item.url}\n                  alt=\"\"\n                  className=\"h-16 w-full object-cover\"\n                />\n                <figcaption className=\"text-caption-1-regular truncate px-2 py-1.5\">\n                  {item.label}\n                </figcaption>\n              </figure>\n            ))}\n          </div>\n        </div>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-inquiry",
      "type": "registry:block",
      "title": "Agent Inquiry",
      "description": "agent inquiry",
      "dependencies": [
        "@remixicon/react@^4.9.0",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-inquiry.tsx",
          "target": "@components/agents-ui/agent-inquiry.tsx",
          "type": "registry:component",
          "content": "export { AgentInquiry } from \"./application/inquiry/inquiry\"\nexport type {\n  AgentInquiryProps,\n  Inquiry,\n  InquiryHistoryItem,\n  InquiryType,\n} from \"./application/inquiry/inquiry\"\n"
        },
        {
          "path": "components/agents-ui/application/inquiry/inquiry.tsx",
          "target": "@components/agents-ui/application/inquiry/inquiry.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Input } from \"@/components/boardui/base/input/input\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, ChevronRight, Send, SkipForward } from \"lucide-react\"\nimport { useState } from \"react\"\n\nexport type InquiryType = \"multipleChoice\" | \"text\" | \"confirmation\" | \"scale\"\nexport interface Inquiry {\n  id: string\n  question: string\n  type: InquiryType\n  options?: string[]\n  required?: boolean\n}\nexport interface InquiryHistoryItem {\n  question: string\n  answer: string\n  timestamp: string\n}\nexport interface AgentInquiryProps {\n  agentName?: string\n  taskContext?: string\n  inquiry?: Inquiry\n  inquiryHistory?: InquiryHistoryItem[]\n  remainingInquiries?: number\n  className?: string\n  onSubmit?: (inquiryId: string, answer: string) => void\n  onSkip?: (inquiryId: string) => void\n}\nconst defaultInquiry: Inquiry = {\n  id: \"inq-1\",\n  question: \"Which migration strategy do you prefer?\",\n  type: \"multipleChoice\",\n  options: [\"Blue-green deployment\", \"Rolling migration\", \"Canary release\"],\n  required: true,\n}\nexport function AgentInquiry({\n  agentName = \"Migration agent\",\n  taskContext = \"Database migration plan\",\n  inquiry = defaultInquiry,\n  inquiryHistory = [],\n  remainingInquiries = 0,\n  className,\n  onSubmit,\n  onSkip,\n}: AgentInquiryProps) {\n  const [selected, setSelected] = useState(\"\")\n  const [text, setText] = useState(\"\")\n  const answer = inquiry.type === \"text\" ? text : selected\n  const canSubmit = !inquiry.required || Boolean(answer)\n  const submit = () => {\n    if (canSubmit) onSubmit?.(inquiry.id, answer)\n  }\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3\">\n        <div>\n          <h3 className=\"text-headline-semibold\">Input required</h3>\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {agentName} | {taskContext}\n          </p>\n        </div>\n        <span className=\"text-caption-1-regular text-text-secondary\">\n          {remainingInquiries > 0\n            ? `${remainingInquiries + 1} decisions remaining`\n            : \"Final decision\"}\n        </span>\n      </header>\n      {inquiryHistory.length > 0 && (\n        <details className=\"border-separator-border border-b\">\n          <summary className=\"text-caption-1-medium text-text-secondary flex min-h-10 cursor-pointer items-center gap-2 px-4\">\n            Previous decisions <span>{inquiryHistory.length}</span>\n            <ChevronRight className=\"ml-auto size-4\" />\n          </summary>\n          <dl className=\"divide-separator-border bg-background-secondary-default divide-y\">\n            {inquiryHistory.map((item, index) => (\n              <div\n                key={`${item.timestamp}-${index}`}\n                className=\"grid gap-1 px-4 py-3 sm:grid-cols-[1fr_1fr_auto]\"\n              >\n                <dt className=\"text-body-2-regular text-text-secondary\">\n                  {item.question}\n                </dt>\n                <dd className=\"text-body-medium\">{item.answer}</dd>\n                <dd className=\"text-caption-1-regular text-text-tertiary\">\n                  {item.timestamp}\n                </dd>\n              </div>\n            ))}\n          </dl>\n        </details>\n      )}\n      <div className=\"space-y-4 p-4\">\n        <div>\n          <p className=\"text-body-medium leading-6\">{inquiry.question}</p>\n          {inquiry.required && (\n            <p className=\"text-caption-1-regular text-text-secondary mt-1\">\n              A response is required to continue.\n            </p>\n          )}\n        </div>\n        {inquiry.type === \"multipleChoice\" && (\n          <div className=\"divide-separator-border border-separator-border divide-y overflow-hidden rounded-lg border\">\n            {inquiry.options?.map((option) => (\n              <button\n                key={option}\n                type=\"button\"\n                onClick={() => setSelected(option)}\n                className={cx(\n                  \"hover:bg-background-secondary-hover flex min-h-11 w-full items-center gap-3 px-3 text-left\",\n                  selected === option && \"bg-background-secondary-default\"\n                )}\n              >\n                <span\n                  className={cx(\n                    \"border-border-button-default grid size-4 place-items-center rounded-full border\",\n                    selected === option &&\n                      \"border-button-primary bg-button-primary text-text-white\"\n                  )}\n                >\n                  {selected === option && <Check className=\"size-3\" />}\n                </span>\n                <span className=\"text-body-2-regular\">{option}</span>\n              </button>\n            ))}\n          </div>\n        )}\n        {inquiry.type === \"confirmation\" && (\n          <div className=\"flex gap-2\">\n            <Button\n              size=\"small\"\n              variant={selected === \"Yes\" ? \"primary\" : \"secondary\"}\n              onClick={() => setSelected(\"Yes\")}\n            >\n              Yes, proceed\n            </Button>\n            <Button\n              size=\"small\"\n              variant={selected === \"No\" ? \"primary\" : \"secondary\"}\n              onClick={() => setSelected(\"No\")}\n            >\n              No, skip\n            </Button>\n          </div>\n        )}\n        {inquiry.type === \"scale\" && (\n          <div className=\"flex gap-2\" role=\"radiogroup\" aria-label=\"Rating\">\n            {[1, 2, 3, 4, 5].map((rating) => (\n              <Button\n                key={rating}\n                size=\"small\"\n                variant={selected === String(rating) ? \"primary\" : \"secondary\"}\n                onClick={() => setSelected(String(rating))}\n              >\n                {rating}\n              </Button>\n            ))}\n          </div>\n        )}\n        {inquiry.type === \"text\" && (\n          <Input\n            value={text}\n            onChange={setText}\n            onKeyDown={(event) => {\n              if (event.key === \"Enter\") submit()\n            }}\n            placeholder=\"Enter your response\"\n          />\n        )}\n      </div>\n      <footer className=\"border-separator-border flex gap-2 border-t px-4 py-3\">\n        <Button\n          size=\"small\"\n          leadingIcon={Send}\n          disabled={!canSubmit}\n          onClick={submit}\n        >\n          Submit answer\n        </Button>\n        {!inquiry.required && (\n          <Button\n            size=\"small\"\n            variant=\"ghost\"\n            leadingIcon={SkipForward}\n            onClick={() => onSkip?.(inquiry.id)}\n          >\n            Skip\n          </Button>\n        )}\n      </footer>\n    </section>\n  )\n}\nAgentInquiry.displayName = \"AgentInquiry\"\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/input/input.tsx",
          "target": "@components/boardui/base/input/input.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  createContext,\n  useContext,\n  type ComponentType,\n  type ReactNode,\n  type Ref,\n} from \"react\";\nimport {\n  Group as AriaGroup,\n  Input as AriaInput,\n  TextField as AriaTextField,\n} from \"react-aria-components\";\nimport type {\n  InputProps as AriaInputProps,\n  TextFieldProps as AriaTextFieldProps,\n} from \"react-aria-components\";\nimport { Label } from \"./label\";\nimport { HintText } from \"./hint-text\";\nimport { cx, sortCx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Figma source: Board UI → Input (node 3665:1849).\n *\n * Architecture (mirrors the Untitled UI / React Aria pattern):\n *\n *   InputBase   - the styled field shell. Renders <AriaGroup> + adornments\n *                 + <AriaInput>. State (hover / focus / disabled / invalid)\n *                 arrives as render-prop booleans from Aria.\n *   TextField   - wraps <AriaTextField> and a TextFieldContext so size /\n *                 classes can flow from the composer down into InputBase\n *                 without prop drilling.\n *   Input       - opinionated composition: TextField → Label → InputBase\n *                 → HintText. The component most consumers use.\n *\n * Why React Aria:\n *   - Label ↔ input ↔ hint association via aria-labelledby / aria-describedby\n *   - aria-required, aria-invalid auto-applied\n *   - Form library / native validation integration\n *   - i18n, RTL, autofill edge cases handled\n *   - Render-prop state surfaces `isFocusWithin`, `isHovered`, `isDisabled`,\n *     `isInvalid`, `isRequired` - no CSS pseudo gymnastics\n *\n * Visuals stay 1:1 with Figma - see `styles/theme.css` for the tokens.\n */\n\ntype InputSize = \"medium\" | \"small\";\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\n/* -------------------------------------------------------------------------- */\n/*  TextFieldContext                                                           */\n/* -------------------------------------------------------------------------- */\n\ninterface TextFieldContextValue {\n  size?: InputSize;\n  fieldClassName?: string;\n  inputClassName?: string;\n}\n\nconst TextFieldContext = createContext<TextFieldContextValue>({});\n\n/* -------------------------------------------------------------------------- */\n/*  TextField                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface TextFieldProps\n  extends Omit<AriaTextFieldProps, \"className\">,\n    TextFieldContextValue {\n  className?: string;\n  children?: ReactNode | ((state: { isRequired: boolean; isInvalid: boolean; isDisabled: boolean; isReadOnly: boolean }) => ReactNode);\n}\n\nexport function TextField({\n  size = \"medium\",\n  fieldClassName,\n  inputClassName,\n  className,\n  children,\n  ...props\n}: TextFieldProps) {\n  return (\n    <TextFieldContext.Provider value={{ size, fieldClassName, inputClassName }}>\n      <AriaTextField\n        {...props}\n        data-input-size={size}\n        className={cx(\n          \"group flex h-max w-full flex-col items-start gap-1\",\n          className,\n        )}\n      >\n        {children as never /* RAC accepts render-prop children */}\n      </AriaTextField>\n    </TextFieldContext.Provider>\n  );\n}\n\nTextField.displayName = \"TextField\";\n\n/* -------------------------------------------------------------------------- */\n/*  InputBase                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputBaseProps extends Omit<AriaInputProps, \"size\" | \"className\"> {\n  size?: InputSize;\n  className?: string;\n  leadingIcon?: IconComponent;\n  trailingIcon?: IconComponent;\n  /** Custom element rendered in the leading slot (Phone basic uses this). */\n  leadingAddon?: ReactNode;\n  /** Class for the field shell. */\n  fieldClassName?: string;\n  /** Ref to the <input> element. */\n  ref?: Ref<HTMLInputElement>;\n  /** Ref to the field shell wrapper. */\n  groupRef?: Ref<HTMLDivElement>;\n}\n\nconst inputStyles = sortCx({\n  field: [\n    \"relative flex w-full items-center\",\n    \"rounded-2lg\",\n    \"bg-background-tertiary-default text-foreground-icon-tertiary\",\n    \"ring-2 ring-inset ring-transparent\",\n    \"transition-[background-color,box-shadow,color] duration-[var(--input-transition-ms)] ease\",\n  ].join(\" \"),\n\n  fieldSize: {\n    medium: \"p-2\",                // 8px all sides → h auto = 36\n    small:  \"h-8 px-1.5 py-2\",    // 32 / 6 / 8\n  },\n\n  // When a leadingAddon is present (Phone basic): tighten left padding.\n  fieldWithAddonSize: {\n    medium: \"h-9 pl-1 pr-2 py-2\", // 36 / 4 / 8 / 8\n    small:  \"h-8 pl-1 pr-1.5 py-2\",\n  },\n\n  content: \"flex w-full items-center gap-2 min-w-0\",\n  leftSection: \"flex flex-1 items-center gap-0.5 min-w-0\",\n\n  input: [\n    \"min-w-0 flex-1 bg-transparent border-0 outline-none p-0 m-0\",\n    \"font-sans text-body-regular text-text-primary pl-1\",\n    \"placeholder:text-text-tertiary\",\n    \"focus:placeholder:text-text-primary\",\n    \"disabled:text-input-disabled-text disabled:placeholder:text-input-disabled-text\",\n    \"disabled:cursor-not-allowed\",\n    \"aria-invalid:placeholder:text-text-error-placeholder\",\n  ].join(\" \"),\n\n  icon: \"size-5 shrink-0\",\n});\n\nexport function InputBase({\n  size: sizeProp,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  leadingAddon,\n  fieldClassName,\n  className,\n  ref,\n  groupRef,\n  ...inputProps\n}: InputBaseProps) {\n  const ctx = useContext(TextFieldContext);\n  const size: InputSize = sizeProp ?? ctx.size ?? \"medium\";\n  const hasAddon = leadingAddon !== undefined && leadingAddon !== null;\n\n  return (\n    <AriaGroup\n      ref={groupRef}\n      className={({ isFocusWithin, isHovered, isDisabled, isInvalid }) =>\n        cx(\n          inputStyles.field,\n          hasAddon\n            ? inputStyles.fieldWithAddonSize[size]\n            : inputStyles.fieldSize[size],\n          // Hover: idle, no focus, no disabled, no invalid\n          isHovered &&\n            !isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-hover\",\n          // Focus wins over hover\n          isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-active\",\n          // Disabled\n          isDisabled &&\n            \"bg-input-disabled-background text-input-disabled-foreground\",\n          // Invalid\n          isInvalid && \"bg-background-tertiary-error text-foreground-icon-error\",\n          ctx.fieldClassName,\n          fieldClassName,\n        )\n      }\n    >\n      <div className={inputStyles.content}>\n        <div className={inputStyles.leftSection}>\n          {hasAddon ? (\n            leadingAddon\n          ) : Leading ? (\n            <Leading className={inputStyles.icon} aria-hidden />\n          ) : null}\n          <AriaInput\n            ref={ref}\n            {...inputProps}\n            className={cx(inputStyles.input, ctx.inputClassName, className)}\n          />\n        </div>\n        {Trailing ? (\n          <Trailing className={inputStyles.icon} aria-hidden />\n        ) : null}\n      </div>\n    </AriaGroup>\n  );\n}\n\nInputBase.displayName = \"InputBase\";\n\n/* -------------------------------------------------------------------------- */\n/*  Input (composed)                                                           */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputProps\n  extends Omit<TextFieldProps, \"children\">,\n    Pick<\n      InputBaseProps,\n      | \"leadingIcon\"\n      | \"trailingIcon\"\n      | \"leadingAddon\"\n      | \"fieldClassName\"\n      | \"groupRef\"\n      | \"ref\"\n    > {\n  label?: ReactNode;\n  hint?: ReactNode;\n  /** Show an info icon next to the label. Replace with tooltip when Tooltip lands. */\n  tooltip?: boolean | string;\n  placeholder?: string;\n}\n\nexport function Input({\n  label,\n  hint,\n  tooltip,\n  placeholder,\n  leadingIcon,\n  trailingIcon,\n  leadingAddon,\n  fieldClassName,\n  ref,\n  groupRef,\n  className,\n  ...textFieldProps\n}: InputProps) {\n  return (\n    <TextField\n      {...textFieldProps}\n      className={className}\n      // Don't clobber an explicit aria-label; fall back to the placeholder\n      // only for unlabelled fields that don't provide one.\n      aria-label={\n        textFieldProps[\"aria-label\"] ??\n        (!label && typeof placeholder === \"string\" ? placeholder : undefined)\n      }\n    >\n      {({ isRequired, isInvalid }) => (\n        <>\n          {label && (\n            <Label\n              isRequired={isRequired}\n              isInvalid={isInvalid}\n              tooltip={tooltip}\n            >\n              {label}\n            </Label>\n          )}\n          <InputBase\n            ref={ref}\n            groupRef={groupRef}\n            placeholder={placeholder}\n            leadingIcon={leadingIcon}\n            trailingIcon={trailingIcon}\n            leadingAddon={leadingAddon}\n            fieldClassName={fieldClassName}\n          />\n          {hint && <HintText isInvalid={isInvalid}>{hint}</HintText>}\n        </>\n      )}\n    </TextField>\n  );\n}\n\nInput.displayName = \"Input\";\n"
        },
        {
          "path": "components/boardui/base/input/label.tsx",
          "target": "@components/boardui/base/input/label.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport { RiInformationFill } from \"@remixicon/react\";\nimport type { LabelProps as AriaLabelProps } from \"react-aria-components\";\nimport { Label as AriaLabel } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Field label. Wraps `react-aria-components`' Label so the parent `TextField`\n * automatically wires `htmlFor` / `aria-labelledby`.\n *\n * Visuals come from Figma:\n *   - Inter Medium 14/20, color text/primary\n *   - 2px gap between label + required asterisk + info icon\n *   - asterisk is text/error-primary (red/500)\n *   - info icon is 16×16 in foreground/icon/quaternary\n *\n * Pass `isRequired` to show the asterisk. Pass `tooltip` to show the info\n * icon (currently a static glyph - when the Tooltip component lands it'll\n * wire up here).\n */\n\nexport interface LabelProps extends AriaLabelProps {\n  children: ReactNode;\n  isRequired?: boolean;\n  /** Reserved for invalid-aware styling (asterisk color, etc.) once we need it. */\n  isInvalid?: boolean;\n  /** Show the info icon next to the label. */\n  tooltip?: boolean | string;\n  ref?: Ref<HTMLLabelElement>;\n}\n\nexport function Label({\n  isRequired = false,\n  isInvalid: _isInvalid,\n  tooltip,\n  className,\n  children,\n  ...props\n}: LabelProps) {\n  void _isInvalid;\n  return (\n    <AriaLabel\n      data-label=\"true\"\n      {...props}\n      className={cx(\n        \"flex cursor-default items-center gap-0.5\",\n        \"text-body-medium text-text-primary\",\n        className,\n      )}\n    >\n      {children}\n      {isRequired && (\n        <span\n          aria-hidden=\"true\"\n          className=\"text-body-medium text-text-error-primary\"\n        >\n          *\n        </span>\n      )}\n      {tooltip && (\n        <RiInformationFill\n          className=\"size-4 shrink-0 text-foreground-icon-quaternary\"\n          aria-hidden\n        />\n      )}\n    </AriaLabel>\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/input/hint-text.tsx",
          "target": "@components/boardui/base/input/hint-text.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport type { TextProps as AriaTextProps } from \"react-aria-components\";\nimport { Text as AriaText } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Caption text rendered below a field. Wraps `react-aria-components`' Text\n * so the parent `TextField` automatically wires `aria-describedby` (when\n * `slot=\"description\"`) or `aria-errormessage` (when `slot=\"errorMessage\"`).\n *\n * Visuals come from Figma:\n *   - Inter Medium 12/16, letter-spacing 0.15px\n *   - color text/secondary (default) or text/error-primary (invalid)\n *   - 1px top padding to align with the field's bottom edge\n */\n\nexport interface HintTextProps extends AriaTextProps {\n  children: ReactNode;\n  isInvalid?: boolean;\n  ref?: Ref<HTMLElement>;\n}\n\nexport function HintText({\n  isInvalid = false,\n  className,\n  ...props\n}: HintTextProps) {\n  return (\n    <AriaText\n      slot={isInvalid ? \"errorMessage\" : \"description\"}\n      {...props}\n      className={cx(\n        \"pt-px text-caption-1-medium text-text-secondary\",\n        isInvalid && \"text-text-error-primary\",\n        className,\n      )}\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-ops-monitor",
      "type": "registry:block",
      "title": "Agent Ops Monitor",
      "description": "agent ops monitor",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-ops-monitor.tsx",
          "target": "@components/agents-ui/agent-ops-monitor.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { OpsMonitor } from \"@/components/agents-ui/application/ops-monitor/ops-monitor\"\nimport type { AgentOpsMonitorProps } from \"@/components/agents-ui/application/ops-monitor/ops-monitor\"\nimport { createElement } from \"react\"\n\nexport type {\n  AgentOpsMonitorProps,\n  IncidentEvent,\n  OpsServiceMetric,\n  OpsSignal,\n} from \"@/components/agents-ui/application/ops-monitor/ops-monitor\"\nexport function AgentOpsMonitor(props: AgentOpsMonitorProps) {\n  return createElement(OpsMonitor, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/ops-monitor/ops-monitor.tsx",
          "target": "@components/agents-ui/application/ops-monitor/ops-monitor.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cn } from \"@/lib/utils\"\nimport { Check, ChevronDown, Download, TriangleAlert } from \"lucide-react\"\n\nexport interface OpsSignal {\n  id: string\n  title: string\n  status: \"healthy\" | \"warning\" | \"critical\"\n  detail: string\n  owner?: string\n  lastUpdated?: string\n}\nexport interface OpsServiceMetric {\n  label: string\n  value: string\n  threshold: string\n  trend: \"up\" | \"down\" | \"stable\"\n}\nexport interface IncidentEvent {\n  id: string\n  timestamp: string\n  summary: string\n  actionNeeded?: string\n}\nexport interface AgentOpsMonitorProps {\n  environment?: string\n  uptime?: string\n  signals?: OpsSignal[]\n  metrics?: OpsServiceMetric[]\n  incidents?: IncidentEvent[]\n  onAcknowledge?: (signal: OpsSignal) => void\n  onEscalate?: (signal: OpsSignal) => void\n  onExportReport?: () => void\n  className?: string\n}\nconst signalsDefault: OpsSignal[] = [\n  {\n    id: \"latency\",\n    title: \"Latency increased in US East\",\n    status: \"critical\",\n    detail: \"P95 latency increased from 410 ms to 930 ms over five minutes.\",\n    owner: \"Platform on-call\",\n    lastUpdated: \"2 min ago\",\n  },\n  {\n    id: \"drift\",\n    title: \"Embedding quality drift\",\n    status: \"warning\",\n    detail:\n      \"Evaluation accuracy decreased by 4.8 points against the reference set.\",\n    owner: \"Search team\",\n    lastUpdated: \"8 min ago\",\n  },\n  {\n    id: \"backup\",\n    title: \"Backup pipeline\",\n    status: \"healthy\",\n    detail: \"Nightly backup completed with no errors.\",\n    owner: \"Infrastructure\",\n    lastUpdated: \"Completed\",\n  },\n]\nconst metricsDefault: OpsServiceMetric[] = [\n  {\n    label: \"P95 latency\",\n    value: \"930 ms\",\n    threshold: \"Below 550 ms\",\n    trend: \"up\",\n  },\n  { label: \"Error rate\", value: \"0.8%\", threshold: \"Below 1%\", trend: \"down\" },\n  {\n    label: \"Availability\",\n    value: \"99.7%\",\n    threshold: \"Above 99.9%\",\n    trend: \"stable\",\n  },\n]\nconst incidentsDefault: IncidentEvent[] = [\n  {\n    id: \"1\",\n    timestamp: \"06:42\",\n    summary: \"Failover to EU West orchestrator\",\n    actionNeeded: \"Monitor\",\n  },\n  {\n    id: \"2\",\n    timestamp: \"06:55\",\n    summary: \"Customer impact flagged for priority accounts\",\n    actionNeeded: \"Support notified\",\n  },\n]\nconst signalTone: Record<OpsSignal[\"status\"], string> = {\n  healthy: \"text-green-600\",\n  warning: \"text-amber-700\",\n  critical: \"text-red-600\",\n}\nexport function OpsMonitor({\n  environment = \"Production\",\n  uptime = \"99.97%\",\n  signals = signalsDefault,\n  metrics = metricsDefault,\n  incidents = incidentsDefault,\n  onAcknowledge,\n  onEscalate,\n  onExportReport,\n  className,\n}: AgentOpsMonitorProps) {\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-start sm:justify-between\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">\n            {environment} environment\n          </p>\n          <h2 className=\"text-text-primary mt-1 text-lg font-semibold\">\n            Operations status\n          </h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">\n            Uptime {uptime} · {signals.length} active signals\n          </p>\n        </div>\n        <Button\n          size=\"small\"\n          variant=\"secondary\"\n          leadingIcon={Download}\n          onClick={onExportReport}\n        >\n          Export report\n        </Button>\n      </header>\n      <div>\n        {signals.map((signal) => (\n          <article\n            key={signal.id}\n            className=\"border-separator-border flex flex-col gap-3 border-b px-4 py-3 sm:flex-row sm:items-start\"\n          >\n            <div className=\"min-w-0 flex-1\">\n              <div className=\"flex flex-wrap gap-x-3\">\n                <h3 className=\"text-text-primary text-sm font-medium\">\n                  {signal.title}\n                </h3>\n                <span\n                  className={cn(\n                    \"text-xs capitalize\",\n                    signalTone[signal.status]\n                  )}\n                >\n                  {signal.status}\n                </span>\n              </div>\n              <p className=\"text-text-secondary mt-1 text-xs leading-5\">\n                {signal.detail}\n              </p>\n              <div className=\"text-text-secondary mt-2 flex gap-3 text-xs\">\n                <span>{signal.owner || \"Unassigned\"}</span>\n                <span>{signal.lastUpdated || \"Just now\"}</span>\n              </div>\n            </div>\n            <div className=\"flex gap-2\">\n              <Button\n                size=\"xs\"\n                variant=\"secondary\"\n                leadingIcon={Check}\n                onClick={() => onAcknowledge?.(signal)}\n              >\n                Acknowledge\n              </Button>\n              {signal.status !== \"healthy\" && (\n                <Button\n                  size=\"xs\"\n                  variant=\"danger\"\n                  leadingIcon={TriangleAlert}\n                  onClick={() => onEscalate?.(signal)}\n                >\n                  Escalate\n                </Button>\n              )}\n            </div>\n          </article>\n        ))}\n      </div>\n      <details className=\"group border-separator-border border-t p-4\">\n        <summary className=\"text-text-primary flex cursor-pointer list-none items-center gap-1 text-xs\">\n          <ChevronDown className=\"size-3.5 transition-transform group-open:rotate-180\" />\n          Service metrics and incidents\n        </summary>\n        <div className=\"mt-3 grid gap-4 lg:grid-cols-2\">\n          <div className=\"divide-separator-border bg-background-secondary-default divide-y rounded-lg px-3\">\n            {metrics.map((metric) => (\n              <div\n                key={metric.label}\n                className=\"grid grid-cols-[1fr_auto] gap-3 py-2.5 text-xs\"\n              >\n                <span className=\"text-text-primary\">{metric.label}</span>\n                <span className=\"text-text-secondary text-right\">\n                  {metric.value}\n                  <span className=\"ml-2\">Target {metric.threshold}</span>\n                </span>\n              </div>\n            ))}\n          </div>\n          <div className=\"divide-separator-border bg-background-secondary-default divide-y rounded-lg px-3\">\n            {incidents.map((incident) => (\n              <div\n                key={incident.id}\n                className=\"grid grid-cols-[3.5rem_1fr] gap-3 py-2.5 text-xs\"\n              >\n                <time className=\"text-text-secondary\">\n                  {incident.timestamp}\n                </time>\n                <span className=\"text-text-primary\">\n                  {incident.summary}\n                  {incident.actionNeeded && (\n                    <small className=\"text-text-secondary ml-2\">\n                      {incident.actionNeeded}\n                    </small>\n                  )}\n                </span>\n              </div>\n            ))}\n          </div>\n        </div>\n      </details>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-orchestrator",
      "type": "registry:block",
      "title": "Agent Orchestrator",
      "description": "agent orchestrator",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-orchestrator.tsx",
          "target": "@components/agents-ui/agent-orchestrator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Orchestrator } from \"@/components/agents-ui/application/orchestrator/orchestrator\"\nimport type { AgentOrchestratorProps } from \"@/components/agents-ui/application/orchestrator/orchestrator\"\nimport { createElement } from \"react\"\n\nexport type {\n  AgentOrchestratorProps,\n  CommLogEntry,\n  SubAgent,\n  SubAgentMetrics,\n  SubAgentStatus,\n} from \"@/components/agents-ui/application/orchestrator/orchestrator\"\nexport function AgentOrchestrator(props: AgentOrchestratorProps) {\n  return createElement(Orchestrator, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/orchestrator/orchestrator.tsx",
          "target": "@components/agents-ui/application/orchestrator/orchestrator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDown, Pause, Play, RefreshCw } from \"lucide-react\"\n\nexport type SubAgentStatus = \"idle\" | \"running\" | \"completed\" | \"failed\"\nexport interface SubAgentMetrics {\n  tokens?: number\n  cost?: string\n  latency?: string\n}\nexport interface SubAgent {\n  id: string\n  name: string\n  role: string\n  status: SubAgentStatus\n  task: string\n  progress: number\n  metrics?: SubAgentMetrics\n}\nexport interface CommLogEntry {\n  id: string\n  timestamp: string\n  from: string\n  to: string\n  message: string\n}\nexport interface AgentOrchestratorProps {\n  orchestratorName?: string\n  description?: string\n  subAgents?: SubAgent[]\n  communicationLog?: CommLogEntry[]\n  aggregatedResult?: string\n  isProcessing?: boolean\n  timestamp?: string\n  className?: string\n  onStart?: () => void\n  onPauseAll?: () => void\n  onRedistribute?: () => void\n  onRetryAgent?: (agentId: string) => void\n}\n\nconst workers: SubAgent[] = [\n  {\n    id: \"research\",\n    name: \"Research\",\n    role: \"Source collection\",\n    status: \"completed\",\n    task: \"Collect and rank primary sources\",\n    progress: 100,\n    metrics: { tokens: 3420, cost: \"$0.04\", latency: \"12s\" },\n  },\n  {\n    id: \"analysis\",\n    name: \"Analysis\",\n    role: \"Evidence review\",\n    status: \"running\",\n    task: \"Compare claims and group related evidence\",\n    progress: 64,\n    metrics: { tokens: 1860, cost: \"$0.02\", latency: \"8s\" },\n  },\n  {\n    id: \"writing\",\n    name: \"Writer\",\n    role: \"Brief production\",\n    status: \"idle\",\n    task: \"Draft the brief from approved findings\",\n    progress: 0,\n    metrics: { tokens: 0, cost: \"$0.00\" },\n  },\n]\nconst log: CommLogEntry[] = [\n  {\n    id: \"1\",\n    timestamp: \"09:01\",\n    from: \"Coordinator\",\n    to: \"Research\",\n    message: \"Collect sources and flag conflicting claims.\",\n  },\n  {\n    id: \"2\",\n    timestamp: \"09:13\",\n    from: \"Research\",\n    to: \"Coordinator\",\n    message: \"Twenty sources are ready for analysis.\",\n  },\n  {\n    id: \"3\",\n    timestamp: \"09:14\",\n    from: \"Coordinator\",\n    to: \"Analysis\",\n    message: \"Rank evidence by relevance and confidence.\",\n  },\n]\nconst statusText: Record<SubAgentStatus, string> = {\n  idle: \"Waiting\",\n  running: \"Running\",\n  completed: \"Complete\",\n  failed: \"Failed\",\n}\nconst statusClass: Record<SubAgentStatus, string> = {\n  idle: \"text-text-secondary\",\n  running: \"text-accent-600\",\n  completed: \"text-green-600\",\n  failed: \"text-red-600\",\n}\n\nexport function Orchestrator({\n  orchestratorName = \"Content research run\",\n  description = \"Coordinate research, analysis, and writing as one accountable run.\",\n  subAgents = workers,\n  communicationLog = log,\n  aggregatedResult = \"Research is complete. Analysis is comparing four themes across twenty sources.\",\n  isProcessing = true,\n  timestamp = \"Updated moments ago\",\n  className,\n  onStart,\n  onPauseAll,\n  onRedistribute,\n  onRetryAgent,\n}: AgentOrchestratorProps) {\n  const progress = subAgents.length\n    ? Math.round(\n        subAgents.reduce((sum, item) => sum + item.progress, 0) /\n          subAgents.length\n      )\n    : 0\n  const tokens = subAgents.reduce(\n    (sum, item) => sum + (item.metrics?.tokens || 0),\n    0\n  )\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n      aria-label=\"Agent orchestrator\"\n    >\n      <header className=\"border-separator-border flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-start sm:justify-between\">\n        <div>\n          <div className=\"flex flex-wrap items-center gap-3\">\n            <h2 className=\"text-text-primary text-lg font-semibold\">\n              {orchestratorName}\n            </h2>\n            <span\n              className={cn(\n                \"text-xs\",\n                isProcessing ? \"text-accent-600\" : \"text-green-600\"\n              )}\n            >\n              {isProcessing ? \"Run active\" : \"Run complete\"}\n            </span>\n          </div>\n          <p className=\"text-text-secondary mt-1 max-w-2xl text-sm\">\n            {description}\n          </p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            size=\"small\"\n            leadingIcon={Play}\n            disabled={isProcessing}\n            onClick={onStart}\n          >\n            Start\n          </Button>\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={Pause}\n            onClick={onPauseAll}\n          >\n            Pause all\n          </Button>\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={RefreshCw}\n            onClick={onRedistribute}\n          >\n            Reassign\n          </Button>\n        </div>\n      </header>\n      <div className=\"border-separator-border border-b px-4 py-3\">\n        <div className=\"text-text-secondary flex justify-between text-xs\">\n          <span>\n            {subAgents.filter((item) => item.status === \"completed\").length} of{\" \"}\n            {subAgents.length} workers complete\n          </span>\n          <span>{progress}%</span>\n        </div>\n        <div\n          className=\"bg-background-secondary-default mt-2 h-1.5 overflow-hidden rounded-full\"\n          role=\"progressbar\"\n          aria-label=\"Run progress\"\n          aria-valuenow={progress}\n          aria-valuemin={0}\n          aria-valuemax={100}\n        >\n          <span\n            className=\"bg-accent-500 block h-full\"\n            style={{ width: `${progress}%` }}\n          />\n        </div>\n      </div>\n      <div>\n        {subAgents.map((worker) => (\n          <article\n            key={worker.id}\n            className=\"border-separator-border flex items-start gap-3 border-b px-4 py-3 last:border-0\"\n          >\n            <div className=\"min-w-0 flex-1\">\n              <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1\">\n                <h3 className=\"text-text-primary text-sm font-medium\">\n                  {worker.name}\n                </h3>\n                <span className=\"text-text-secondary text-xs\">\n                  {worker.role}\n                </span>\n                <span className={cn(\"text-xs\", statusClass[worker.status])}>\n                  {statusText[worker.status]}\n                </span>\n              </div>\n              <p className=\"text-text-secondary mt-1 text-xs\">{worker.task}</p>\n              <div className=\"mt-2 flex items-center gap-3\">\n                <div className=\"bg-background-secondary-default h-1.5 flex-1 overflow-hidden rounded-full\">\n                  <span\n                    className=\"bg-accent-500 block h-full\"\n                    style={{ width: `${worker.progress}%` }}\n                  />\n                </div>\n                <span className=\"text-text-secondary text-xs tabular-nums\">\n                  {worker.progress}%\n                </span>\n              </div>\n              {worker.metrics && (\n                <div className=\"text-text-secondary mt-2 flex gap-3 text-xs\">\n                  {worker.metrics.tokens !== undefined && (\n                    <span>{worker.metrics.tokens.toLocaleString()} tokens</span>\n                  )}\n                  {worker.metrics.cost && <span>{worker.metrics.cost}</span>}\n                  {worker.metrics.latency && (\n                    <span>{worker.metrics.latency}</span>\n                  )}\n                </div>\n              )}\n            </div>\n            {worker.status === \"failed\" && (\n              <Button\n                size=\"xs\"\n                variant=\"secondary\"\n                leadingIcon={RefreshCw}\n                onClick={() => onRetryAgent?.(worker.id)}\n              >\n                Retry\n              </Button>\n            )}\n          </article>\n        ))}\n      </div>\n      <div className=\"p-4\">\n        <div className=\"bg-background-secondary-default rounded-lg p-3\">\n          <p className=\"text-text-primary text-xs font-medium\">\n            Current result\n          </p>\n          <p className=\"text-text-secondary mt-1 text-sm\">{aggregatedResult}</p>\n        </div>\n        <details className=\"group mt-3\">\n          <summary className=\"text-text-secondary flex cursor-pointer list-none items-center gap-1 text-xs\">\n            <ChevronDown className=\"size-3.5 transition-transform group-open:rotate-180\" />\n            Communication log\n          </summary>\n          <ol className=\"divide-separator-border bg-background-secondary-default mt-3 divide-y rounded-lg px-3\">\n            {communicationLog.map((entry) => (\n              <li\n                key={entry.id}\n                className=\"grid gap-1 py-2 text-xs sm:grid-cols-[4rem_10rem_1fr]\"\n              >\n                <time className=\"text-text-secondary\">{entry.timestamp}</time>\n                <span className=\"text-text-primary\">\n                  {entry.from} to {entry.to}\n                </span>\n                <span className=\"text-text-secondary\">{entry.message}</span>\n              </li>\n            ))}\n          </ol>\n        </details>\n        <div className=\"border-separator-border text-text-secondary mt-3 flex flex-wrap gap-3 border-t pt-3 text-xs\">\n          <span>{subAgents.length} workers</span>\n          <span>{tokens.toLocaleString()} tokens</span>\n          <span>{timestamp}</span>\n        </div>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-parallel-processor",
      "type": "registry:block",
      "title": "Agent Parallel Processor",
      "description": "agent parallel processor",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-parallel-processor.tsx",
          "target": "@components/agents-ui/agent-parallel-processor.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { ParallelProcessor } from \"@/components/agents-ui/application/parallel-processor/parallel-processor\"\nimport type { AgentParallelProcessorProps } from \"@/components/agents-ui/application/parallel-processor/parallel-processor\"\nimport { createElement } from \"react\"\n\nexport type {\n  AgentParallelProcessorProps,\n  ParallelLane,\n  ParallelLaneStatus,\n} from \"@/components/agents-ui/application/parallel-processor/parallel-processor\"\nexport function AgentParallelProcessor(props: AgentParallelProcessorProps) {\n  return createElement(ParallelProcessor, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/parallel-processor/parallel-processor.tsx",
          "target": "@components/agents-ui/application/parallel-processor/parallel-processor.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDown, Play, RefreshCw, X } from \"lucide-react\"\n\nexport type ParallelLaneStatus = \"waiting\" | \"processing\" | \"done\" | \"error\"\nexport interface ParallelLane {\n  id: string\n  label: string\n  agentName: string\n  status: ParallelLaneStatus\n  progress: number\n  output?: string\n  tokens?: number\n}\nexport interface AgentParallelProcessorProps {\n  taskDescription?: string\n  lanes?: ParallelLane[]\n  mergeStatus?: \"idle\" | \"merging\" | \"complete\"\n  mergedOutput?: string\n  totalTokens?: number\n  totalCost?: string\n  onStartAll?: () => void\n  onCancelAll?: () => void\n  onRetryFailed?: () => void\n  onRetryLane?: (laneId: string) => void\n  className?: string\n}\nconst defaultLanes: ParallelLane[] = [\n  {\n    id: \"sentiment\",\n    label: \"Sentiment analysis\",\n    agentName: \"Analysis worker\",\n    status: \"done\",\n    progress: 100,\n    output: \"Positive sentiment with delivery speed as the strongest theme.\",\n    tokens: 1240,\n  },\n  {\n    id: \"entities\",\n    label: \"Entity extraction\",\n    agentName: \"Entity worker\",\n    status: \"processing\",\n    progress: 64,\n    tokens: 860,\n  },\n  {\n    id: \"topics\",\n    label: \"Topic classification\",\n    agentName: \"Classification worker\",\n    status: \"processing\",\n    progress: 38,\n    tokens: 520,\n  },\n  {\n    id: \"summary\",\n    label: \"Summary generation\",\n    agentName: \"Summary worker\",\n    status: \"waiting\",\n    progress: 0,\n    tokens: 0,\n  },\n]\nconst label: Record<ParallelLaneStatus, string> = {\n  waiting: \"Waiting\",\n  processing: \"Running\",\n  done: \"Complete\",\n  error: \"Failed\",\n}\nconst tone: Record<ParallelLaneStatus, string> = {\n  waiting: \"text-text-secondary\",\n  processing: \"text-accent-600\",\n  done: \"text-green-600\",\n  error: \"text-red-600\",\n}\nexport function ParallelProcessor({\n  taskDescription = \"Analyze product reviews and produce a structured report.\",\n  lanes,\n  mergeStatus = \"idle\",\n  mergedOutput,\n  totalTokens,\n  totalCost,\n  onStartAll,\n  onCancelAll,\n  onRetryFailed,\n  onRetryLane,\n  className,\n}: AgentParallelProcessorProps) {\n  const items = lanes?.length ? lanes : defaultLanes\n  const tokens =\n    totalTokens ?? items.reduce((sum, item) => sum + (item.tokens || 0), 0)\n  const cost = totalCost ?? `$${(tokens * 0.00015).toFixed(2)}`\n  const failed = items.filter((item) => item.status === \"error\").length\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-start sm:justify-between\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">\n            Parallel execution\n          </p>\n          <h2 className=\"text-text-primary mt-1 text-lg font-semibold\">\n            Processing lanes\n          </h2>\n          <p className=\"text-text-secondary mt-1 max-w-2xl text-sm\">\n            {taskDescription}\n          </p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button size=\"small\" leadingIcon={Play} onClick={onStartAll}>\n            Start all\n          </Button>\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={X}\n            onClick={onCancelAll}\n          >\n            Cancel\n          </Button>\n          {failed > 0 && (\n            <Button\n              size=\"small\"\n              variant=\"secondary\"\n              leadingIcon={RefreshCw}\n              onClick={onRetryFailed}\n            >\n              Retry failed\n            </Button>\n          )}\n        </div>\n      </header>\n      <ol>\n        {items.map((lane, index) => (\n          <li\n            key={lane.id}\n            className=\"border-separator-border border-b px-4 py-3 last:border-0\"\n          >\n            <div className=\"flex items-start gap-3\">\n              <span className=\"text-text-secondary w-6 text-xs tabular-nums\">\n                {String(index + 1).padStart(2, \"0\")}\n              </span>\n              <div className=\"min-w-0 flex-1\">\n                <div className=\"flex flex-wrap items-center gap-x-3\">\n                  <h3 className=\"text-text-primary text-sm font-medium\">\n                    {lane.label}\n                  </h3>\n                  <span className=\"text-text-secondary text-xs\">\n                    {lane.agentName}\n                  </span>\n                  <span className={cn(\"text-xs\", tone[lane.status])}>\n                    {label[lane.status]}\n                  </span>\n                </div>\n                <div className=\"mt-2 flex items-center gap-3\">\n                  <div\n                    className=\"bg-background-secondary-default h-1.5 flex-1 overflow-hidden rounded-full\"\n                    role=\"progressbar\"\n                    aria-label={`${lane.label} progress`}\n                    aria-valuenow={lane.progress}\n                    aria-valuemin={0}\n                    aria-valuemax={100}\n                  >\n                    <span\n                      className=\"bg-accent-500 block h-full\"\n                      style={{ width: `${lane.progress}%` }}\n                    />\n                  </div>\n                  <span className=\"text-text-secondary text-xs tabular-nums\">\n                    {lane.progress}%\n                  </span>\n                  {lane.tokens !== undefined && (\n                    <span className=\"text-text-secondary text-xs\">\n                      {lane.tokens.toLocaleString()} tokens\n                    </span>\n                  )}\n                </div>\n                {lane.output && (\n                  <details className=\"group mt-2\">\n                    <summary className=\"text-text-secondary flex cursor-pointer list-none items-center gap-1 text-xs\">\n                      <ChevronDown className=\"size-3.5 transition-transform group-open:rotate-180\" />\n                      Output\n                    </summary>\n                    <p className=\"bg-background-secondary-default text-text-secondary mt-2 rounded-lg p-3 text-xs\">\n                      {lane.output}\n                    </p>\n                  </details>\n                )}\n              </div>\n              {lane.status === \"error\" && (\n                <Button\n                  size=\"xs\"\n                  variant=\"secondary\"\n                  leadingIcon={RefreshCw}\n                  onClick={() => onRetryLane?.(lane.id)}\n                >\n                  Retry\n                </Button>\n              )}\n            </div>\n          </li>\n        ))}\n      </ol>\n      <footer className=\"p-4\">\n        <div className=\"bg-background-secondary-default rounded-lg p-3\">\n          <div className=\"flex gap-3 text-xs\">\n            <span className=\"text-text-primary font-medium\">Merged result</span>\n            <span\n              className={cn(\n                mergeStatus === \"complete\"\n                  ? \"text-green-600\"\n                  : mergeStatus === \"merging\"\n                    ? \"text-accent-600\"\n                    : \"text-text-secondary\"\n              )}\n            >\n              {mergeStatus === \"complete\"\n                ? \"Ready\"\n                : mergeStatus === \"merging\"\n                  ? \"Merging\"\n                  : \"Waiting\"}\n            </span>\n          </div>\n          {mergedOutput && (\n            <p className=\"text-text-secondary mt-2 text-sm\">{mergedOutput}</p>\n          )}\n        </div>\n        <div className=\"border-separator-border text-text-secondary mt-3 flex gap-3 border-t pt-3 text-xs\">\n          <span>{items.length} lanes</span>\n          <span>{tokens.toLocaleString()} tokens</span>\n          <span>{cost}</span>\n        </div>\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-plan-builder",
      "type": "registry:block",
      "title": "Agent Plan Builder",
      "description": "agent plan builder",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-plan-builder.tsx",
          "target": "@components/agents-ui/agent-plan-builder.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { PlanBuilder } from \"@/components/agents-ui/application/plan-builder/plan-builder\"\nimport type { AgentPlanBuilderProps } from \"@/components/agents-ui/application/plan-builder/plan-builder\"\nimport { createElement } from \"react\"\n\nexport type {\n  AgentPlanBuilderProps,\n  PlanStep,\n  PlanStepStatus,\n} from \"@/components/agents-ui/application/plan-builder/plan-builder\"\nexport function AgentPlanBuilder(props: AgentPlanBuilderProps) {\n  return createElement(PlanBuilder, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/plan-builder/plan-builder.tsx",
          "target": "@components/agents-ui/application/plan-builder/plan-builder.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cn } from \"@/lib/utils\"\nimport { Check, ChevronDown, RotateCcw, X } from \"lucide-react\"\n\nexport type PlanStepStatus = \"pending\" | \"approved\" | \"rejected\" | \"modified\"\nexport interface PlanStep {\n  id: string\n  title: string\n  description: string\n  tool: string\n  duration: string\n  dependencies: number[]\n  status: PlanStepStatus\n}\nexport interface AgentPlanBuilderProps {\n  planTitle?: string\n  objective?: string\n  totalEstimate?: string\n  estimatedCost?: string\n  steps?: PlanStep[]\n  confidence?: number\n  onApproveAll?: () => void\n  onRejectPlan?: () => void\n  onRevise?: () => void\n  onApproveStep?: (stepId: string) => void\n  onRejectStep?: (stepId: string) => void\n  className?: string\n}\nconst defaults: PlanStep[] = [\n  {\n    id: \"crawl\",\n    title: \"Crawl site pages\",\n    description:\n      \"Collect public URLs, metadata, status codes, and response times.\",\n    tool: \"Web crawler\",\n    duration: \"8 min\",\n    dependencies: [],\n    status: \"approved\",\n  },\n  {\n    id: \"content\",\n    title: \"Analyze content quality\",\n    description: \"Score readability, topic coverage, and internal links.\",\n    tool: \"Content analyzer\",\n    duration: \"10 min\",\n    dependencies: [1],\n    status: \"pending\",\n  },\n  {\n    id: \"links\",\n    title: \"Check backlink profile\",\n    description: \"Review referring domains, anchors, and risk indicators.\",\n    tool: \"Backlink analysis\",\n    duration: \"6 min\",\n    dependencies: [1],\n    status: \"pending\",\n  },\n  {\n    id: \"report\",\n    title: \"Generate audit report\",\n    description: \"Compile findings into a priority-ranked report.\",\n    tool: \"Report builder\",\n    duration: \"7 min\",\n    dependencies: [2, 3],\n    status: \"rejected\",\n  },\n  {\n    id: \"notify\",\n    title: \"Notify stakeholders\",\n    description: \"Send the approved report to the review team.\",\n    tool: \"Notification service\",\n    duration: \"3 min\",\n    dependencies: [4],\n    status: \"pending\",\n  },\n]\nconst status: Record<PlanStepStatus, string> = {\n  pending: \"Needs review\",\n  approved: \"Approved\",\n  rejected: \"Rejected\",\n  modified: \"Modified\",\n}\nconst tone: Record<PlanStepStatus, string> = {\n  pending: \"text-amber-700\",\n  approved: \"text-green-600\",\n  rejected: \"text-red-600\",\n  modified: \"text-amber-700\",\n}\nexport function PlanBuilder({\n  planTitle = \"SEO audit plan\",\n  objective = \"Audit the site, identify content gaps, and deliver an actionable report.\",\n  totalEstimate = \"34 min\",\n  estimatedCost = \"$1.20\",\n  steps,\n  confidence = 87,\n  onApproveAll,\n  onRejectPlan,\n  onRevise,\n  onApproveStep,\n  onRejectStep,\n  className,\n}: AgentPlanBuilderProps) {\n  const items = steps?.length ? steps : defaults\n  const approved = items.filter((item) => item.status === \"approved\").length\n  const rejected = items.filter((item) => item.status === \"rejected\").length\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-col gap-3 border-b p-4 sm:flex-row sm:justify-between\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">Plan review</p>\n          <h2 className=\"text-text-primary mt-1 text-lg font-semibold\">\n            {planTitle}\n          </h2>\n          <p className=\"text-text-secondary mt-1 max-w-2xl text-sm\">\n            {objective}\n          </p>\n        </div>\n        <div className=\"text-text-primary shrink-0 text-sm\">\n          {confidence}% confidence\n          <p className=\"text-text-secondary mt-1 text-xs\">\n            {totalEstimate} · {estimatedCost}\n          </p>\n        </div>\n      </header>\n      <ol>\n        {items.map((step, index) => (\n          <li\n            key={step.id}\n            className=\"border-separator-border flex items-start gap-3 border-b px-4 py-3 last:border-0\"\n          >\n            <span className=\"text-text-secondary w-6 text-xs\">\n              {String(index + 1).padStart(2, \"0\")}\n            </span>\n            <div className=\"min-w-0 flex-1\">\n              <div className=\"flex flex-wrap gap-x-3\">\n                <h3 className=\"text-text-primary text-sm font-medium\">\n                  {step.title}\n                </h3>\n                <span className={cn(\"text-xs\", tone[step.status])}>\n                  {status[step.status]}\n                </span>\n              </div>\n              <p className=\"text-text-secondary mt-1 text-xs\">\n                {step.description}\n              </p>\n              <div className=\"text-text-secondary mt-2 flex flex-wrap gap-x-3 text-xs\">\n                <span>{step.tool}</span>\n                <span>{step.duration}</span>\n                {step.dependencies.length > 0 && (\n                  <span>\n                    After{\" \"}\n                    {step.dependencies.map((item) => `step ${item}`).join(\", \")}\n                  </span>\n                )}\n              </div>\n            </div>\n            {(step.status === \"pending\" || step.status === \"modified\") && (\n              <div className=\"flex gap-1\">\n                <Button\n                  size=\"xs\"\n                  variant=\"ghost\"\n                  iconOnly\n                  leadingIcon={Check}\n                  aria-label={`Approve ${step.title}`}\n                  onClick={() => onApproveStep?.(step.id)}\n                />\n                <Button\n                  size=\"xs\"\n                  variant=\"ghost\"\n                  iconOnly\n                  leadingIcon={X}\n                  aria-label={`Reject ${step.title}`}\n                  onClick={() => onRejectStep?.(step.id)}\n                />\n              </div>\n            )}\n          </li>\n        ))}\n      </ol>\n      <details className=\"group border-separator-border border-t px-4 py-3\">\n        <summary className=\"text-text-primary flex cursor-pointer list-none items-center gap-1 text-xs\">\n          <ChevronDown className=\"size-3.5 transition-transform group-open:rotate-180\" />\n          Approval summary\n        </summary>\n        <div className=\"bg-background-secondary-default text-text-secondary mt-3 grid gap-2 rounded-lg p-3 text-xs sm:grid-cols-3\">\n          <span>{approved} approved</span>\n          <span>{items.length - approved - rejected} awaiting review</span>\n          <span>{rejected} rejected</span>\n        </div>\n      </details>\n      <footer className=\"border-separator-border flex flex-col gap-3 border-t p-4 sm:flex-row sm:items-center sm:justify-between\">\n        <div className=\"text-text-secondary flex gap-3 text-xs\">\n          <span>{items.length} steps</span>\n          <span>{totalEstimate}</span>\n          <span>{estimatedCost}</span>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={RotateCcw}\n            onClick={onRevise}\n          >\n            Revise\n          </Button>\n          <Button\n            size=\"small\"\n            variant=\"danger\"\n            leadingIcon={X}\n            onClick={onRejectPlan}\n          >\n            Reject\n          </Button>\n          <Button size=\"small\" leadingIcon={Check} onClick={onApproveAll}>\n            Approve plan\n          </Button>\n        </div>\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-prompt-composer",
      "type": "registry:block",
      "title": "Agent Prompt Composer",
      "description": "agent prompt composer",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-prompt-composer.tsx",
          "target": "@components/agents-ui/agent-prompt-composer.tsx",
          "type": "registry:component",
          "content": "export { AgentPromptComposer } from \"./application/prompt-composer/prompt-composer\"\nexport type {\n  AgentPromptComposerProps,\n  Persona,\n  PromptTemplate,\n} from \"./application/prompt-composer/prompt-composer\"\n"
        },
        {
          "path": "components/agents-ui/application/prompt-composer/prompt-composer.tsx",
          "target": "@components/agents-ui/application/prompt-composer/prompt-composer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport {\n  Dropdown,\n  DropdownItem,\n  DropdownPopover,\n  DropdownTrigger,\n} from \"@/components/boardui/base/dropdown/dropdown\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  BookTemplate,\n  ChevronDown,\n  Mic,\n  Paperclip,\n  Send,\n  Settings,\n  Square,\n} from \"lucide-react\"\nimport { useId, useState } from \"react\"\n\nexport type PromptTemplate = {\n  id: string\n  name: string\n  prompt: string\n  description?: string\n}\nexport type Persona = {\n  id: string\n  name: string\n  avatar?: string\n  systemPrompt: string\n  description?: string\n}\nexport interface AgentPromptComposerProps {\n  value?: string\n  onChange?: (value: string) => void\n  onSubmit?: (\n    value: string,\n    options?: { persona?: Persona; template?: PromptTemplate }\n  ) => void\n  placeholder?: string\n  disabled?: boolean\n  isLoading?: boolean\n  templates?: PromptTemplate[]\n  personas?: Persona[]\n  showVoiceInput?: boolean\n  showFileAttachment?: boolean\n  showSettings?: boolean\n  className?: string\n}\n\nexport function AgentPromptComposer({\n  value,\n  onChange,\n  onSubmit,\n  placeholder = \"Ask anything...\",\n  disabled = false,\n  isLoading = false,\n  templates = [],\n  personas = [],\n  showVoiceInput = true,\n  showFileAttachment = true,\n  showSettings = true,\n  className,\n}: AgentPromptComposerProps) {\n  const [draft, setDraft] = useState(\"\")\n  const inputValue = value ?? draft\n  const changeValue = (next: string) => {\n    if (value === undefined) setDraft(next)\n    onChange?.(next)\n  }\n  const fileInputId = useId()\n  const [persona, setPersona] = useState<Persona | null>(null)\n  const [template, setTemplate] = useState<PromptTemplate | null>(null)\n  const [recording, setRecording] = useState(false)\n  const [attachment, setAttachment] = useState<string | null>(null)\n  const [settingsOpen, setSettingsOpen] = useState(false)\n  const submit = () => {\n    if (inputValue.trim() && !disabled && !isLoading)\n      onSubmit?.(inputValue, {\n        persona: persona ?? undefined,\n        template: template ?? undefined,\n      })\n  }\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <div className=\"border-separator-border text-caption-1-medium text-text-secondary flex min-h-10 flex-wrap items-center gap-1 border-b px-3 py-1.5\">\n        {personas.length > 0 && (\n          <Dropdown>\n            <DropdownTrigger className=\"hover:bg-background-secondary-hover inline-flex min-h-8 items-center gap-1.5 rounded-lg px-2\">\n              {persona?.name ?? \"Default assistant\"}\n              <ChevronDown className=\"size-3.5\" />\n            </DropdownTrigger>\n            <DropdownPopover aria-label=\"Select assistant\" className=\"w-64\">\n              <DropdownItem\n                selected={!persona}\n                onSelect={() => setPersona(null)}\n              >\n                <div>\n                  <p className=\"text-body-medium\">Default assistant</p>\n                  <p className=\"text-caption-1-regular text-text-secondary\">\n                    Standard workspace behavior\n                  </p>\n                </div>\n              </DropdownItem>\n              {personas.map((item) => (\n                <DropdownItem\n                  key={item.id}\n                  selected={persona?.id === item.id}\n                  onSelect={() => setPersona(item)}\n                >\n                  <div>\n                    <p className=\"text-body-medium\">{item.name}</p>\n                    {item.description && (\n                      <p className=\"text-caption-1-regular text-text-secondary\">\n                        {item.description}\n                      </p>\n                    )}\n                  </div>\n                </DropdownItem>\n              ))}\n            </DropdownPopover>\n          </Dropdown>\n        )}\n        {templates.length > 0 && (\n          <Dropdown>\n            <DropdownTrigger className=\"hover:bg-background-secondary-hover inline-flex min-h-8 items-center gap-1.5 rounded-lg px-2\">\n              <BookTemplate className=\"size-3.5\" />\n              {template?.name ?? \"Templates\"}\n              <ChevronDown className=\"size-3.5\" />\n            </DropdownTrigger>\n            <DropdownPopover aria-label=\"Prompt templates\" className=\"w-80\">\n              {templates.map((item) => (\n                <DropdownItem\n                  key={item.id}\n                  selected={template?.id === item.id}\n                  onSelect={() => {\n                    setTemplate(item)\n                    changeValue(item.prompt)\n                  }}\n                >\n                  <div>\n                    <p className=\"text-body-medium\">{item.name}</p>\n                    {item.description && (\n                      <p className=\"text-caption-1-regular text-text-secondary\">\n                        {item.description}\n                      </p>\n                    )}\n                  </div>\n                </DropdownItem>\n              ))}\n            </DropdownPopover>\n          </Dropdown>\n        )}\n        {showSettings && (\n          <Button\n            size=\"xs\"\n            variant=\"ghost\"\n            iconOnly\n            leadingIcon={Settings}\n            aria-label=\"Composer settings\"\n            aria-pressed={settingsOpen}\n            onClick={() => setSettingsOpen((open) => !open)}\n          />\n        )}\n      </div>\n      {settingsOpen && (\n        <div className=\"border-separator-border bg-background-secondary-default text-caption-1-regular text-text-secondary border-b px-4 py-2\">\n          Selected assistant and template are included when the prompt is\n          submitted.\n        </div>\n      )}\n      <textarea\n        aria-label=\"Message\"\n        value={inputValue}\n        onChange={(event) => changeValue(event.target.value)}\n        onKeyDown={(event) => {\n          if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n            event.preventDefault()\n            submit()\n          }\n        }}\n        disabled={disabled}\n        placeholder={placeholder}\n        rows={4}\n        className=\"text-body-regular text-text-primary placeholder:text-text-tertiary disabled:text-text-tertiary min-h-24 w-full resize-y bg-transparent px-4 py-3 leading-5 outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-border-focus-ring disabled:cursor-not-allowed\"\n      />\n      <footer className=\"border-separator-border flex min-h-12 flex-wrap items-center justify-between gap-2 border-t px-2.5 py-2\">\n        <div className=\"flex min-w-0 flex-wrap items-center gap-1\">\n          {showFileAttachment && (\n            <>\n              <label\n                htmlFor={fileInputId}\n                className=\"text-text-secondary hover:bg-button-ghost-hover grid size-8 cursor-pointer place-items-center rounded-lg\"\n                aria-label=\"Attach file\"\n              >\n                <Paperclip className=\"size-[18px]\" />\n              </label>\n              <input\n                id={fileInputId}\n                type=\"file\"\n                className=\"sr-only\"\n                onChange={(event) =>\n                  setAttachment(event.target.files?.[0]?.name ?? null)\n                }\n              />\n            </>\n          )}\n          {showVoiceInput && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={Mic}\n              aria-label={recording ? \"Stop voice input\" : \"Start voice input\"}\n              aria-pressed={recording}\n              onClick={() => setRecording((active) => !active)}\n              className={cx(recording && \"text-foreground-icon-error\")}\n            />\n          )}\n          {attachment && (\n            <span className=\"bg-background-secondary-default text-caption-1-regular text-text-secondary max-w-48 truncate rounded-sm px-2 py-1\">\n              {attachment}\n            </span>\n          )}\n          <span className=\"text-caption-1-regular text-text-tertiary px-1\">\n            {isLoading\n              ? \"Working\"\n              : recording\n                ? \"Listening\"\n                : \"No write actions\"}\n          </span>\n        </div>\n        <Button\n          size=\"medium\"\n          iconOnly\n          leadingIcon={isLoading ? Square : Send}\n          aria-label={isLoading ? \"Generation in progress\" : \"Send message\"}\n          disabled={!inputValue.trim() || disabled || isLoading}\n          onClick={submit}\n        />\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/dropdown/dropdown.tsx",
          "target": "@components/boardui/base/dropdown/dropdown.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { createContext, useContext, useRef, useState, type ComponentProps, type ReactNode, type RefObject } from \"react\";\nimport {\n  Button as AriaButton,\n  Dialog as AriaDialog,\n  DialogTrigger as AriaDialogTrigger,\n  Popover as AriaPopover,\n} from \"react-aria-components\";\nimport {\n  MENU_ITEM,\n  MENU_ITEM_ACTIVE,\n  MENU_ITEM_INTERACTIVE,\n  MENU_POPOVER_SURFACE,\n  MENU_POPOVER_WIDTH,\n} from \"@/components/boardui/base/dropdown/menu-styles\";\nimport { cx } from \"@/components/boardui/utils/cx\";\nimport { useDismissOnOutsidePress, useTriggerToggle } from \"@/components/boardui/utils/use-dismiss-on-outside-press\";\n\n/**\n * Dropdown - the BoardUI popover-menu recipe as composable primitives, built\n * on React Aria's DialogTrigger/Popover. Unlike Select (which picks a value\n * into a trigger), Dropdown is a free-form menu surface: grouped rows of\n * actions, headers, footers, whatever the panel needs.\n *\n * The same recipe powers the dashboard sidebar's team/account menus and the\n * AI chat template's add/model/folder menus:\n *\n * - Panel: white, 1px border/button/default, radius 16, p 10, shadow/dropdown.\n * - Appear animation: 150ms fade + scale-95 + 2px blur in and out.\n * - Rows: rounded-2lg, background/secondary/hover on hover and on the selected\n *   row, body-medium labels, 4px apart (the panel's flex column carries a\n *   gap-1, the same rhythm as the Select listbox).\n *\n * Composition:\n *\n * ```tsx\n * <Dropdown isOpen={isOpen} onOpenChange={setIsOpen}>\n *   <DropdownTrigger>Open</DropdownTrigger>\n *   <DropdownPopover aria-label=\"Actions\" placement=\"bottom start\">\n *     <DropdownGroup label=\"Add\">\n *       <DropdownItem onSelect={close}>…row content…</DropdownItem>\n *     </DropdownGroup>\n *     <DropdownDivider />\n *     <DropdownGroup label=\"Plugins\">…</DropdownGroup>\n *   </DropdownPopover>\n * </Dropdown>\n * ```\n *\n * State can be uncontrolled (omit isOpen/onOpenChange) - control it when the\n * trigger needs to react to the open state (e.g. rotating a chevron).\n */\n\n/* ------------------------------------------------------------------- shell */\n\ninterface DropdownContextValue {\n  triggerRef: RefObject<HTMLButtonElement | null>;\n  popoverRef: RefObject<HTMLElement | null>;\n}\n\nconst DropdownContext = createContext<DropdownContextValue | null>(null);\n\nexport interface DropdownProps {\n  isOpen?: boolean;\n  onOpenChange?: (isOpen: boolean) => void;\n  /** Trigger (a DropdownTrigger) followed by a DropdownPopover. */\n  children: ReactNode;\n}\n\n/**\n * The popover is `isNonModal`: react-aria's modal scroll lock puts\n * `overflow: hidden` on <html>, which collapses the page scroll position and\n * visibly yanks sticky layout (e.g. the docs sidebar) whenever a menu opens.\n * Non-modal skips the lock, but react-aria hard-couples outside-press\n * dismissal to modality - so open state lives here (bridging any controlled\n * props) and dismissal is restored via useDismissOnOutsidePress, the same\n * fix as Select and the date-picker family.\n */\nexport function Dropdown({ isOpen: controlledOpen, onOpenChange, children }: DropdownProps) {\n  const triggerRef = useRef<HTMLButtonElement>(null);\n  const popoverRef = useRef<HTMLElement>(null);\n  const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n\n  const isOpen = controlledOpen ?? uncontrolledOpen;\n  const setOpen = (next: boolean) => {\n    setUncontrolledOpen(next);\n    onOpenChange?.(next);\n  };\n\n  useDismissOnOutsidePress(isOpen, () => setOpen(false), [triggerRef, popoverRef]);\n  // Pressing the trigger while open closes the menu instead of reopening\n  const allowOpenChange = useTriggerToggle(isOpen, triggerRef);\n\n  return (\n    <DropdownContext.Provider value={{ triggerRef, popoverRef }}>\n      <AriaDialogTrigger isOpen={isOpen} onOpenChange={(o) => allowOpenChange(o) && setOpen(o)}>\n        {children}\n      </AriaDialogTrigger>\n    </DropdownContext.Provider>\n  );\n}\n\n/** The element that opens the menu. Style it entirely via className. */\nexport function DropdownTrigger({ className, ...props }: ComponentProps<typeof AriaButton>) {\n  const context = useContext(DropdownContext);\n  return (\n    <AriaButton\n      ref={context?.triggerRef}\n      {...props}\n      className={cx(\n        \"cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n        className as string,\n      )}\n    />\n  );\n}\n\n/* ------------------------------------------------------------------- panel */\n\nexport interface DropdownPopoverProps\n  extends Pick<ComponentProps<typeof AriaPopover>, \"placement\" | \"offset\" | \"crossOffset\"> {\n  \"aria-label\": string;\n  /** Extra classes on the panel - e.g. a width override (default w-[266px]). */\n  className?: string;\n  /** Classes on the inner dialog (the flex column), e.g. gap between groups. */\n  dialogClassName?: string;\n  children: ReactNode;\n}\n\nexport function DropdownPopover({\n  \"aria-label\": ariaLabel,\n  placement = \"bottom start\",\n  offset = 4,\n  crossOffset,\n  className,\n  dialogClassName,\n  children,\n}: DropdownPopoverProps) {\n  const context = useContext(DropdownContext);\n  return (\n    <AriaPopover\n      ref={context?.popoverRef}\n      isNonModal\n      placement={placement}\n      offset={offset}\n      crossOffset={crossOffset}\n      className={cx(\n        MENU_POPOVER_WIDTH,\n        MENU_POPOVER_SURFACE,\n        className,\n      )}\n    >\n      {/* gap-1 keeps bare DropdownItems 4px apart, the same rhythm as the\n          Select listbox; DropdownDivider's margins are sized to absorb it. */}\n      <AriaDialog aria-label={ariaLabel} className={cx(\"flex flex-col gap-1 outline-none\", dialogClassName)}>\n        {children}\n      </AriaDialog>\n    </AriaPopover>\n  );\n}\n\n/* ----------------------------------------------------------------- content */\n\nexport interface DropdownGroupProps {\n  /** Muted body-medium heading above the rows. */\n  label?: string;\n  className?: string;\n  children: ReactNode;\n}\n\nexport function DropdownGroup({ label, className, children }: DropdownGroupProps) {\n  return (\n    // pt-1 is spacing for the group LABEL - a label-less group must not\n    // carry it, or its first row floats 4px lower than the panel padding\n    // implies (visible as extra space above the first item's hover pill).\n    <div className={cx(\"flex w-full flex-col gap-1.5\", label && \"pt-1\", className)}>\n      {label && <span className=\"pl-2 text-body-medium text-text-secondary\">{label}</span>}\n      <div className=\"flex w-full flex-col gap-1\">{children}</div>\n    </div>\n  );\n}\n\nexport interface DropdownItemProps {\n  /** Highlights the row like the hover state (current selection). */\n  selected?: boolean;\n  onSelect?: () => void;\n  /** Row padding defaults to p-2 - override for denser rows (px-2 py-1.5). */\n  className?: string;\n  children: ReactNode;\n}\n\n/**\n * A menu row. Content is free-form - icon + label, avatar + name, label +\n * trailing badge - laid out in a gap-2 flex row.\n */\nexport function DropdownItem({ selected, onSelect, className, children }: DropdownItemProps) {\n  return (\n    <button\n      type=\"button\"\n      aria-pressed={selected}\n      onClick={onSelect}\n      className={cx(\n        MENU_ITEM,\n        selected ? MENU_ITEM_ACTIVE : MENU_ITEM_INTERACTIVE,\n        className,\n      )}\n    >\n      {children}\n    </button>\n  );\n}\n\n/** Full-bleed 1px divider between groups (bleeds through the panel's p-2.5).\n *  my-1.5 + the dialog's gap-1 on both sides = the original 10px breathing room. */\nexport function DropdownDivider({ className }: { className?: string }) {\n  return <div className={cx(\"-mx-2.5 my-1.5 h-px shrink-0 bg-border-button-default\", className)} />;\n}\n"
        },
        {
          "path": "components/boardui/base/dropdown/menu-styles.ts",
          "target": "@components/boardui/base/dropdown/menu-styles.ts",
          "type": "registry:component",
          "content": "/**\n * Shared visual recipe for BoardUI menu surfaces.\n *\n * Select and Dropdown intentionally keep their distinct React Aria semantics\n * (single-value listbox vs. action menu), while consuming the same panel,\n * motion, and row treatments from here.\n */\nexport const MENU_POPOVER_SURFACE = [\n  \"max-w-[calc(100vw-32px)] overflow-y-auto\",\n  \"rounded-2xl border border-border-button-default bg-background-primary-default p-2.5 shadow-dropdown\",\n  \"transition duration-150 ease-out\",\n  \"data-[entering]:opacity-0 data-[entering]:scale-95 data-[entering]:blur-[2px]\",\n  \"data-[exiting]:opacity-0 data-[exiting]:scale-95 data-[exiting]:blur-[2px]\",\n  \"data-[placement=bottom]:origin-top-left data-[placement=top]:origin-bottom-left\",\n  \"data-[placement=left]:origin-right data-[placement=right]:origin-left\",\n].join(\" \");\n\nexport const MENU_POPOVER_WIDTH = \"w-[266px]\";\n\nexport const MENU_ITEMS_CONTAINER = \"flex w-full flex-col gap-1 outline-none\";\n\nexport const MENU_ITEM = [\n  \"flex w-full cursor-pointer items-center gap-2 rounded-2lg p-2 text-left\",\n  \"text-text-primary outline-none transition-colors\",\n].join(\" \");\n\nexport const MENU_ITEM_ACTIVE = \"bg-dropdown-item-hover-background\";\n\nexport const MENU_ITEM_INTERACTIVE =\n  \"hover:bg-dropdown-item-hover-background focus-visible:bg-dropdown-item-hover-background\";\n"
        },
        {
          "path": "components/boardui/utils/use-dismiss-on-outside-press.ts",
          "target": "@components/boardui/utils/use-dismiss-on-outside-press.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport type { RefObject } from \"react\";\n\n/**\n * React Aria's `Popover` couples \"non-modal\" with \"not dismissable on\n * outside interaction\" — `isNonModal` (which we set to avoid the scroll\n * lock / focus trap that comes with a modal popover) also silently disables\n * its built-in outside-click-to-close behavior. This restores just that\n * piece manually: closes when a pointerdown lands outside every given ref\n * (typically the trigger + the popover's own content).\n */\nexport function useDismissOnOutsidePress(\n  isOpen: boolean,\n  onDismiss: () => void,\n  refs: RefObject<HTMLElement | null>[],\n) {\n  useEffect(() => {\n    if (!isOpen) return;\n\n    const handlePointerDown = (event: PointerEvent) => {\n      const target = event.target as Node;\n      if (refs.some((ref) => ref.current?.contains(target))) return;\n      onDismiss();\n    };\n\n    document.addEventListener(\"pointerdown\", handlePointerDown, true);\n    return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n  }, [isOpen, onDismiss, refs]);\n}\n\n/**\n * Companion fix for the same `isNonModal` popovers: pressing the trigger\n * while the popover is open should close it (toggle), but React Aria fires\n * `onOpenChange(false)` immediately followed by `onOpenChange(true)` within\n * the same press, so the popover never actually closes.\n *\n * This watches for a pointerdown on the trigger while open and swallows the\n * spurious reopen that follows. Wire the returned guard into the component's\n * `onOpenChange`:\n *\n *   const allowOpenChange = useTriggerToggle(isOpen, triggerRef);\n *   <AriaSelect onOpenChange={(o) => allowOpenChange(o) && setIsOpen(o)} …\n */\nexport function useTriggerToggle(\n  isOpen: boolean,\n  triggerRef: RefObject<HTMLElement | null>,\n) {\n  const suppressReopenRef = useRef(false);\n\n  useEffect(() => {\n    if (!isOpen) return;\n\n    const handlePointerDown = (event: PointerEvent) => {\n      if (!triggerRef.current?.contains(event.target as Node)) return;\n      suppressReopenRef.current = true;\n      // Safety valve: only the very next open within this click may be\n      // swallowed; never leave a stale suppression behind.\n      setTimeout(() => {\n        suppressReopenRef.current = false;\n      }, 400);\n    };\n\n    document.addEventListener(\"pointerdown\", handlePointerDown, true);\n    return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n  }, [isOpen, triggerRef]);\n\n  return (next: boolean) => {\n    if (next && suppressReopenRef.current) {\n      suppressReopenRef.current = false;\n      return false;\n    }\n    return true;\n  };\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-response",
      "type": "registry:block",
      "title": "Agent Response",
      "description": "agent response",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "marked@^15.0.7",
        "react-aria-components@^1.21.1",
        "react-markdown@^10.1.0",
        "remark-breaks@^4.0.0",
        "remark-gfm@^4.0.1",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-response.tsx",
          "target": "@components/agents-ui/agent-response.tsx",
          "type": "registry:component",
          "content": "export { AgentResponse } from \"./application/response/response\"\nexport type {\n  AgentResponseProps,\n  Artifact,\n  ToolCall,\n} from \"./application/response/response\"\n"
        },
        {
          "path": "components/agents-ui/application/response/response.tsx",
          "target": "@components/agents-ui/application/response/response.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { CodeBlockCode } from \"@/components/prompt-kit/code-block\"\nimport { Markdown } from \"@/components/prompt-kit/markdown\"\nimport {\n  Check,\n  ChevronRight,\n  Circle,\n  Copy,\n  Download,\n  FileCode,\n  FileText,\n  Loader2,\n  RefreshCw,\n  Wrench,\n  XCircle,\n} from \"lucide-react\"\nimport { useState } from \"react\"\n\n/* Tool payloads are intentionally provider-defined. */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport type ToolCall = {\n  id: string\n  name: string\n  input: any\n  output?: any\n  status: \"pending\" | \"running\" | \"completed\" | \"failed\"\n  duration?: number\n}\nexport type Artifact = {\n  id: string\n  type: \"code\" | \"file\" | \"image\" | \"data\"\n  name: string\n  content: string\n  language?: string\n  size?: string\n}\nexport interface AgentResponseProps {\n  message: string\n  thinking?: string\n  toolCalls?: ToolCall[]\n  artifacts?: Artifact[]\n  isStreaming?: boolean\n  className?: string\n  onRegenerate?: () => void\n  onCopy?: () => void\n}\nconst statusIcons = {\n  pending: Circle,\n  running: Loader2,\n  completed: Check,\n  failed: XCircle,\n}\n\nfunction ToolRow({ tool }: { tool: ToolCall }) {\n  const [open, setOpen] = useState(false)\n  const Icon = statusIcons[tool.status]\n  return (\n    <div className=\"border-separator-border border-b last:border-b-0\">\n      <button\n        type=\"button\"\n        aria-expanded={open}\n        onClick={() => setOpen((value) => !value)}\n        className=\"hover:bg-background-secondary-hover flex min-h-11 w-full items-center gap-2 px-3 text-left\"\n      >\n        <Icon\n          className={cx(\n            \"text-text-secondary size-4\",\n            tool.status === \"running\" && \"text-accent-600 animate-spin\",\n            tool.status === \"failed\" && \"text-foreground-icon-error\",\n            tool.status === \"completed\" && \"text-foreground-icon-positive\"\n          )}\n        />\n        <Wrench className=\"text-text-tertiary size-4\" />\n        <span className=\"text-body-medium min-w-0 flex-1 truncate\">\n          {tool.name}\n        </span>\n        <span className=\"text-caption-1-regular text-text-secondary tabular-nums\">\n          {tool.duration === undefined ? tool.status : `${tool.duration} ms`}\n        </span>\n        <ChevronRight\n          className={cx(\n            \"text-text-tertiary size-4 transition-transform\",\n            open && \"rotate-90\"\n          )}\n        />\n      </button>\n      {open && (\n        <div className=\"border-separator-border bg-background-secondary-default space-y-3 border-t p-3\">\n          <Payload label=\"Input\" value={tool.input} />\n          {tool.output !== undefined && (\n            <Payload label=\"Output\" value={tool.output} />\n          )}\n        </div>\n      )}\n    </div>\n  )\n}\nfunction Payload({ label, value }: { label: string; value: unknown }) {\n  return (\n    <div>\n      <p className=\"text-caption-1-medium text-text-secondary mb-1\">{label}</p>\n      <pre className=\"text-caption-1-regular text-text-primary overflow-x-auto whitespace-pre-wrap\">\n        {JSON.stringify(value, null, 2)}\n      </pre>\n    </div>\n  )\n}\nfunction ArtifactView({ artifact }: { artifact: Artifact }) {\n  const Icon = artifact.type === \"code\" ? FileCode : FileText\n  return (\n    <section className=\"border-separator-border overflow-hidden rounded-lg border\">\n      <header className=\"border-separator-border flex min-h-11 items-center gap-2 border-b px-3\">\n        <Icon className=\"text-text-secondary size-4\" />\n        <span className=\"text-body-medium min-w-0 flex-1 truncate\">\n          {artifact.name}\n        </span>\n        {artifact.size && (\n          <span className=\"text-caption-1-regular text-text-secondary\">\n            {artifact.size}\n          </span>\n        )}\n        <Button\n          size=\"xs\"\n          variant=\"ghost\"\n          iconOnly\n          leadingIcon={Download}\n          aria-label={`Download ${artifact.name}`}\n        />\n      </header>\n      <div className=\"bg-background-secondary-default max-h-96 overflow-auto\">\n        {artifact.type === \"code\" ? (\n          <CodeBlockCode\n            code={artifact.content}\n            language={artifact.language || \"plaintext\"}\n            className=\"rounded-none border-0\"\n          />\n        ) : (\n          <pre className=\"text-body-2-regular p-4 whitespace-pre-wrap\">\n            {artifact.content}\n          </pre>\n        )}\n      </div>\n    </section>\n  )\n}\nexport function AgentResponse({\n  message,\n  thinking,\n  toolCalls = [],\n  artifacts = [],\n  isStreaming = false,\n  className,\n  onRegenerate,\n  onCopy,\n}: AgentResponseProps) {\n  const [thinkingOpen, setThinkingOpen] = useState(false)\n  return (\n    <article\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex min-h-12 items-center justify-between gap-3 border-b px-4\">\n        <div>\n          <h3 className=\"text-body-medium\">Assistant response</h3>\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {isStreaming\n              ? \"Generating response\"\n              : `${toolCalls.length} tools  |  ${artifacts.length} artifacts`}\n          </p>\n        </div>\n        {isStreaming && (\n          <Loader2 className=\"text-text-secondary size-4 animate-spin\" />\n        )}\n      </header>\n      <div className=\"space-y-4 p-4\">\n        {thinking && (\n          <div>\n            <button\n              type=\"button\"\n              aria-expanded={thinkingOpen}\n              onClick={() => setThinkingOpen((open) => !open)}\n              className=\"text-body-medium text-text-secondary hover:text-text-primary flex min-h-10 items-center gap-2\"\n            >\n              <ChevronRight\n                className={cx(\n                  \"size-4 transition-transform\",\n                  thinkingOpen && \"rotate-90\"\n                )}\n              />\n              Reasoning summary\n            </button>\n            {thinkingOpen && (\n              <p className=\"bg-background-secondary-default text-body-2-regular text-text-secondary rounded-lg p-3 leading-5\">\n                {thinking}\n              </p>\n            )}\n          </div>\n        )}\n        {toolCalls.length > 0 && (\n          <section>\n            <h4 className=\"text-caption-1-medium text-text-secondary mb-2\">\n              Tool activity\n            </h4>\n            <div className=\"border-separator-border overflow-hidden rounded-lg border\">\n              {toolCalls.map((tool) => (\n                <ToolRow key={tool.id} tool={tool} />\n              ))}\n            </div>\n          </section>\n        )}\n        <div className=\"text-body-regular max-w-none leading-6\">\n          <Markdown>{message}</Markdown>\n          {isStreaming && (\n            <span className=\"bg-text-primary ml-1 inline-block h-4 w-px animate-pulse\" />\n          )}\n        </div>\n        {artifacts.length > 0 && (\n          <section className=\"space-y-2\">\n            <h4 className=\"text-caption-1-medium text-text-secondary\">\n              Artifacts\n            </h4>\n            {artifacts.map((artifact) => (\n              <ArtifactView key={artifact.id} artifact={artifact} />\n            ))}\n          </section>\n        )}\n      </div>\n      {!isStreaming && (onCopy || onRegenerate) && (\n        <footer className=\"border-separator-border flex gap-1 border-t px-3 py-2\">\n          {onCopy && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Copy}\n              onClick={onCopy}\n            >\n              Copy\n            </Button>\n          )}\n          {onRegenerate && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={RefreshCw}\n              onClick={onRegenerate}\n            >\n              Regenerate\n            </Button>\n          )}\n        </footer>\n      )}\n    </article>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/prompt-kit/code-block.tsx",
          "target": "@components/prompt-kit/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport React, { useEffect, useState } from \"react\"\nimport { codeToHtml } from \"shiki\"\n\nexport type CodeBlockProps = {\n  children?: React.ReactNode\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlock({ children, className, ...props }: CodeBlockProps) {\n  return (\n    <div\n      className={cn(\n        \"not-prose flex w-full flex-col overflow-clip border\",\n        \"border-border bg-card text-card-foreground rounded-xl\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type CodeBlockCodeProps = {\n  code: string\n  language?: string\n  theme?: string\n  className?: string\n} & React.HTMLProps<HTMLDivElement>\n\nfunction CodeBlockCode({\n  code,\n  language = \"tsx\",\n  theme = \"github-light\",\n  className,\n  ...props\n}: CodeBlockCodeProps) {\n  const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null)\n\n  useEffect(() => {\n    async function highlight() {\n      if (!code) {\n        setHighlightedHtml(\"<pre><code></code></pre>\")\n        return\n      }\n\n      const html = await codeToHtml(code, { lang: language, theme })\n      setHighlightedHtml(html)\n    }\n    highlight()\n  }, [code, language, theme])\n\n  const classNames = cn(\n    \"w-full overflow-x-auto text-[13px] [&>pre]:px-4 [&>pre]:py-4\",\n    className\n  )\n\n  // SSR fallback: render plain code if not hydrated yet\n  return highlightedHtml ? (\n    <div\n      data-code-theme={theme}\n      className={classNames}\n      dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n      {...props}\n    />\n  ) : (\n    <div data-code-theme={theme} className={classNames} {...props}>\n      <pre>\n        <code>{code}</code>\n      </pre>\n    </div>\n  )\n}\n\nexport type CodeBlockGroupProps = React.HTMLAttributes<HTMLDivElement>\n\nfunction CodeBlockGroup({\n  children,\n  className,\n  ...props\n}: CodeBlockGroupProps) {\n  return (\n    <div\n      className={cn(\"flex items-center justify-between\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport { CodeBlockGroup, CodeBlockCode, CodeBlock }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/prompt-kit/markdown.tsx",
          "target": "@components/prompt-kit/markdown.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { marked } from \"marked\"\nimport { memo, useId, useMemo } from \"react\"\nimport ReactMarkdown, { Components } from \"react-markdown\"\nimport remarkBreaks from \"remark-breaks\"\nimport remarkGfm from \"remark-gfm\"\nimport { CodeBlock, CodeBlockCode } from \"./code-block\"\n\nexport type MarkdownProps = {\n  children: string\n  id?: string\n  className?: string\n  components?: Partial<Components>\n}\n\nfunction parseMarkdownIntoBlocks(markdown: string): string[] {\n  const tokens = marked.lexer(markdown)\n  return tokens.map((token) => token.raw)\n}\n\nfunction extractLanguage(className?: string): string {\n  if (!className) return \"plaintext\"\n  const match = className.match(/language-(\\w+)/)\n  return match ? match[1] : \"plaintext\"\n}\n\nconst INITIAL_COMPONENTS: Partial<Components> = {\n  code: function CodeComponent({ className, children, ...props }) {\n    const isInline =\n      !props.node?.position?.start.line ||\n      props.node?.position?.start.line === props.node?.position?.end.line\n\n    if (isInline) {\n      return (\n        <span\n          className={cn(\n            \"bg-primary-foreground rounded-sm px-1 font-mono text-sm\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </span>\n      )\n    }\n\n    const language = extractLanguage(className)\n\n    return (\n      <CodeBlock className={className}>\n        <CodeBlockCode code={children as string} language={language} />\n      </CodeBlock>\n    )\n  },\n  pre: function PreComponent({ children }) {\n    return <>{children}</>\n  },\n}\n\nconst MemoizedMarkdownBlock = memo(\n  function MarkdownBlock({\n    content,\n    components = INITIAL_COMPONENTS,\n  }: {\n    content: string\n    components?: Partial<Components>\n  }) {\n    return (\n      <ReactMarkdown\n        remarkPlugins={[remarkGfm, remarkBreaks]}\n        components={components}\n      >\n        {content}\n      </ReactMarkdown>\n    )\n  },\n  function propsAreEqual(prevProps, nextProps) {\n    return prevProps.content === nextProps.content\n  }\n)\n\nMemoizedMarkdownBlock.displayName = \"MemoizedMarkdownBlock\"\n\nfunction MarkdownComponent({\n  children,\n  id,\n  className,\n  components = INITIAL_COMPONENTS,\n}: MarkdownProps) {\n  const generatedId = useId()\n  const blockId = id ?? generatedId\n  const blocks = useMemo(() => parseMarkdownIntoBlocks(children), [children])\n\n  return (\n    <div className={className}>\n      {blocks.map((block, index) => (\n        <MemoizedMarkdownBlock\n          key={`${blockId}-block-${index}`}\n          content={block}\n          components={components}\n        />\n      ))}\n    </div>\n  )\n}\n\nconst Markdown = memo(MarkdownComponent)\nMarkdown.displayName = \"Markdown\"\n\nexport { Markdown }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/LICENSE.md",
          "target": "@components/prompt-kit/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Julien Thibeaut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. app/page.tsx\n"
        },
        {
          "path": "components/prompt-kit/SOURCE.json",
          "target": "@components/prompt-kit/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Prompt Kit\",\n  \"upstream\": \"https://github.com/ibelick/prompt-kit\",\n  \"revision\": \"de80375967400aa0c6ebab9d3ba4f9258ab79fcc\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"components/ui/hover-card.tsx\",\n    \"components/prompt-kit/chain-of-thought.tsx\",\n    \"components/prompt-kit/chat-container.tsx\",\n    \"components/prompt-kit/code-block.tsx\",\n    \"components/prompt-kit/feedback-bar.tsx\",\n    \"components/prompt-kit/file-upload.tsx\",\n    \"components/prompt-kit/image.tsx\",\n    \"components/prompt-kit/jsx-preview.tsx\",\n    \"components/prompt-kit/loader.tsx\",\n    \"components/prompt-kit/markdown.tsx\",\n    \"components/prompt-kit/message.tsx\",\n    \"components/prompt-kit/prompt-input.tsx\",\n    \"components/prompt-kit/prompt-suggestion.tsx\",\n    \"components/prompt-kit/reasoning.tsx\",\n    \"components/prompt-kit/response-stream.tsx\",\n    \"components/prompt-kit/scroll-button.tsx\",\n    \"components/prompt-kit/source.tsx\",\n    \"components/prompt-kit/steps.tsx\",\n    \"components/prompt-kit/system-message.tsx\",\n    \"components/prompt-kit/text-shimmer.tsx\",\n    \"components/prompt-kit/thinking-bar.tsx\",\n    \"components/prompt-kit/tool.tsx\",\n    \"app/globals.css\"\n  ],\n  \"fullStackItems\": [\n    \"components/primitives/chatbot.tsx\",\n    \"components/primitives/tool-calling.tsx\"\n  ],\n  \"adaptation\": \"Public primitives retain upstream APIs, layout, states, and motion. PromptInput preserves the host IME guard; CodeBlock preserves data-code-theme while restoring upstream theme selection. Gallery examples use local fieldwork fixtures and no backend or API key. The gallery code themes follow the host theme unless explicitly selected; Markdown prose and status messages have readable dark-mode styling.\"\n}\n"
        },
        {
          "path": "components/prompt-kit/styles.css",
          "target": "@components/prompt-kit/styles.css",
          "type": "registry:file",
          "content": "@import \"../../styles/animations.css\";\n\n/* keyframes for loaders */\n@keyframes typing {\n  0%,\n  100% {\n    transform: translateY(0);\n    opacity: 0.5;\n  }\n  50% {\n    transform: translateY(-2px);\n    opacity: 1;\n  }\n}\n\n@keyframes loading-dots {\n  0%,\n  100% {\n    opacity: 0;\n  }\n  50% {\n    opacity: 1;\n  }\n}\n\n@keyframes wave {\n  0%,\n  100% {\n    transform: scaleY(1);\n  }\n  50% {\n    transform: scaleY(0.6);\n  }\n}\n\n@keyframes blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@keyframes text-blink {\n  0%,\n  100% {\n    color: var(--primary);\n  }\n  50% {\n    color: var(--muted-foreground);\n  }\n}\n\n@keyframes bounce-dots {\n  0%,\n  100% {\n    transform: scale(0.8);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scale(1.2);\n    opacity: 1;\n  }\n}\n\n@keyframes thin-pulse {\n  0%,\n  100% {\n    transform: scale(0.95);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.05);\n    opacity: 0.4;\n  }\n}\n\n@keyframes pulse-dot {\n  0%,\n  100% {\n    transform: scale(1);\n    opacity: 0.8;\n  }\n  50% {\n    transform: scale(1.5);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer-text {\n  0% {\n    background-position: 150% center;\n  }\n  100% {\n    background-position: -150% center;\n  }\n}\n\n@keyframes wave-bars {\n  0%,\n  100% {\n    transform: scaleY(1);\n    opacity: 0.5;\n  }\n  50% {\n    transform: scaleY(0.6);\n    opacity: 1;\n  }\n}\n\n@keyframes shimmer {\n  0% {\n    background-position: 200% 50%;\n  }\n  100% {\n    background-position: -200% 50%;\n  }\n}\n\n@keyframes spinner-fade {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-revenue-insights",
      "type": "registry:block",
      "title": "Agent Revenue Insights",
      "description": "agent revenue insights",
      "dependencies": [
        "clsx@^2.1.1",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-revenue-insights.tsx",
          "target": "@components/agents-ui/agent-revenue-insights.tsx",
          "type": "registry:component",
          "content": "export interface RevenueForecastPoint {\n  label: string\n  value: number\n}\n\nexport interface RevenueSegmentInsight {\n  id: string\n  segment: string\n  arr: string\n  trend: \"up\" | \"down\" | \"flat\"\n  change: string\n  confidence: number\n  owner?: string\n}\n\nexport interface AgentRevenueInsightsProps {\n  currentArr?: string\n  arrChange?: string\n  periodLabel?: string\n  forecastPoints?: RevenueForecastPoint[]\n  segmentInsights?: RevenueSegmentInsight[]\n  scenario?: \"base\" | \"stretch\" | \"conservative\"\n  onRefresh?: () => void\n  onScenarioChange?: (scenario: \"base\" | \"stretch\" | \"conservative\") => void\n  onSegmentClick?: (segment: RevenueSegmentInsight) => void\n  className?: string\n}\n\nexport { AgentRevenueInsights } from \"./application/revenue-insights/agent-revenue-insights\"\n"
        },
        {
          "path": "components/agents-ui/application/revenue-insights/agent-revenue-insights.tsx",
          "target": "@components/agents-ui/application/revenue-insights/agent-revenue-insights.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Tab, TabList, Tabs } from \"@/components/boardui/base/tabs/tabs\"\nimport { cn } from \"@/lib/utils\"\nimport { useEffect, useState } from \"react\"\nimport type { AgentRevenueInsightsProps } from \"../../agent-revenue-insights\"\n\nconst defaultPoints = [\n  { label: \"Jan\", value: 9.8 },\n  { label: \"Feb\", value: 10.4 },\n  { label: \"Mar\", value: 11.2 },\n  { label: \"Apr\", value: 11.8 },\n  { label: \"May\", value: 12.4 },\n  { label: \"Jun\", value: 13.1 },\n]\nconst defaultSegments = [\n  {\n    id: \"enterprise\",\n    segment: \"Enterprise\",\n    arr: \"$4.2M\",\n    trend: \"up\" as const,\n    change: \"+14% QoQ\",\n    confidence: 0.86,\n    owner: \"Account team\",\n  },\n  {\n    id: \"smb\",\n    segment: \"SMB\",\n    arr: \"$2.1M\",\n    trend: \"flat\" as const,\n    change: \"+2% QoQ\",\n    confidence: 0.74,\n    owner: \"Growth team\",\n  },\n]\n\nexport function AgentRevenueInsights({\n  currentArr = \"$12.9M\",\n  arrChange = \"+8.4%\",\n  periodLabel = \"Trailing 6 months\",\n  forecastPoints = defaultPoints,\n  segmentInsights = defaultSegments,\n  scenario = \"base\",\n  onRefresh,\n  onScenarioChange,\n  onSegmentClick,\n  className,\n}: AgentRevenueInsightsProps) {\n  const [selected, setSelected] = useState(scenario)\n  useEffect(() => setSelected(scenario), [scenario])\n  const points = forecastPoints.filter((point) => Number.isFinite(point.value))\n  const min = Math.min(...points.map((point) => point.value)),\n    max = Math.max(...points.map((point) => point.value))\n  const path = points\n    .map(\n      (point, i) =>\n        `${24 + (i / Math.max(1, points.length - 1)) * 552},${160 - ((point.value - min) / (max - min || 1)) * 136}`\n    )\n    .join(\" \")\n  return (\n    <section\n      aria-label=\"Revenue insights\"\n      className={cn(\n        \"agent-widget border-separator-border bg-background-primary-default text-text-primary w-full min-w-0 space-y-5 rounded-xl border p-5\",\n        className\n      )}\n    >\n      <header className=\"flex flex-wrap justify-between gap-4\">\n        <div>\n          <p className=\"text-text-secondary text-xs\">{periodLabel}</p>\n          <h2 className=\"mt-1 text-lg font-semibold\">Revenue outlook</h2>\n        </div>\n        {onRefresh && (\n          <Button variant=\"secondary\" size=\"small\" onClick={onRefresh}>\n            Refresh\n          </Button>\n        )}\n      </header>\n      <div className=\"border-separator-border flex flex-wrap items-end justify-between gap-4 border-y py-4\">\n        <div>\n          <p className=\"text-text-secondary text-xs\">\n            Annual recurring revenue\n          </p>\n          <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n            {currentArr}\n            <span className=\"text-text-secondary ml-3 text-xs font-normal\">\n              {arrChange}\n            </span>\n          </p>\n        </div>\n        <Tabs\n          selectedKey={selected}\n          onSelectionChange={(key) => {\n            const value = String(key) as typeof selected\n            setSelected(value)\n            onScenarioChange?.(value)\n          }}\n        >\n          <TabList aria-label=\"Forecast scenario\">\n            {[\"conservative\", \"base\", \"stretch\"].map((key) => (\n              <Tab key={key} id={key} className=\"capitalize\">\n                {key}\n              </Tab>\n            ))}\n          </TabList>\n        </Tabs>\n      </div>\n      <div className=\"grid min-w-0 gap-6 lg:grid-cols-2\">\n        <section className=\"min-w-0\">\n          <h3 className=\"text-sm font-medium capitalize\">\n            {selected} forecast\n          </h3>\n          {points.length > 0 ? (\n            <svg\n              role=\"img\"\n              aria-label={`Forecast: ${points.map((p) => `${p.label} ${p.value} million`).join(\", \")}`}\n              viewBox=\"0 0 600 190\"\n              className=\"my-3 w-full\"\n            >\n              <path d=\"M24 160 H576\" stroke=\"currentColor\" opacity=\".12\" />\n              <polyline\n                points={path}\n                fill=\"none\"\n                stroke=\"currentColor\"\n                strokeWidth=\"2\"\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n              />\n              {points.map((point, i) => (\n                <text\n                  key={point.label}\n                  x={24 + (i / Math.max(1, points.length - 1)) * 552}\n                  y=\"184\"\n                  textAnchor=\"middle\"\n                  fill=\"currentColor\"\n                  opacity=\".65\"\n                  fontSize=\"12\"\n                >\n                  {point.label}\n                </text>\n              ))}\n            </svg>\n          ) : (\n            <p className=\"text-text-secondary py-8 text-sm\">\n              No forecast data available.\n            </p>\n          )}\n          <details className=\"text-text-secondary text-xs\">\n            <summary className=\"focus-visible:outline-border-focus-ring cursor-pointer rounded py-2 focus-visible:outline-2\">\n              View forecast values\n            </summary>\n            <dl className=\"mt-2 space-y-2\">\n              {points.map((point) => (\n                <div key={point.label} className=\"flex justify-between\">\n                  <dt>{point.label}</dt>\n                  <dd className=\"tabular-nums\">{point.value.toFixed(1)}M</dd>\n                </div>\n              ))}\n            </dl>\n          </details>\n        </section>\n        <section className=\"min-w-0\">\n          <h3 className=\"mb-2 text-sm font-medium\">Segments to watch</h3>\n          <ul className=\"divide-separator-border divide-y\">\n            {segmentInsights.map((item) => (\n              <li key={item.id}>\n                <button\n                  type=\"button\"\n                  className=\"hover:bg-background-primary-hover focus-visible:outline-border-focus-ring w-full rounded-lg py-3 text-left focus-visible:outline-2\"\n                  onClick={() => onSegmentClick?.(item)}\n                >\n                  <div className=\"flex items-start justify-between gap-3\">\n                    <span className=\"text-sm font-medium\">{item.segment}</span>\n                    <span className=\"shrink-0 text-sm tabular-nums\">\n                      {item.arr}\n                    </span>\n                  </div>\n                  <p className=\"text-text-secondary mt-1 text-xs\">\n                    {item.owner ?? \"Unassigned\"}\n                  </p>\n                  <div className=\"text-text-secondary mt-2 flex flex-wrap justify-between gap-2 text-xs\">\n                    <span>\n                      {item.change} · {item.trend}\n                    </span>\n                    <span>Confidence {Math.round(item.confidence * 100)}%</span>\n                  </div>\n                </button>\n              </li>\n            ))}\n          </ul>\n          {segmentInsights.length === 0 && (\n            <p className=\"text-text-secondary py-4 text-sm\">\n              No segment insights available.\n            </p>\n          )}\n        </section>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/tabs/tabs.tsx",
          "target": "@components/boardui/base/tabs/tabs.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type { ComponentType, ReactNode, Ref } from \"react\";\nimport {\n  Tab as AriaTab,\n  TabList as AriaTabList,\n  TabPanel as AriaTabPanel,\n  Tabs as AriaTabs,\n} from \"react-aria-components\";\nimport type {\n  TabListProps as AriaTabListProps,\n  TabPanelProps as AriaTabPanelProps,\n  TabProps as AriaTabProps,\n  TabsProps as AriaTabsProps,\n} from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Figma source: Board UI → Tab (node 3793:2942).\n *\n * Underline tabs. The tab strip sits on a 1px border/button/default baseline;\n * the active tab paints a 2px foreground underline over it.\n *   tab       px 10, py 8, gap 10 (label ↔ count), Body 1 (14/20)\n *     active     text/primary, Medium weight, 2px foreground underline\n *     inactive   text/primary, Regular weight, transparent underline\n *   count     radius/sm, px 4, py 1, Caption 1/Medium (12/16)\n *     active     selected count background, text/primary\n *     inactive   bg black/10 @ 50% opacity, text/primary\n *   icon      optional 16px leading glyph, inherits the label color\n *\n * Built on react-aria Tabs: roving-tabindex arrow-key navigation, automatic\n * activation, and TabList/TabPanel association.\n */\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\nexport interface TabsProps extends AriaTabsProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tabs({ className, ref, ...props }: TabsProps) {\n  return (\n    <AriaTabs\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"flex w-full flex-col gap-4\",\n          state.orientation === \"vertical\" && \"flex-row\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n\nexport interface TabListProps<T extends object> extends AriaTabListProps<T> {\n  ref?: Ref<HTMLDivElement>;\n}\n\ntype Underline = { left: number; width: number };\n\nexport function TabList<T extends object>({ className, ref, ...props }: TabListProps<T>) {\n  const wrapperRef = useRef<HTMLDivElement>(null);\n  const [underline, setUnderline] = useState<Underline | null>(null);\n\n  useIsomorphicLayoutEffect(() => {\n    const el = wrapperRef.current;\n    if (!el) return;\n    const measure = () => {\n      const selected = el.querySelector<HTMLElement>(\"[role='tab'][data-selected]\");\n      if (selected) {\n        setUnderline({ left: selected.offsetLeft, width: selected.offsetWidth });\n      }\n    };\n    measure();\n    // Re-measure when selection flips (data-selected toggles) or size changes.\n    const mo = new MutationObserver(measure);\n    mo.observe(el, { attributes: true, subtree: true, attributeFilter: [\"data-selected\"] });\n    const ro = new ResizeObserver(measure);\n    ro.observe(el);\n    return () => {\n      mo.disconnect();\n      ro.disconnect();\n    };\n  }, []);\n\n  return (\n    <div ref={wrapperRef} className=\"relative w-full\">\n      <AriaTabList\n        ref={ref}\n        {...props}\n        className={(state) =>\n          cx(\n            \"flex w-full items-center gap-1 border-b border-separator-border\",\n            typeof className === \"function\" ? className(state) : className,\n          )\n        }\n      />\n      {underline && (\n        <span\n          aria-hidden\n          className=\"pointer-events-none absolute bottom-0 left-0 h-0.5 bg-text-primary transition-[transform,width] duration-200 ease\"\n          style={{\n            transform: `translateX(${underline.left}px)`,\n            width: underline.width,\n          }}\n        />\n      )}\n    </div>\n  );\n}\n\nexport interface TabProps extends Omit<AriaTabProps, \"children\"> {\n  children?: ReactNode;\n  /** Optional leading icon (16px). Inherits the label color. */\n  icon?: IconComponent;\n  /** Optional trailing count badge. */\n  count?: ReactNode;\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tab({ className, children, icon: Icon, count, ref, ...props }: TabProps) {\n  return (\n    <AriaTab\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"relative inline-flex cursor-pointer items-center gap-2.5 px-2.5 py-2 whitespace-nowrap\",\n          \"outline-none transition-colors duration-150 ease\",\n          \"focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          state.isDisabled && \"cursor-not-allowed opacity-50\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    >\n      {({ isSelected }) => (\n        <>\n          <span\n            className={cx(\n              \"inline-flex items-center gap-1.5\",\n              isSelected\n                ? \"text-body-medium text-text-primary\"\n                : \"text-body-regular text-text-primary\",\n            )}\n          >\n            {Icon && <Icon className=\"size-4 shrink-0\" aria-hidden />}\n            {children}\n          </span>\n          {count != null && (\n            <span\n              className={cx(\n                \"inline-flex items-center justify-center rounded-sm px-1 py-px text-caption-1-medium whitespace-nowrap\",\n                isSelected\n                  ? \"bg-tab-count-selected-background text-text-primary\"\n                  : \"bg-black/10 text-text-primary opacity-50\",\n              )}\n            >\n              {count}\n            </span>\n          )}\n        </>\n      )}\n    </AriaTab>\n  );\n}\n\nexport interface TabPanelProps extends AriaTabPanelProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function TabPanel({ className, ref, ...props }: TabPanelProps) {\n  return (\n    <AriaTabPanel\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"outline-none focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-routing-hub",
      "type": "registry:block",
      "title": "Agent Routing Hub",
      "description": "agent routing hub",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-routing-hub.tsx",
          "target": "@components/agents-ui/agent-routing-hub.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { RoutingHub } from \"@/components/agents-ui/application/routing-hub/routing-hub\"\nimport type { AgentRoutingHubProps } from \"@/components/agents-ui/application/routing-hub/routing-hub\"\nimport { createElement } from \"react\"\n\nexport type {\n  AgentRoute,\n  AgentRoutingHubProps,\n  RouteClassification,\n  RouteStatus,\n  RoutingHistoryEntry,\n} from \"@/components/agents-ui/application/routing-hub/routing-hub\"\nexport function AgentRoutingHub(props: AgentRoutingHubProps) {\n  return createElement(RoutingHub, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/routing-hub/routing-hub.tsx",
          "target": "@components/agents-ui/application/routing-hub/routing-hub.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDown, Clock, RefreshCw } from \"lucide-react\"\n\nexport type RouteStatus = \"selected\" | \"available\" | \"unavailable\"\nexport interface RouteClassification {\n  intent: string\n  confidence: number\n  reasoning: string\n}\nexport interface AgentRoute {\n  id: string\n  agentName: string\n  specialty: string\n  matchScore: number\n  status: RouteStatus\n  description: string\n}\nexport interface RoutingHistoryEntry {\n  id: string\n  query: string\n  intent: string\n  agentName: string\n  timestamp: string\n}\nexport interface AgentRoutingHubProps {\n  inputQuery?: string\n  classification?: RouteClassification\n  routes?: AgentRoute[]\n  selectedRouteId?: string\n  routingHistory?: RoutingHistoryEntry[]\n  isClassifying?: boolean\n  className?: string\n  onReclassify?: () => void\n  onOverrideRoute?: (routeId: string) => void\n  onViewHistory?: () => void\n}\nconst defaultRoutes: AgentRoute[] = [\n  {\n    id: \"technical\",\n    agentName: \"Technical support\",\n    specialty: \"Product troubleshooting\",\n    matchScore: 94,\n    status: \"selected\",\n    description: \"Handles errors, integrations, and product troubleshooting.\",\n  },\n  {\n    id: \"billing\",\n    agentName: \"Billing support\",\n    specialty: \"Payments and invoices\",\n    matchScore: 42,\n    status: \"available\",\n    description: \"Handles payment failures, refunds, and invoice questions.\",\n  },\n  {\n    id: \"sales\",\n    agentName: \"Sales support\",\n    specialty: \"Plans and procurement\",\n    matchScore: 18,\n    status: \"available\",\n    description: \"Handles upgrades, comparisons, and procurement.\",\n  },\n  {\n    id: \"general\",\n    agentName: \"General support\",\n    specialty: \"General questions\",\n    matchScore: 12,\n    status: \"unavailable\",\n    description: \"Handles requests without a specialist match.\",\n  },\n]\nconst baseClassification = {\n  intent: \"Technical support\",\n  confidence: 96,\n  reasoning:\n    \"The request reports a product error and asks for troubleshooting, which best matches technical support.\",\n}\nconst baseHistory: RoutingHistoryEntry[] = [\n  {\n    id: \"1\",\n    query: \"How do I upgrade my plan?\",\n    intent: \"Sales\",\n    agentName: \"Sales support\",\n    timestamp: \"2 min ago\",\n  },\n  {\n    id: \"2\",\n    query: \"Invoice 4821 is incorrect\",\n    intent: \"Billing\",\n    agentName: \"Billing support\",\n    timestamp: \"8 min ago\",\n  },\n]\nexport function RoutingHub({\n  inputQuery = \"How do I fix the payment processing error?\",\n  classification = baseClassification,\n  routes,\n  selectedRouteId,\n  routingHistory,\n  isClassifying = false,\n  className,\n  onReclassify,\n  onOverrideRoute,\n  onViewHistory,\n}: AgentRoutingHubProps) {\n  const items = routes?.length ? routes : defaultRoutes\n  const selected =\n    selectedRouteId ?? items.find((route) => route.status === \"selected\")?.id\n  const history = routingHistory?.length ? routingHistory : baseHistory\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-start sm:justify-between\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">\n            Routing decision\n          </p>\n          <h2 className=\"text-text-primary mt-1 text-lg font-semibold\">\n            {classification.intent}\n          </h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">{inputQuery}</p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={RefreshCw}\n            disabled={isClassifying}\n            onClick={onReclassify}\n          >\n            {isClassifying ? \"Classifying\" : \"Reclassify\"}\n          </Button>\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={Clock}\n            onClick={onViewHistory}\n          >\n            History\n          </Button>\n        </div>\n      </header>\n      <div className=\"border-separator-border border-b p-4\">\n        <div className=\"flex justify-between gap-4\">\n          <div>\n            <p className=\"text-text-primary text-sm font-medium\">\n              Selected route\n            </p>\n            <p className=\"text-text-secondary mt-1 text-xs leading-5\">\n              {classification.reasoning}\n            </p>\n          </div>\n          <span className=\"text-text-primary shrink-0 text-sm tabular-nums\">\n            {classification.confidence}%\n          </span>\n        </div>\n        <div\n          className=\"bg-background-secondary-default mt-3 h-1.5 overflow-hidden rounded-full\"\n          role=\"progressbar\"\n          aria-label=\"Classification confidence\"\n          aria-valuenow={classification.confidence}\n          aria-valuemin={0}\n          aria-valuemax={100}\n        >\n          <span\n            className=\"bg-accent-500 block h-full\"\n            style={{ width: `${classification.confidence}%` }}\n          />\n        </div>\n      </div>\n      <div>\n        {items.map((route) => (\n          <article\n            key={route.id}\n            className={cn(\n              \"border-separator-border flex items-start gap-3 border-b px-4 py-3 last:border-0\",\n              route.id === selected && \"bg-background-secondary-default\"\n            )}\n          >\n            <div className=\"min-w-0 flex-1\">\n              <div className=\"flex flex-wrap gap-x-3\">\n                <h3 className=\"text-text-primary text-sm font-medium\">\n                  {route.agentName}\n                </h3>\n                <span className=\"text-text-secondary text-xs\">\n                  {route.specialty}\n                </span>\n                <span\n                  className={cn(\n                    \"text-xs\",\n                    route.status === \"unavailable\"\n                      ? \"text-text-secondary\"\n                      : route.id === selected\n                        ? \"text-green-600\"\n                        : \"text-text-secondary\"\n                  )}\n                >\n                  {route.status === \"unavailable\"\n                    ? \"Unavailable\"\n                    : route.id === selected\n                      ? \"Selected\"\n                      : \"Available\"}\n                </span>\n              </div>\n              <p className=\"text-text-secondary mt-1 text-xs\">\n                {route.description}\n              </p>\n              <div className=\"mt-2 flex items-center gap-3\">\n                <div className=\"bg-background-secondary-default h-1.5 max-w-56 flex-1 overflow-hidden rounded-full\">\n                  <span\n                    className=\"bg-accent-500 block h-full\"\n                    style={{ width: `${route.matchScore}%` }}\n                  />\n                </div>\n                <span className=\"text-text-secondary text-xs\">\n                  {route.matchScore}% match\n                </span>\n              </div>\n            </div>\n            {route.id !== selected && route.status === \"available\" && (\n              <Button\n                size=\"xs\"\n                variant=\"secondary\"\n                onClick={() => onOverrideRoute?.(route.id)}\n              >\n                Select\n              </Button>\n            )}\n          </article>\n        ))}\n      </div>\n      <details className=\"group border-separator-border border-t p-4\">\n        <summary className=\"text-text-primary flex cursor-pointer list-none items-center gap-1 text-xs\">\n          <ChevronDown className=\"size-3.5 transition-transform group-open:rotate-180\" />\n          Recent decisions\n        </summary>\n        <div className=\"divide-separator-border bg-background-secondary-default mt-3 divide-y rounded-lg px-3\">\n          {history.map((item) => (\n            <div\n              key={item.id}\n              className=\"grid gap-1 py-2 text-xs sm:grid-cols-[1fr_9rem_6rem]\"\n            >\n              <span className=\"text-text-primary\">{item.query}</span>\n              <span className=\"text-text-secondary\">{item.agentName}</span>\n              <span className=\"text-text-secondary text-right\">\n                {item.timestamp}\n              </span>\n            </div>\n          ))}\n        </div>\n      </details>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-sequential-workflow",
      "type": "registry:block",
      "title": "Agent Sequential Workflow",
      "description": "agent sequential workflow",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-sequential-workflow.tsx",
          "target": "@components/agents-ui/agent-sequential-workflow.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { SequentialWorkflow } from \"@/components/agents-ui/application/sequential-workflow/sequential-workflow\"\nimport type { AgentSequentialWorkflowProps } from \"@/components/agents-ui/application/sequential-workflow/sequential-workflow\"\nimport { createElement } from \"react\"\n\nexport type {\n  AgentSequentialWorkflowProps,\n  WorkflowStep,\n  WorkflowStepStatus,\n} from \"@/components/agents-ui/application/sequential-workflow/sequential-workflow\"\nexport function AgentSequentialWorkflow(props: AgentSequentialWorkflowProps) {\n  return createElement(SequentialWorkflow, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/sequential-workflow/sequential-workflow.tsx",
          "target": "@components/agents-ui/application/sequential-workflow/sequential-workflow.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDown, Pause, Play, RefreshCw, SkipForward } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport type WorkflowStepStatus =\n  | \"waiting\"\n  | \"running\"\n  | \"completed\"\n  | \"failed\"\n  | \"skipped\"\nexport interface WorkflowStep {\n  id: string\n  number: number\n  title: string\n  agentName: string\n  inputSummary: string\n  outputSummary: string\n  status: WorkflowStepStatus\n  duration?: string\n  tokens?: number\n}\nexport interface AgentSequentialWorkflowProps {\n  workflowName?: string\n  description?: string\n  steps?: WorkflowStep[]\n  currentStepId?: string\n  totalDuration?: string\n  totalTokens?: number\n  isRunning?: boolean\n  onStart?: () => void\n  onPause?: () => void\n  onRetryStep?: (stepId: string) => void\n  onSkipStep?: (stepId: string) => void\n  onReset?: () => void\n  className?: string\n}\nconst defaults: WorkflowStep[] = [\n  {\n    id: \"research\",\n    number: 1,\n    title: \"Research\",\n    agentName: \"Research worker\",\n    inputSummary: \"Topic and source policy\",\n    outputSummary: \"Twelve sources and a structured brief\",\n    status: \"completed\",\n    duration: \"1m 42s\",\n    tokens: 4820,\n  },\n  {\n    id: \"draft\",\n    number: 2,\n    title: \"Draft\",\n    agentName: \"Writing worker\",\n    inputSummary: \"Approved research brief\",\n    outputSummary: \"First draft complete\",\n    status: \"completed\",\n    duration: \"2m 18s\",\n    tokens: 6140,\n  },\n  {\n    id: \"edit\",\n    number: 3,\n    title: \"Edit\",\n    agentName: \"Review worker\",\n    inputSummary: \"First draft\",\n    outputSummary: \"\",\n    status: \"running\",\n    tokens: 2300,\n  },\n  {\n    id: \"optimize\",\n    number: 4,\n    title: \"Optimize\",\n    agentName: \"Search worker\",\n    inputSummary: \"Edited draft\",\n    outputSummary: \"\",\n    status: \"waiting\",\n  },\n  {\n    id: \"publish\",\n    number: 5,\n    title: \"Publish\",\n    agentName: \"Publishing worker\",\n    inputSummary: \"Approved article\",\n    outputSummary: \"\",\n    status: \"waiting\",\n  },\n]\nconst text: Record<WorkflowStepStatus, string> = {\n  waiting: \"Waiting\",\n  running: \"Running\",\n  completed: \"Complete\",\n  failed: \"Failed\",\n  skipped: \"Skipped\",\n}\nconst tone: Record<WorkflowStepStatus, string> = {\n  waiting: \"text-text-secondary\",\n  running: \"text-accent-600\",\n  completed: \"text-green-600\",\n  failed: \"text-red-600\",\n  skipped: \"text-text-secondary\",\n}\nexport function SequentialWorkflow({\n  workflowName = \"Content publishing workflow\",\n  description = \"Each completed step provides the input for the next step.\",\n  steps,\n  currentStepId = \"edit\",\n  totalDuration = \"4m 00s\",\n  totalTokens = 13260,\n  isRunning = true,\n  onStart,\n  onPause,\n  onRetryStep,\n  onSkipStep,\n  onReset,\n  className,\n}: AgentSequentialWorkflowProps) {\n  const items = steps?.length ? steps : defaults\n  const [selected, setSelected] = React.useState(currentStepId)\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-start sm:justify-between\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">\n            Sequential workflow\n          </p>\n          <h2 className=\"text-text-primary mt-1 text-lg font-semibold\">\n            {workflowName}\n          </h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">{description}</p>\n        </div>\n        <div className=\"flex gap-2\">\n          {isRunning ? (\n            <Button\n              size=\"small\"\n              variant=\"secondary\"\n              leadingIcon={Pause}\n              onClick={onPause}\n            >\n              Pause\n            </Button>\n          ) : (\n            <Button size=\"small\" leadingIcon={Play} onClick={onStart}>\n              Start\n            </Button>\n          )}\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={RefreshCw}\n            onClick={onReset}\n          >\n            Reset\n          </Button>\n        </div>\n      </header>\n      <ol>\n        {items.map((step, index) => (\n          <li\n            key={step.id}\n            className=\"border-separator-border border-b last:border-0\"\n          >\n            <button\n              type=\"button\"\n              className=\"focus-visible:ring-border-focus-ring grid w-full grid-cols-[2rem_1fr_auto] gap-3 px-4 py-3 text-left outline-none focus-visible:ring-2 focus-visible:ring-inset\"\n              aria-expanded={selected === step.id}\n              onClick={() => setSelected(step.id)}\n            >\n              <span className=\"text-text-secondary text-xs tabular-nums\">\n                {String(step.number || index + 1).padStart(2, \"0\")}\n              </span>\n              <span>\n                <span className=\"flex flex-wrap gap-x-3\">\n                  <strong className=\"text-text-primary text-sm font-medium\">\n                    {step.title}\n                  </strong>\n                  <span className=\"text-text-secondary text-xs\">\n                    {step.agentName}\n                  </span>\n                </span>\n                <span className=\"text-text-secondary mt-1 block text-xs\">\n                  {step.inputSummary}\n                </span>\n              </span>\n              <span className=\"flex items-center gap-2\">\n                <span className={cn(\"text-xs\", tone[step.status])}>\n                  {text[step.status]}\n                </span>\n                <ChevronDown\n                  className={cn(\n                    \"text-text-secondary size-3.5\",\n                    selected === step.id && \"rotate-180\"\n                  )}\n                />\n              </span>\n            </button>\n            {selected === step.id && (\n              <div className=\"bg-background-secondary-default grid gap-3 px-4 py-3 text-xs sm:grid-cols-2\">\n                <div>\n                  <p className=\"text-text-primary font-medium\">Input</p>\n                  <p className=\"text-text-secondary mt-1\">\n                    {step.inputSummary}\n                  </p>\n                </div>\n                <div>\n                  <p className=\"text-text-primary font-medium\">Output</p>\n                  <p className=\"text-text-secondary mt-1\">\n                    {step.outputSummary ||\n                      \"Available when this step completes.\"}\n                  </p>\n                </div>\n                <div className=\"text-text-secondary flex gap-3\">\n                  {step.duration && <span>{step.duration}</span>}\n                  {step.tokens !== undefined && (\n                    <span>{step.tokens.toLocaleString()} tokens</span>\n                  )}\n                </div>\n                <div className=\"flex justify-end gap-2\">\n                  {step.status === \"failed\" && (\n                    <Button\n                      size=\"xs\"\n                      variant=\"secondary\"\n                      leadingIcon={RefreshCw}\n                      onClick={() => onRetryStep?.(step.id)}\n                    >\n                      Retry\n                    </Button>\n                  )}\n                  {(step.status === \"waiting\" || step.status === \"running\") && (\n                    <Button\n                      size=\"xs\"\n                      variant=\"secondary\"\n                      leadingIcon={SkipForward}\n                      onClick={() => onSkipStep?.(step.id)}\n                    >\n                      Skip\n                    </Button>\n                  )}\n                </div>\n              </div>\n            )}\n          </li>\n        ))}\n      </ol>\n      <footer className=\"text-text-secondary flex flex-wrap gap-3 px-4 py-3 text-xs\">\n        <span>\n          {items.filter((item) => item.status === \"completed\").length} of{\" \"}\n          {items.length} complete\n        </span>\n        <span>{totalDuration}</span>\n        <span>{totalTokens.toLocaleString()} tokens</span>\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-sources-citations",
      "type": "registry:block",
      "title": "Agent Sources Citations",
      "description": "agent sources citations",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-sources-citations.tsx",
          "target": "@components/agents-ui/agent-sources-citations.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { SourcesCitations } from \"@/components/agents-ui/application/sources-citations/sources-citations\"\n\nexport type SourceType = \"web\" | \"document\" | \"database\" | \"api\"\nexport interface CitationSource {\n  id: string\n  number: number\n  title: string\n  url: string\n  type: SourceType\n  relevance: number\n  snippet: string\n  verified: boolean\n}\nexport interface AgentSourcesCitationsProps {\n  content?: string\n  sources?: CitationSource[]\n  activeCitationId?: string | null\n  className?: string\n  onCitationClick?: (sourceId: string) => void\n  onSourceClick?: (sourceId: string) => void\n  onVerifySource?: (sourceId: string) => void\n  onCopyWithCitations?: () => void\n  onExportSources?: () => void\n}\nexport function AgentSourcesCitations(props: AgentSourcesCitationsProps) {\n  return <SourcesCitations {...props} />\n}\n"
        },
        {
          "path": "components/agents-ui/application/sources-citations/sources-citations.tsx",
          "target": "@components/agents-ui/application/sources-citations/sources-citations.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type {\n  AgentSourcesCitationsProps,\n  CitationSource,\n} from \"@/components/agents-ui/agent-sources-citations\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Copy, Download, ExternalLink, FileText } from \"lucide-react\"\nimport * as React from \"react\"\n\nconst fallbackSources: CitationSource[] = [\n  {\n    id: \"1\",\n    number: 1,\n    title: \"Q3 renewal forecast\",\n    url: \"renewals_q3.csv\",\n    type: \"document\",\n    relevance: 0.96,\n    snippet: \"Twelve accounts are below the renewal confidence threshold.\",\n    verified: true,\n  },\n  {\n    id: \"2\",\n    number: 2,\n    title: \"Account health notes\",\n    url: \"Salesforce\",\n    type: \"database\",\n    relevance: 0.91,\n    snippet: \"Four accounts have unresolved adoption or sponsor risks.\",\n    verified: true,\n  },\n  {\n    id: \"3\",\n    number: 3,\n    title: \"Executive sponsor coverage\",\n    url: \"CRM report\",\n    type: \"api\",\n    relevance: 0.84,\n    snippet: \"Sponsor coverage is missing for two high-value renewals.\",\n    verified: true,\n  },\n  {\n    id: \"4\",\n    number: 4,\n    title: \"Renewal playbook\",\n    url: \"Internal handbook\",\n    type: \"document\",\n    relevance: 0.79,\n    snippet: \"Escalate combined value and sponsor-risk signals this week.\",\n    verified: false,\n  },\n]\nconst fallbackContent =\n  \"The review identified 12 at-risk accounts representing $1.84M in renewal value [1]. Four need executive outreach this week because adoption has slowed or sponsor coverage is incomplete [2]. The highest priority is restoring executive ownership for the largest renewals [3]. The action plan follows the internal escalation criteria [4].\"\n\nexport function SourcesCitations({\n  content,\n  sources,\n  activeCitationId = null,\n  onCitationClick,\n  onSourceClick,\n  onVerifySource,\n  onCopyWithCitations,\n  onExportSources,\n  className,\n}: AgentSourcesCitationsProps) {\n  const useFallback = content === undefined && sources === undefined\n  const displayContent = useFallback ? fallbackContent : (content ?? \"\")\n  const displaySources = useFallback ? fallbackSources : (sources ?? [])\n  const [selected, setSelected] = React.useState(activeCitationId)\n  React.useEffect(() => setSelected(activeCitationId), [activeCitationId])\n  const answer = displayContent.split(/(\\[\\d+\\])/).map((part, index) => {\n    const match = /^\\[(\\d+)\\]$/.exec(part)\n    const source = match\n      ? displaySources.find((item) => item.number === Number(match[1]))\n      : undefined\n    return source ? (\n      <button\n        key={index}\n        type=\"button\"\n        aria-label={`View source ${source.number}: ${source.title}`}\n        onClick={() => {\n          setSelected(source.id)\n          onCitationClick?.(source.id)\n        }}\n        className={cx(\n          \"text-accent-600 focus:ring-border-focus-ring mx-0.5 min-h-6 rounded-sm px-1 text-xs underline outline-none focus:ring-2\",\n          selected === source.id && \"bg-background-secondary-default\"\n        )}\n      >\n        [{source.number}]\n      </button>\n    ) : (\n      <React.Fragment key={index}>{part}</React.Fragment>\n    )\n  })\n\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full max-w-[880px] rounded-xl border p-5\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-3 border-b pb-4\">\n        <div>\n          <h2 className=\"text-text-primary text-lg font-semibold\">Sources</h2>\n          <p className=\"text-text-secondary mt-1 text-xs\">\n            {displaySources.length} references\n          </p>\n        </div>\n        <div className=\"flex gap-2\">\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={Copy}\n            onClick={onCopyWithCitations}\n          >\n            Copy answer\n          </Button>\n          <Button\n            variant=\"secondary\"\n            size=\"small\"\n            leadingIcon={Download}\n            onClick={onExportSources}\n          >\n            Export\n          </Button>\n        </div>\n      </header>\n      <div className=\"grid gap-6 py-5 md:grid-cols-[3fr_2fr]\">\n        <article className=\"text-text-primary text-sm leading-7\">\n          {displayContent ? (\n            answer\n          ) : (\n            <p className=\"text-text-secondary\">No answer content provided.</p>\n          )}\n        </article>\n        <div>\n          {displaySources.length === 0 ? (\n            <div className=\"border-separator-border border-y py-6 text-center\">\n              <p className=\"text-text-primary text-sm font-medium\">\n                No sources provided\n              </p>\n              <p className=\"text-text-secondary mt-1 text-xs\">\n                References will appear here when they are available.\n              </p>\n            </div>\n          ) : (\n            <div className=\"divide-separator-border border-separator-border divide-y border-y md:border-l md:pl-5\">\n              {displaySources.map((source) => (\n                <div\n                  key={source.id}\n                  className={cx(\n                    \"py-3\",\n                    selected === source.id && \"bg-background-secondary-default\"\n                  )}\n                >\n                  <div className=\"flex gap-3\">\n                    <FileText className=\"text-text-secondary mt-0.5 size-4 shrink-0\" />\n                    <button\n                      type=\"button\"\n                      className=\"min-w-0 flex-1 text-left\"\n                      onClick={() => {\n                        setSelected(source.id)\n                        onSourceClick?.(source.id)\n                      }}\n                    >\n                      <span className=\"block text-sm font-medium\">\n                        {source.number}. {source.title}\n                      </span>\n                      <span className=\"text-text-secondary block text-xs\">\n                        {source.url}\n                      </span>\n                    </button>\n                    <button\n                      type=\"button\"\n                      aria-label={`Open ${source.title}`}\n                      onClick={() => onSourceClick?.(source.id)}\n                    >\n                      <ExternalLink className=\"text-text-secondary size-4\" />\n                    </button>\n                  </div>\n                  <p className=\"text-text-secondary mt-2 pl-7 text-xs leading-5\">\n                    {source.snippet}\n                  </p>\n                  <div className=\"text-text-secondary mt-2 flex gap-3 pl-7 text-xs\">\n                    {source.verified ? (\n                      <span className=\"flex items-center gap-1\">\n                        <Check className=\"size-3 text-green-600\" />\n                        Verified\n                      </span>\n                    ) : (\n                      <button\n                        type=\"button\"\n                        className=\"underline\"\n                        onClick={() => onVerifySource?.(source.id)}\n                      >\n                        Verify source\n                      </button>\n                    )}\n                    {Number.isFinite(source.relevance) && (\n                      <span>\n                        {Math.round(source.relevance * 100)}% relevance\n                      </span>\n                    )}\n                  </div>\n                </div>\n              ))}\n            </div>\n          )}\n        </div>\n      </div>\n      <p className=\"border-separator-border text-text-secondary border-t pt-3 text-xs\">\n        {displaySources.length} sources ·{\" \"}\n        {displaySources.filter((source) => source.verified).length} verified\n      </p>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-status-panel",
      "type": "registry:block",
      "title": "Agent Status Panel",
      "description": "agent status panel",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-status-panel.tsx",
          "target": "@components/agents-ui/agent-status-panel.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { StatusPanel } from \"@/components/agents-ui/application/status-panel/status-panel\"\nimport type { AgentStatusPanelProps } from \"@/components/agents-ui/application/status-panel/status-panel\"\nimport { createElement } from \"react\"\n\nexport type {\n  AgentStatusPanelProps,\n  ConnectionStatus,\n  ModelCapability,\n  ModelInfo,\n  SystemResources,\n} from \"@/components/agents-ui/application/status-panel/status-panel\"\nexport function AgentStatusPanel(props: AgentStatusPanelProps) {\n  return createElement(StatusPanel, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/status-panel/status-panel.tsx",
          "target": "@components/agents-ui/application/status-panel/status-panel.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cn } from \"@/lib/utils\"\nimport { Power, RefreshCw, Settings } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport type ConnectionStatus =\n  | \"connected\"\n  | \"connecting\"\n  | \"disconnected\"\n  | \"error\"\nexport type ModelCapability =\n  | \"chat\"\n  | \"code\"\n  | \"vision\"\n  | \"function-calling\"\n  | \"embedding\"\nexport interface ModelInfo {\n  name: string\n  provider: string\n  contextLength: number\n  capabilities: ModelCapability[]\n  costPer1kTokens?: { input: number; output: number }\n}\nexport interface SystemResources {\n  cpu: number\n  memory: number\n  latency: number\n  uptime: string\n}\nexport interface AgentStatusPanelProps {\n  connectionStatus?: ConnectionStatus\n  modelInfo?: ModelInfo\n  systemResources?: SystemResources\n  version?: string\n  onReconnect?: () => void\n  onRefresh?: () => void\n  onSettings?: () => void\n  className?: string\n  compact?: boolean\n}\nconst statusText: Record<ConnectionStatus, string> = {\n  connected: \"Connected\",\n  connecting: \"Connecting\",\n  disconnected: \"Disconnected\",\n  error: \"Connection error\",\n}\nconst statusTone: Record<ConnectionStatus, string> = {\n  connected: \"text-green-600\",\n  connecting: \"text-accent-600\",\n  disconnected: \"text-text-secondary\",\n  error: \"text-red-600\",\n}\nconst capabilityText: Record<ModelCapability, string> = {\n  chat: \"Chat\",\n  code: \"Code\",\n  vision: \"Vision\",\n  \"function-calling\": \"Tools\",\n  embedding: \"Embeddings\",\n}\nexport function StatusPanel({\n  connectionStatus = \"connected\",\n  modelInfo,\n  systemResources,\n  version = \"1.0.0\",\n  onReconnect,\n  onRefresh,\n  onSettings,\n  className,\n  compact = false,\n}: AgentStatusPanelProps) {\n  const [refreshing, setRefreshing] = React.useState(false)\n  const refresh = () => {\n    setRefreshing(true)\n    onRefresh?.()\n    window.setTimeout(() => setRefreshing(false), 1000)\n  }\n  if (compact)\n    return (\n      <section\n        className={cn(\n          \"border-separator-border bg-background-primary-default rounded-xl border p-3\",\n          className\n        )}\n      >\n        <div className=\"flex items-center justify-between gap-3\">\n          <span\n            className={cn(\"text-sm font-medium\", statusTone[connectionStatus])}\n          >\n            {statusText[connectionStatus]}\n          </span>\n          <div className=\"flex gap-1\">\n            {connectionStatus === \"disconnected\" && onReconnect && (\n              <Button\n                size=\"xs\"\n                variant=\"ghost\"\n                iconOnly\n                leadingIcon={Power}\n                aria-label=\"Reconnect\"\n                onClick={onReconnect}\n              />\n            )}\n            <Button\n              size=\"xs\"\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={RefreshCw}\n              aria-label=\"Refresh status\"\n              onClick={refresh}\n            />\n            {onSettings && (\n              <Button\n                size=\"xs\"\n                variant=\"ghost\"\n                iconOnly\n                leadingIcon={Settings}\n                aria-label=\"Open settings\"\n                onClick={onSettings}\n              />\n            )}\n          </div>\n        </div>\n        {modelInfo && (\n          <p className=\"text-text-secondary mt-2 text-xs\">\n            {modelInfo.name} · {modelInfo.provider}\n          </p>\n        )}\n      </section>\n    )\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex items-start justify-between gap-3 border-b p-4\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">\n            Runtime status\n          </p>\n          <h2 className=\"text-text-primary mt-1 text-lg font-semibold\">\n            Agent connection\n          </h2>\n          <p className=\"text-text-secondary mt-1 text-xs\">Version {version}</p>\n        </div>\n        <div className=\"flex gap-1\">\n          <Button\n            size=\"small\"\n            variant=\"ghost\"\n            iconOnly\n            leadingIcon={RefreshCw}\n            aria-label={refreshing ? \"Refreshing status\" : \"Refresh status\"}\n            onClick={refresh}\n          />\n          {onSettings && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              iconOnly\n              leadingIcon={Settings}\n              aria-label=\"Open settings\"\n              onClick={onSettings}\n            />\n          )}\n        </div>\n      </header>\n      <div className=\"border-separator-border flex items-center justify-between border-b px-4 py-3\">\n        <span\n          className={cn(\"text-sm font-medium\", statusTone[connectionStatus])}\n        >\n          {statusText[connectionStatus]}\n        </span>\n        {(connectionStatus === \"disconnected\" ||\n          connectionStatus === \"error\") &&\n          onReconnect && (\n            <Button\n              size=\"xs\"\n              variant=\"secondary\"\n              leadingIcon={Power}\n              onClick={onReconnect}\n            >\n              Reconnect\n            </Button>\n          )}\n      </div>\n      {modelInfo && (\n        <div className=\"border-separator-border border-b p-4\">\n          <h3 className=\"text-text-primary text-sm font-medium\">\n            {modelInfo.name}\n          </h3>\n          <p className=\"text-text-secondary mt-1 text-xs\">\n            {modelInfo.provider} · {modelInfo.contextLength.toLocaleString()}{\" \"}\n            token context\n          </p>\n          <div className=\"mt-3 flex flex-wrap gap-2\">\n            {modelInfo.capabilities.map((item) => (\n              <span\n                key={item}\n                className=\"bg-background-secondary-default text-text-secondary rounded-md px-2 py-1 text-xs\"\n              >\n                {capabilityText[item]}\n              </span>\n            ))}\n          </div>\n          {modelInfo.costPer1kTokens && (\n            <p className=\"text-text-secondary mt-3 text-xs\">\n              Input ${modelInfo.costPer1kTokens.input}/1K · Output $\n              {modelInfo.costPer1kTokens.output}/1K\n            </p>\n          )}\n        </div>\n      )}\n      {systemResources && (\n        <div className=\"p-4\">\n          <p className=\"text-text-primary text-sm font-medium\">Resources</p>\n          <div className=\"mt-3 space-y-3\">\n            {[\n              [\"CPU\", systemResources.cpu, \"%\"],\n              [\"Memory\", systemResources.memory, \"%\"],\n              [\"Latency\", systemResources.latency, \" ms\"],\n            ].map(([label, value, unit]) => (\n              <div\n                key={label as string}\n                className=\"grid grid-cols-[5rem_1fr_auto] items-center gap-3 text-xs\"\n              >\n                <span className=\"text-text-secondary\">{label}</span>\n                <div className=\"bg-background-secondary-default h-1.5 overflow-hidden rounded-full\">\n                  <span\n                    className=\"bg-accent-500 block h-full\"\n                    style={{ width: `${Math.min(Number(value), 100)}%` }}\n                  />\n                </div>\n                <span className=\"text-text-primary tabular-nums\">\n                  {value}\n                  {unit}\n                </span>\n              </div>\n            ))}\n          </div>\n          <p className=\"border-separator-border text-text-secondary mt-3 border-t pt-3 text-xs\">\n            Uptime {systemResources.uptime}\n          </p>\n        </div>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-task-queue",
      "type": "registry:block",
      "title": "Agent Task Queue",
      "description": "agent task queue",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-task-queue.tsx",
          "target": "@components/agents-ui/agent-task-queue.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { TaskQueue } from \"@/components/agents-ui/application/task-queue/task-queue\"\nimport type { AgentTaskQueueProps } from \"@/components/agents-ui/application/task-queue/task-queue\"\nimport { createElement } from \"react\"\n\nexport type {\n  AgentTask,\n  AgentTaskAssignee,\n  AgentTaskPriority,\n  AgentTaskQueueProps,\n  AgentTaskStatus,\n  AgentTaskTimelineEvent,\n  AgentTaskTimelineStatus,\n} from \"@/components/agents-ui/application/task-queue/task-queue\"\nexport function AgentTaskQueue(props: AgentTaskQueueProps) {\n  return createElement(TaskQueue, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/task-queue/task-queue.tsx",
          "target": "@components/agents-ui/application/task-queue/task-queue.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Switch } from \"@/components/boardui/base/switch/switch\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  ChevronDown,\n  Pause,\n  Play,\n  Plus,\n  RefreshCw,\n  SlidersHorizontal,\n} from \"lucide-react\"\n\nexport type AgentTaskStatus =\n  | \"queued\"\n  | \"running\"\n  | \"completed\"\n  | \"failed\"\n  | \"blocked\"\n  | \"paused\"\nexport type AgentTaskPriority = \"low\" | \"medium\" | \"high\"\nexport type AgentTaskTimelineStatus = \"pending\" | \"active\" | \"completed\"\nexport interface AgentTaskTimelineEvent {\n  id: string\n  title: string\n  description?: string\n  status: AgentTaskTimelineStatus\n  timestamp?: string\n}\nexport interface AgentTaskAssignee {\n  name: string\n  avatarColor?: string\n  initials?: string\n}\nexport interface AgentTask {\n  id: string\n  title: string\n  description?: string\n  status: AgentTaskStatus\n  progress?: number\n  priority?: AgentTaskPriority\n  createdAt?: string\n  updatedAt?: string\n  updatedLabel?: string\n  estimatedDuration?: string\n  tool?: string\n  assignee?: AgentTaskAssignee\n  checkpoints?: AgentTaskTimelineEvent[]\n  relatedResources?: Array<{ label: string; href?: string }>\n  metrics?: { tokens?: number; cost?: string; confidence?: number }\n}\nexport interface AgentTaskQueueProps {\n  tasks?: AgentTask[]\n  activeTaskId?: string | null\n  autoStart?: boolean\n  concurrencyLimit?: number\n  isProcessing?: boolean\n  showTimeline?: boolean\n  timestamp?: string\n  className?: string\n  onStartTask?: (taskId: string) => void\n  onPauseTask?: (taskId: string) => void\n  onResumeTask?: (taskId: string) => void\n  onCancelTask?: (taskId: string) => void\n  onReorder?: (taskIds: string[]) => void\n  onToggleAutoStart?: (value: boolean) => void\n  onClearCompleted?: () => void\n  onAddTask?: () => void\n}\n\nconst sampleTasks: AgentTask[] = [\n  {\n    id: \"pricing\",\n    title: \"Collect competitor pricing\",\n    description: \"Review public pricing pages and normalize plan details.\",\n    status: \"running\",\n    progress: 62,\n    priority: \"high\",\n    tool: \"Web research\",\n    updatedLabel: \"Updated 2 min ago\",\n    estimatedDuration: \"4 min remaining\",\n    checkpoints: [\n      {\n        id: \"urls\",\n        title: \"Find primary sources\",\n        status: \"completed\",\n        timestamp: \"09:02\",\n      },\n      {\n        id: \"extract\",\n        title: \"Extract plan details\",\n        status: \"active\",\n        timestamp: \"09:08\",\n      },\n      { id: \"normalize\", title: \"Normalize pricing\", status: \"pending\" },\n    ],\n    relatedResources: [\n      { label: \"pricing-data.json\" },\n      { label: \"source-log.txt\" },\n    ],\n    metrics: { tokens: 1840, cost: \"$0.21\", confidence: 0.84 },\n  },\n  {\n    id: \"standups\",\n    title: \"Summarize weekly standups\",\n    description: \"Combine transcripts and identify team blockers.\",\n    status: \"queued\",\n    priority: \"medium\",\n    tool: \"Transcription\",\n    updatedLabel: \"Next in queue\",\n  },\n  {\n    id: \"release\",\n    title: \"Draft release notes\",\n    description: \"Prepare customer-facing highlights for the next release.\",\n    status: \"queued\",\n    priority: \"high\",\n    tool: \"Documentation\",\n    updatedLabel: \"Queued\",\n  },\n  {\n    id: \"security\",\n    title: \"Review security prompts\",\n    description: \"Evaluate policy edge cases before publishing.\",\n    status: \"paused\",\n    progress: 34,\n    priority: \"high\",\n    tool: \"Safety review\",\n    updatedLabel: \"Paused for approval\",\n  },\n  {\n    id: \"analytics\",\n    title: \"Refresh analytics snapshot\",\n    status: \"completed\",\n    progress: 100,\n    tool: \"Metrics pipeline\",\n    updatedLabel: \"Completed 18:40\",\n  },\n  {\n    id: \"contacts\",\n    title: \"Sync CRM contacts\",\n    status: \"failed\",\n    tool: \"CRM connector\",\n    updatedLabel: \"API timeout\",\n  },\n]\n\nconst taskStatusText: Record<AgentTaskStatus, string> = {\n  queued: \"Queued\",\n  running: \"Running\",\n  completed: \"Complete\",\n  failed: \"Failed\",\n  blocked: \"Blocked\",\n  paused: \"Paused\",\n}\nconst taskStatusClass: Record<AgentTaskStatus, string> = {\n  queued: \"text-text-secondary\",\n  running: \"text-accent-600\",\n  completed: \"text-green-600\",\n  failed: \"text-red-600\",\n  blocked: \"text-amber-700\",\n  paused: \"text-text-secondary\",\n}\n\nfunction TaskControl({\n  task,\n  disabled,\n  props,\n}: {\n  task: AgentTask\n  disabled: boolean\n  props: AgentTaskQueueProps\n}) {\n  if (task.status === \"running\")\n    return (\n      <Button\n        size=\"xs\"\n        variant=\"secondary\"\n        leadingIcon={Pause}\n        disabled={disabled}\n        onClick={() => props.onPauseTask?.(task.id)}\n      >\n        Pause\n      </Button>\n    )\n  if (task.status === \"paused\")\n    return (\n      <Button\n        size=\"xs\"\n        variant=\"secondary\"\n        leadingIcon={Play}\n        disabled={disabled}\n        onClick={() => props.onResumeTask?.(task.id)}\n      >\n        Resume\n      </Button>\n    )\n  if (task.status === \"queued\")\n    return (\n      <Button\n        size=\"xs\"\n        variant=\"secondary\"\n        leadingIcon={Play}\n        disabled={disabled}\n        onClick={() => props.onStartTask?.(task.id)}\n      >\n        Start\n      </Button>\n    )\n  if (task.status === \"failed\")\n    return (\n      <Button\n        size=\"xs\"\n        variant=\"secondary\"\n        leadingIcon={RefreshCw}\n        disabled={disabled}\n        onClick={() => props.onCancelTask?.(task.id)}\n      >\n        Reset\n      </Button>\n    )\n  return null\n}\n\nexport function TaskQueue(props: AgentTaskQueueProps) {\n  const {\n    tasks,\n    activeTaskId = null,\n    autoStart = true,\n    concurrencyLimit = 1,\n    isProcessing = false,\n    showTimeline = true,\n    timestamp = \"Updated moments ago\",\n    className,\n  } = props\n  const records = tasks?.length ? tasks : sampleTasks\n  const ordered = activeTaskId\n    ? [...records].sort((a, b) =>\n        a.id === activeTaskId ? -1 : b.id === activeTaskId ? 1 : 0\n      )\n    : records\n  const queued = records.filter((task) => task.status === \"queued\")\n  const completed = records.filter((task) => task.status === \"completed\").length\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n      aria-label=\"Agent task queue\"\n    >\n      <header className=\"border-separator-border flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-start sm:justify-between\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">\n            Execution queue\n          </p>\n          <h2 className=\"text-text-primary mt-1 text-lg font-semibold\">\n            Active work\n          </h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">\n            Monitor current work and control the tasks waiting to run.\n          </p>\n        </div>\n        <div className=\"flex flex-wrap gap-2\">\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={SlidersHorizontal}\n            onClick={() => props.onReorder?.(queued.map((task) => task.id))}\n          >\n            Optimize\n          </Button>\n          <Button size=\"small\" leadingIcon={Plus} onClick={props.onAddTask}>\n            Add task\n          </Button>\n        </div>\n      </header>\n      <div className=\"border-separator-border text-text-secondary flex flex-wrap items-center gap-x-4 gap-y-2 border-b px-4 py-2.5 text-xs\">\n        <span>\n          {records.filter((task) => task.status === \"running\").length} running\n        </span>\n        <span>{queued.length} queued</span>\n        <span>{completed} complete</span>\n        <span>Limit {concurrencyLimit}</span>\n        <Switch\n          size=\"sm\"\n          isSelected={autoStart}\n          onChange={props.onToggleAutoStart}\n          className=\"ml-auto\"\n        >\n          Auto-start\n        </Switch>\n      </div>\n      <div>\n        {ordered.map((task) => (\n          <article\n            key={task.id}\n            className=\"border-separator-border border-b last:border-0\"\n          >\n            <div className=\"flex items-start gap-3 px-4 py-3\">\n              <div className=\"min-w-0 flex-1\">\n                <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1\">\n                  <h3 className=\"text-text-primary text-sm font-medium\">\n                    {task.title}\n                  </h3>\n                  <span className={cn(\"text-xs\", taskStatusClass[task.status])}>\n                    {taskStatusText[task.status]}\n                  </span>\n                </div>\n                {task.description && (\n                  <p className=\"text-text-secondary mt-1 text-xs leading-5\">\n                    {task.description}\n                  </p>\n                )}\n                <div className=\"text-text-secondary mt-2 flex flex-wrap gap-x-3 text-xs\">\n                  {task.tool && <span>{task.tool}</span>}\n                  {task.updatedLabel && <span>{task.updatedLabel}</span>}\n                  {task.estimatedDuration && (\n                    <span>{task.estimatedDuration}</span>\n                  )}\n                </div>\n                {typeof task.progress === \"number\" && (\n                  <div className=\"mt-3 flex items-center gap-3\">\n                    <div\n                      className=\"bg-background-secondary-default h-1.5 flex-1 overflow-hidden rounded-full\"\n                      role=\"progressbar\"\n                      aria-label={`${task.title} progress`}\n                      aria-valuemin={0}\n                      aria-valuemax={100}\n                      aria-valuenow={task.progress}\n                    >\n                      <span\n                        className=\"bg-accent-500 block h-full\"\n                        style={{\n                          width: `${Math.max(0, Math.min(100, task.progress))}%`,\n                        }}\n                      />\n                    </div>\n                    <span className=\"text-text-secondary text-xs tabular-nums\">\n                      {task.progress}%\n                    </span>\n                  </div>\n                )}\n              </div>\n              <TaskControl task={task} disabled={isProcessing} props={props} />\n            </div>\n            {(task.checkpoints?.length ||\n              task.metrics ||\n              task.relatedResources?.length) && (\n              <details className=\"group px-4 pb-3\">\n                <summary className=\"text-text-secondary flex w-fit cursor-pointer list-none items-center gap-1 text-xs\">\n                  <ChevronDown className=\"size-3.5 transition-transform group-open:rotate-180\" />\n                  Details\n                </summary>\n                <div className=\"bg-background-secondary-default mt-3 grid gap-4 rounded-lg p-3 text-xs sm:grid-cols-2\">\n                  {showTimeline && task.checkpoints && (\n                    <ol className=\"space-y-2\">\n                      {task.checkpoints.map((item) => (\n                        <li\n                          key={item.id}\n                          className=\"flex justify-between gap-3\"\n                        >\n                          <span className=\"text-text-primary\">\n                            {item.title}\n                          </span>\n                          <span className=\"text-text-secondary\">\n                            {item.timestamp || item.status}\n                          </span>\n                        </li>\n                      ))}\n                    </ol>\n                  )}\n                  <div className=\"text-text-secondary space-y-2\">\n                    {task.metrics?.tokens !== undefined && (\n                      <p>{task.metrics.tokens.toLocaleString()} tokens</p>\n                    )}\n                    {task.metrics?.cost && (\n                      <p>{task.metrics.cost} estimated cost</p>\n                    )}\n                    {task.metrics?.confidence !== undefined && (\n                      <p>\n                        {Math.round(task.metrics.confidence * 100)}% confidence\n                      </p>\n                    )}\n                    {task.relatedResources?.map((resource) =>\n                      resource.href ? (\n                        <a\n                          className=\"text-accent-600 block\"\n                          key={resource.label}\n                          href={resource.href}\n                        >\n                          {resource.label}\n                        </a>\n                      ) : (\n                        <p key={resource.label}>{resource.label}</p>\n                      )\n                    )}\n                  </div>\n                </div>\n              </details>\n            )}\n          </article>\n        ))}\n      </div>\n      <footer className=\"border-separator-border text-text-secondary flex flex-wrap items-center gap-3 border-t px-4 py-3 text-xs\">\n        <span>{timestamp}</span>\n        <span>{records.length} tasks</span>\n        {completed > 0 && (\n          <button\n            type=\"button\"\n            className=\"text-text-primary ml-auto\"\n            onClick={props.onClearCompleted}\n          >\n            Clear completed\n          </button>\n        )}\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/switch/switch.tsx",
          "target": "@components/boardui/base/switch/switch.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type { ReactNode, Ref } from \"react\"\nimport { Switch as AriaSwitch } from \"react-aria-components\"\nimport type { SwitchProps as AriaSwitchProps } from \"react-aria-components\"\n\n/** BoardUI switch with a flat track, native semantics, and keyboard focus. */\n\nexport type SwitchSize = \"sm\" | \"md\" | \"lg\"\nexport type SwitchShape = \"pill\" | \"rectangle\"\n\nexport const switchSizes = sortCx({\n  sm: {\n    track: \"h-4 w-7\",\n    trackRadius: { pill: \"rounded-full\", rectangle: \"rounded-[3px]\" },\n    onShadow:\n      \"shadow-[inset_0_1px_0_0_rgb(255_255_255/0.25),inset_0_0_0_0.5px_var(--color-accent-500)]\",\n    thumb: \"size-3\",\n    thumbRadius: { pill: \"rounded-full\", rectangle: \"rounded-[1px]\" },\n    offset: \"left-0.5 top-0.5\",\n    travel: \"translate-x-3\",\n    chip: \"size-[5px] border-[0.25px] shadow-[0_2px_2px_0_rgb(0_0_0/0.03)]\",\n    chipRadius: { pill: \"rounded-full\", rectangle: \"rounded-[0.5px]\" },\n  },\n  md: {\n    track: \"h-6 w-[42px]\",\n    trackRadius: { pill: \"rounded-full\", rectangle: \"rounded-[4.5px]\" },\n    onShadow:\n      \"shadow-[inset_0_1.5px_0_0_rgb(255_255_255/0.25),inset_0_0_0_0.75px_var(--color-accent-500)]\",\n    thumb: \"size-[18px]\",\n    thumbRadius: { pill: \"rounded-full\", rectangle: \"rounded-[1.5px]\" },\n    offset: \"left-[3px] top-[3px]\",\n    travel: \"translate-x-[18px]\",\n    chip: \"size-[7.5px] border-[0.375px] shadow-[0_3px_3px_0_rgb(0_0_0/0.03)]\",\n    chipRadius: { pill: \"rounded-full\", rectangle: \"rounded-[0.75px]\" },\n  },\n  lg: {\n    track: \"h-8 w-14\",\n    trackRadius: { pill: \"rounded-full\", rectangle: \"rounded-md\" },\n    onShadow: \"shadow-checkbox-selected\",\n    thumb: \"size-6\",\n    thumbRadius: { pill: \"rounded-full\", rectangle: \"rounded-xs\" },\n    offset: \"left-1 top-1\",\n    travel: \"translate-x-6\",\n    chip: \"size-[10px] border-[0.5px] shadow-[0_4px_4px_0_rgb(0_0_0/0.03)]\",\n    chipRadius: { pill: \"rounded-full\", rectangle: \"rounded-[1px]\" },\n  },\n})\n\nexport interface SwitchVisualState {\n  isSelected: boolean\n  isDisabled: boolean\n  isFocusVisible: boolean\n}\n\n/**\n * The track + thumb + chip visual. Pure presentation - the react-aria Switch\n * (in `Switch` or `SwitchCard`) owns the input and passes its render state in.\n */\nexport function SwitchTrack({\n  state,\n  size = \"md\",\n  shape = \"pill\",\n}: {\n  state: SwitchVisualState\n  size?: SwitchSize\n  shape?: SwitchShape\n}) {\n  const s = switchSizes[size]\n\n  return (\n    <span\n      aria-hidden\n      className={cx(\n        \"relative inline-block shrink-0 transition-colors duration-150\",\n        s.track,\n        s.trackRadius[shape],\n        state.isSelected ? \"bg-accent-500\" : \"bg-background-tertiary-default\",\n        state.isDisabled && \"opacity-50\",\n        state.isFocusVisible && \"ring-border-focus-ring ring-2 ring-offset-2\"\n      )}\n    >\n      {/* Thumb */}\n      <span\n        className={cx(\n          \"absolute flex items-center justify-center\",\n          \"bg-control-indicator-background\",\n          \"shadow-[0_3px_3px_0_rgb(0_0_0/0.03),0_0.75px_0_0_rgb(0_0_0/0.05)]\",\n          \"transition-transform duration-150\",\n          s.thumb,\n          s.thumbRadius[shape],\n          s.offset,\n          state.isSelected && s.travel\n        )}\n      ></span>\n    </span>\n  )\n}\n\nexport interface SwitchProps extends Omit<AriaSwitchProps, \"children\"> {\n  children?: ReactNode\n  size?: SwitchSize\n  shape?: SwitchShape\n  ref?: Ref<HTMLLabelElement>\n}\n\nexport function Switch({\n  className,\n  children,\n  size = \"md\",\n  shape = \"pill\",\n  ref,\n  ...props\n}: SwitchProps) {\n  return (\n    <AriaSwitch\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"group inline-flex items-center gap-2 select-none\",\n          state.isDisabled ? \"cursor-not-allowed\" : \"cursor-pointer\",\n          typeof className === \"function\" ? className(state) : className\n        )\n      }\n    >\n      {(state) => (\n        <>\n          <SwitchTrack state={state} size={size} shape={shape} />\n          {children != null && children !== false && (\n            <span className=\"text-body-medium text-text-primary\">\n              {children}\n            </span>\n          )}\n        </>\n      )}\n    </AriaSwitch>\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-thinking-indicator",
      "type": "registry:block",
      "title": "Agent Thinking Indicator",
      "description": "agent thinking indicator",
      "dependencies": [
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-thinking-indicator.tsx",
          "target": "@components/agents-ui/agent-thinking-indicator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\nexport {\n  GRAVITY_DEFAULTS,\n  ThinkingIndicator,\n  ThinkingOrb,\n  attachGravity,\n  getGravityConfig,\n  getGravityStatus,\n  resetGravity,\n  setGravityConfig,\n  setGravitySprite,\n} from \"@/components/agents-ui/application/thinking-indicator/thinking-indicator\"\nexport type {\n  CursorSprite,\n  GravityOptions,\n  ThinkingIndicatorProps,\n  ThinkingOrbProps,\n  ThinkingOrbSize,\n  ThinkingState,\n} from \"@/components/agents-ui/application/thinking-indicator/thinking-indicator\"\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/thinking-indicator.tsx",
          "target": "@components/agents-ui/application/thinking-indicator/thinking-indicator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { ThinkingOrb as UpstreamThinkingOrb } from \"./upstream/ThinkingOrb\"\nimport type {\n  OrbSize,\n  OrbState,\n  ThinkingOrbProps as UpstreamThinkingOrbProps,\n} from \"./upstream/types\"\n\nexport type ThinkingState = OrbState\nexport type ThinkingOrbSize = OrbSize\nexport type ThinkingOrbProps = UpstreamThinkingOrbProps\n\nexport interface ThinkingIndicatorProps\n  extends Pick<\n    UpstreamThinkingOrbProps,\n    | \"theme\"\n    | \"speed\"\n    | \"color\"\n    | \"dots\"\n    | \"dotSize\"\n    | \"opts\"\n    | \"frame\"\n    | \"gravity\"\n  > {\n  state?: ThinkingState\n  size?: ThinkingOrbSize\n  label?: string\n  paused?: boolean\n  detail?: string\n  className?: string\n}\n\nconst labels: Record<ThinkingState, string> = {\n  working: \"Working\",\n  searching: \"Searching\",\n  solving: \"Solving\",\n  listening: \"Listening\",\n  connecting: \"Connecting\",\n  weaving: \"Weaving\",\n  composing: \"Composing\",\n  breathing: \"Thinking\",\n  shaping: \"Shaping response\",\n}\n\nexport const ThinkingOrb = UpstreamThinkingOrb\n\nexport {\n  GRAVITY_DEFAULTS,\n  attachGravity,\n  getGravityConfig,\n  getGravityStatus,\n  resetGravity,\n  setGravityConfig,\n  setGravitySprite,\n} from \"./upstream\"\nexport type { CursorSprite, GravityOptions } from \"./upstream\"\n\nexport function ThinkingIndicator({\n  state = \"working\",\n  size = 20,\n  label,\n  paused = false,\n  detail,\n  className,\n  theme,\n  speed,\n  color,\n  dots,\n  dotSize,\n  opts,\n  frame,\n  gravity,\n}: ThinkingIndicatorProps) {\n  const text = label ?? labels[state]\n  return (\n    <div\n      className={cx(\n        \"border-separator-border bg-background-primary-default inline-flex items-center gap-2.5 rounded-lg border px-3 py-2\",\n        className\n      )}\n      role=\"status\"\n      aria-live=\"polite\"\n    >\n      <span aria-hidden=\"true\">\n        <ThinkingOrb\n          state={state}\n          size={size}\n          paused={paused}\n          theme={theme}\n          speed={speed}\n          color={color}\n          dots={dots}\n          dotSize={dotSize}\n          opts={opts}\n          frame={frame}\n          gravity={gravity}\n        />\n      </span>\n      <span className=\"min-w-0\">\n        <span className=\"text-text-primary block text-sm font-medium\">\n          {text}\n        </span>\n        {detail && (\n          <span className=\"text-text-secondary mt-0.5 block text-xs\">\n            {detail}\n          </span>\n        )}\n      </span>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/ThinkingOrb.tsx",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/ThinkingOrb.tsx",
          "type": "registry:component",
          "content": "// The ThinkingOrb component. One shared clock (performance.now) keeps\n// every mounted orb in phase; each instance runs its own rAF loop but\n// pauses automatically while offscreen (IntersectionObserver) or when\n// the tab is hidden (visibilitychange). Reduced-motion users get a\n// static representative frame that still follows the live theme.\n\nimport { useEffect, useRef } from 'react';\nimport { paintFrame, type OrbTint } from './engine/core';\nimport { scaleCounts, scaleRadii } from './engine/profiles';\nimport { MODE_FRAMES } from './engine/registry';\nimport { resolvePreset } from './presets';\nimport { useReducedMotion, useResolvedDark } from './theme';\nimport { attachGravity } from './gravity';\nimport type { ThinkingOrbProps } from './types';\n\n/** Parse a CSS color into an RGB triple for the tinted ink painter.\n *  Supports #rgb, #rrggbb and rgb()/rgba(); anything else -> no tint. */\nfunction parseTint(color: string | undefined): OrbTint | undefined {\n  if (!color) return undefined;\n  const hex = color.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);\n  if (hex) {\n    let h = hex[1];\n    if (h.length === 3) h = h.replace(/./g, (c) => c + c);\n    const n = parseInt(h, 16);\n    return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\n  }\n  const fn = color.trim().match(/^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i);\n  if (fn) return { r: Number(fn[1]), g: Number(fn[2]), b: Number(fn[3]) };\n  return undefined;\n}\n\nconst LABELS: Record<string, string> = {\n  working: 'Working…',\n  searching: 'Searching…',\n  solving: 'Solving…',\n  listening: 'Listening…',\n  connecting: 'Connecting…',\n  weaving: 'Weaving…',\n  composing: 'Composing…',\n  breathing: 'Thinking…',\n  shaping: 'Shaping…'\n};\n\nexport function ThinkingOrb({\n  state = 'working',\n  size = 64,\n  theme = 'auto',\n  speed = 1,\n  paused = false,\n  color,\n  dots = 1,\n  dotSize = 1,\n  opts: optsOverride,\n  frame: customFrame,\n  gravity,\n  style,\n  'aria-label': ariaLabel,\n  ...rest\n}: ThinkingOrbProps) {\n  const ref = useRef<HTMLCanvasElement | null>(null);\n  const optsKey = optsOverride ? JSON.stringify(optsOverride) : '';\n  const dark = useResolvedDark(theme, ref);\n\n  // Gravity attaches the canvas to the document-level tracker; compared by\n  // content so an inline options literal does not re-attach every render.\n  const gravityKey = gravity ? JSON.stringify(gravity) : '';\n  useEffect(() => {\n    const canvas = ref.current;\n    if (!canvas || !gravity) return;\n    return attachGravity(canvas, gravity === true ? true : gravity);\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [gravityKey]);\n  const reduced = useReducedMotion();\n\n  useEffect(() => {\n    const canvas = ref.current;\n    if (!canvas) return;\n    const dpr = Math.min(2, (typeof devicePixelRatio !== 'undefined' && devicePixelRatio) || 1);\n    canvas.width = Math.round(size * dpr);\n    canvas.height = Math.round(size * dpr);\n    const ctx = canvas.getContext('2d');\n    if (!ctx) return;\n\n    const { mode, speed: baseSpeed, opts: presetOpts } = resolvePreset(state, size);\n    // `dots` rescales every count knob of the resolved preset with the same\n    // sqrt-paired scaler the presets themselves use, so density changes keep\n    // the mode's balance. resolvePreset caches — never mutate its result.\n    let opts = dots !== 1 ? scaleCounts(presetOpts, Math.max(0.1, dots)) : presetOpts;\n    if (dotSize !== 1) opts = scaleRadii(opts, Math.max(0.1, dotSize));\n    // raw overrides land last, over everything the preset and multipliers set\n    if (optsOverride) opts = { ...opts, ...optsOverride };\n    const frameFn = customFrame ?? MODE_FRAMES[mode];\n    const tint = parseTint(color);\n    const effSpeed = baseSpeed * speed;\n\n    const frame = (tSec: number) => {\n      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n      ctx.clearRect(0, 0, size, size);\n      paintFrame(ctx, frameFn(size, tSec, opts), dark, tint);\n    };\n\n    // reduced motion → one static, deterministic frame\n    if (reduced) {\n      frame(0.6);\n      return;\n    }\n\n    let raf = 0;\n    let running = false;\n    const loop = () => {\n      frame((performance.now() / 1000) * effSpeed);\n      if (running) raf = requestAnimationFrame(loop);\n    };\n    const start = () => {\n      if (running || paused) return;\n      running = true;\n      raf = requestAnimationFrame(loop);\n    };\n    const stop = () => {\n      running = false;\n      cancelAnimationFrame(raf);\n    };\n\n    // draw at least one frame even when paused/offscreen\n    frame((performance.now() / 1000) * effSpeed);\n\n    // pause offscreen + on hidden tabs — free when not visible\n    let visible = true;\n    const io =\n      typeof IntersectionObserver !== 'undefined'\n        ? new IntersectionObserver(([entry]) => {\n            visible = entry.isIntersecting;\n            if (visible && document.visibilityState !== 'hidden') start();\n            else stop();\n          })\n        : null;\n    io?.observe(canvas);\n    const onVis = () => {\n      if (document.visibilityState === 'hidden') stop();\n      else if (visible) start();\n    };\n    document.addEventListener('visibilitychange', onVis);\n    if (!io) start();\n\n    return () => {\n      stop();\n      io?.disconnect();\n      document.removeEventListener('visibilitychange', onVis);\n    };\n    // the override object is compared by content, so an inline literal\n    // does not restart the loop every render\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [state, size, dark, speed, paused, reduced, color, dots, dotSize, optsKey, customFrame]);\n\n  return (\n    <canvas\n      ref={ref}\n      role=\"img\"\n      aria-label={ariaLabel ?? LABELS[state]}\n      style={{ width: size, height: size, display: 'block', ...style }}\n      {...rest}\n    />\n  );\n}\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/core.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/core.ts",
          "type": "registry:component",
          "content": "// Shared primitives for the dotted 3D thought-orbs. Ported from inkform\n// (PlotterLab's HalftoneSphere lineage): honestly 3D — rotated,\n// depth-shaded, z-sorted. Depth is carried by dot size and ink weight\n// alone. Plain 2D canvas fills only: no ctx.filter, no SVG filters, so\n// every mode renders identically in Chrome, Safari and Firefox.\n\nexport interface Dot {\n  x: number;\n  y: number;\n  z: number;\n  r: number;\n  /** Ink value: 0 = darkest ink on paper. Mirrored on dark themes. */\n  white: number;\n  a?: number;\n}\n\n/** A stroked edge between two projected points (the `connecting` web). */\nexport interface Line {\n  x1: number;\n  y1: number;\n  x2: number;\n  y2: number;\n  /** Ink value, same convention as `Dot.white`. */\n  white: number;\n  a?: number;\n  w: number;\n}\n\n/**\n * One rendered instant: a complete, final set of draw instructions.\n * `dots` is already z-sorted into draw order and radius-clamped; `lines`\n * are drawn first. Nothing here needs further interpretation, which is what\n * makes a frame portable to any 2D renderer.\n */\nexport interface OrbFrame {\n  dots: Dot[];\n  lines: Line[];\n}\n\nexport type Projector = (x: number, y: number, z: number) => [number, number, number];\n\nexport function lerp(a: number, b: number, f: number): number {\n  return a + (b - a) * f;\n}\n\nexport function frac(x: number): number {\n  return x - Math.floor(x);\n}\n\n/** Value noise on a 2D lattice — smooth, deterministic, cheap. */\nexport function vnoise(x: number, y: number): number {\n  const xi = Math.floor(x);\n  const yi = Math.floor(y);\n  let fx = x - xi;\n  let fy = y - yi;\n  fx = fx * fx * (3 - 2 * fx);\n  fy = fy * fy * (3 - 2 * fy);\n  const a = hashD(xi, yi);\n  const b = hashD(xi + 1, yi);\n  const c = hashD(xi, yi + 1);\n  const d = hashD(xi + 1, yi + 1);\n  return a + (b - a) * fx + (c - a) * fy + (a - b - c + d) * fx * fy;\n}\n\n/** Deterministic hash in [0, 1). */\nexport function hashD(a: number, b: number): number {\n  const h = Math.sin(a * 12.9898 + b * 78.233) * 43758.5453;\n  return h - Math.floor(h);\n}\n\n/** Stable directions on a unit sphere (Fibonacci lattice). */\nexport function fibDir(i: number, n: number): [number, number, number] {\n  const golden = Math.PI * (3 - Math.sqrt(5));\n  const y = 1 - (2 * (i + 0.5)) / n;\n  const rad = Math.sqrt(1 - y * y);\n  const a = i * golden;\n  return [rad * Math.cos(a), y, rad * Math.sin(a)];\n}\n\n/** Shortest signed angular distance, wrapped to (-π, π]. */\nexport function angleDelta(a: number, b: number): number {\n  return Math.atan2(Math.sin(a - b), Math.cos(a - b));\n}\n\n/** Shared spin + tilt + orthographic projection. */\nexport function makeProj(yaw: number, tilt: number, cx: number, cy: number, scale: number): Projector {\n  const st = Math.sin(tilt);\n  const ct = Math.cos(tilt);\n  const sy = Math.sin(yaw);\n  const cyw = Math.cos(yaw);\n  return (x, y, z) => {\n    const x1 = x * cyw + z * sy;\n    const z1 = -x * sy + z * cyw;\n    const y1 = y * ct - z1 * st;\n    const z2 = y * st + z1 * ct;\n    return [cx + x1 * scale, cy - y1 * scale, z2];\n  };\n}\n\n/** Optional ink tint, resolved to an RGB triple (0–255 each). */\nexport interface OrbTint {\n  r: number;\n  g: number;\n  b: number;\n}\n\n/**\n * Map one ink value to a CSS color. Grayscale by default; with a tint the\n * ink ramp is preserved as a ramp on the tint itself — on dark substrates\n * the tint fades toward black with depth (as the grays do), on light ones\n * it fades toward white — so depth reads identically in color.\n */\nfunction inkColor(w: number, alpha: number, dark: boolean, tint?: OrbTint): string {\n  if (!tint) {\n    const g = Math.round((dark ? 1 - w : w) * 255);\n    return `rgba(${g},${g},${g},${alpha})`;\n  }\n  const ramp = (c: number) => Math.round(dark ? c * (1 - w) : c + (255 - c) * w);\n  return `rgba(${ramp(tint.r)},${ramp(tint.g)},${ramp(tint.b)},${alpha})`;\n}\n\n/**\n * Painter: z-sort far→near, matte grayscale dots. On dark substrates the\n * ink value is mirrored (1 - white) so near dots read bright — the same\n * depth language on an inverted substrate.\n */\nexport function paint(\n  ctx: CanvasRenderingContext2D,\n  dots: Dot[],\n  dark: boolean,\n  rMin = 0.3,\n  tint?: OrbTint\n): void {\n  for (const d of dots) {\n    const alpha = d.a ?? 1;\n    const w = Math.min(1, Math.max(0, d.white));\n    ctx.fillStyle = inkColor(w, alpha, dark, tint);\n    ctx.beginPath();\n    ctx.arc(d.x, d.y, d.r, 0, Math.PI * 2);\n    ctx.fill();\n  }\n}\n\n/** Stroke pass for edge-based modes. Runs before `paint` so nodes sit on top. */\nexport function paintLines(\n  ctx: CanvasRenderingContext2D,\n  lines: Line[],\n  dark: boolean,\n  tint?: OrbTint\n): void {\n  for (const l of lines) {\n    const alpha = l.a ?? 1;\n    const w = Math.min(1, Math.max(0, l.white));\n    ctx.strokeStyle = inkColor(w, alpha, dark, tint);\n    ctx.lineWidth = l.w;\n    ctx.beginPath();\n    ctx.moveTo(l.x1, l.y1);\n    ctx.lineTo(l.x2, l.y2);\n    ctx.stroke();\n  }\n}\n\n/**\n * Turn raw mode output into a finished frame: drop invisible marks, clamp\n * radii to the mode's floor, and z-sort far→near into draw order.\n *\n * This runs in the GEOMETRY step, not the painter, so a frame is a complete\n * set of draw instructions: every value is final and the array order is the\n * order to draw in. That is what lets the RN and SwiftUI ports share this\n * output verbatim — a port draws the list, it never re-derives anything —\n * and what lets the golden-vector tests compare numbers instead of pixels.\n */\nexport function finalizeFrame(dots: Dot[], lines: Line[], rMin = 0.3): OrbFrame {\n  const visible: Dot[] = [];\n  for (const d of dots) {\n    if ((d.a ?? 1) < 0.02) continue;\n    d.r = Math.max(rMin, d.r);\n    visible.push(d);\n  }\n  visible.sort((a, b) => a.z - b.z);\n  return { dots: visible, lines: lines.filter((l) => (l.a ?? 1) >= 0.02) };\n}\n\n/** Paint a finished frame. Lines first, so nodes sit on top of their edges. */\nexport function paintFrame(\n  ctx: CanvasRenderingContext2D,\n  frame: OrbFrame,\n  dark: boolean,\n  tint?: OrbTint\n): void {\n  if (frame.lines.length) paintLines(ctx, frame.lines, dark, tint);\n  paint(ctx, frame.dots, dark, 0.3, tint);\n}\n\n/**\n * Dot radii were tuned for a 300pt frame; sub-linear scaling keeps small\n * spinners legible. Lower pow = radii shrink less with size.\n */\nexport function radiusScale(size: number, pow: number): number {\n  return (size / 300) ** pow;\n}\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/profiles.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/profiles.ts",
          "type": "registry:component",
          "content": "// Density profiles + the multiplier machinery that scales them. The base\n// rows are inkform's `fine` profiles; each shipped preset (state × size)\n// applies count / radius multipliers on top, resolved once per mount.\n\nexport interface ModeOpts {\n  [key: string]: number | undefined;\n}\n\n// 2-D lattices (rings × dots-per-ring) come in pairs — each side takes\n// √scale so the TOTAL dot count scales by `scale`; flat lists scale\n// linearly. `iconD` sets the morph outline's sampling density.\nconst COUNT_PAIRS: ReadonlyArray<readonly [string, string]> = [\n  ['latRings', 'lonDensity'],\n  ['rings', 'lonDensity'],\n  ['lanes', 'segs']\n];\nconst COUNT_KEYS = ['orbitN', 'ghostN', 'nodeN', 'strandN', 'signals'] as const;\nconst ICON_DENSITY_KEYS = ['iconD'] as const;\n\n// Every key that sets a dot's rendered radius — scaling all of them keeps\n// a dot's near/far falloff intact while shrinking or growing the mark.\nconst RADIUS_KEYS = [\n  'rBase',\n  'rDepth',\n  'rActive',\n  'rDot',\n  'ghostR',\n  'partR',\n  'partRDepth',\n  'nodeR',\n  'nodeRDepth'\n] as const;\n\nexport function scaleCounts(opts: ModeOpts, scale: number): ModeOpts {\n  const out: ModeOpts = { ...opts };\n  const done = new Set<string>();\n  const rt = Math.sqrt(scale);\n  for (const [a, b] of COUNT_PAIRS) {\n    const va = out[a];\n    const vb = out[b];\n    if (va != null && vb != null && !done.has(a) && !done.has(b)) {\n      out[a] = Math.max(2, Math.round(va * rt));\n      out[b] = Math.max(2, Math.round(vb * rt));\n      done.add(a);\n      done.add(b);\n    }\n  }\n  for (const k of COUNT_KEYS) {\n    const v = out[k];\n    // 0 means the mode opted out of that layer entirely (ring has no ghost\n    // sphere) — scaling must not resurrect it as a single stray dot\n    if (v != null && v !== 0 && !done.has(k)) out[k] = Math.max(1, Math.round(v * scale));\n  }\n  for (const k of ICON_DENSITY_KEYS) {\n    const v = out[k];\n    if (v != null) out[k] = Math.max(0.02, v * scale);\n  }\n  return out;\n}\n\nexport function scaleRadii(opts: ModeOpts, scale: number): ModeOpts {\n  const out: ModeOpts = { ...opts };\n  for (const k of RADIUS_KEYS) {\n    const v = out[k];\n    if (v != null) out[k] = v * scale;\n  }\n  // remember the multiplier itself — spacing-derived radii (the morph\n  // outline) use it, since they aren't based on any single radius key\n  out.rSizeMul = (out.rSizeMul ?? 1) * scale;\n  return out;\n}\n\n/**\n * How many dots a resolved profile draws.\n *\n * There is no single count knob: a mode either lays its dots out on a grid\n * (a lat/lon sphere, a lane/segment ribbon) or carries standalone counts,\n * and several modes do both. This sums exactly the knobs `scaleCounts`\n * treats as counts — grid pairs as their product, the rest as themselves —\n * so the number tracks what `dots` actually scales. Density-driven layers\n * have no fixed count and are left out.\n */\nexport function countDots(opts: ModeOpts): number {\n  let total = 0;\n  const done = new Set<string>();\n  for (const [a, b] of COUNT_PAIRS) {\n    const va = opts[a];\n    const vb = opts[b];\n    if (va != null && vb != null && !done.has(a) && !done.has(b)) {\n      total += va * vb;\n      done.add(a);\n      done.add(b);\n    }\n  }\n  for (const k of COUNT_KEYS) {\n    const v = opts[k];\n    if (v != null && v !== 0 && !done.has(k)) total += v;\n  }\n  return Math.round(total);\n}\n\n/** Base (fine) profiles per mode, before preset multipliers. */\nexport const BASE_PROFILES: Record<string, ModeOpts> = {\n  globe: {\n    latRings: 17,\n    lonDensity: 44,\n    rBase: 0.6,\n    rDepth: 1.7,\n    rBoost: 1.0,\n    inkFar: 0.62,\n    inkSpan: 0.54,\n    rsPow: 0.6,\n    rMin: 0.3\n  },\n  orbits: {\n    orbitN: 12,\n    ghostN: 40,\n    ghostR: 0.9,\n    ghostA: 0.5,\n    particles: 3,\n    partR: 1.2,\n    partRDepth: 1.6,\n    rsPow: 0.6,\n    rMin: 0.3\n  },\n  rubik: {\n    latRings: 15,\n    lonDensity: 40,\n    moveCount: 14,\n    rBase: 0.6,\n    rDepth: 1.7,\n    rActive: 0.3,\n    inkFar: 0.62,\n    inkSpan: 0.54,\n    rsPow: 0.6,\n    rMin: 0.3\n  },\n  wave: {\n    rings: 15,\n    lonDensity: 40,\n    rBase: 0.6,\n    rDepth: 1.7,\n    rsPow: 0.6,\n    rMin: 0.3\n  },\n  web: {\n    nodeN: 30,\n    thr: 0.72,\n    signals: 5,\n    nodeR: 1.4,\n    nodeRDepth: 1.8,\n    lineW: 0.8,\n    rsPow: 0.6,\n    rMin: 0.3\n  },\n  braid: {\n    strandN: 52,\n    turns: 3.0,\n    ghostN: 150,\n    rBase: 1.2,\n    rDepth: 1.8,\n    rsPow: 0.6,\n    rMin: 0.3\n  },\n  ribbon: {\n    lanes: 5,\n    segs: 88,\n    ghostN: 150,\n    rBase: 1.1,\n    rDepth: 1.7,\n    rsPow: 0.6,\n    rMin: 0.3\n  },\n  // ring shares ribbon's painter; faceOn cancels the camera tilt and moves\n  // the undulation onto the radius, and there is no ghost sphere behind it\n  ring: {\n    lanes: 5,\n    segs: 88,\n    ghostN: 0,\n    faceOn: 1,\n    rBase: 1.1,\n    rDepth: 1.7,\n    rsPow: 0.6,\n    rMin: 0.3\n  },\n  morph: {\n    rDot: 0.021,\n    iconD: 1,\n    rMin: 0.25\n  }\n};\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/registry.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/registry.ts",
          "type": "registry:component",
          "content": "// Mode key → geometry builder. Kept separate from the presets so tree\n// shaking can in principle drop unused modes in custom builds.\n\nimport type { ModeKey } from '../presets';\nimport type { ModeDraw, ModeFrame } from './types';\nimport { paintFrame } from './core';\nimport { frameBraid } from './braid';\nimport { frameGlobe, frameRubik, frameWave } from './lattice';\nimport { frameMorph } from './morph';\nimport { frameOrbits } from './orbits';\nimport { frameRibbon } from './ribbon';\nimport { frameWeb } from './web';\n\n/**\n * The portable surface: pure geometry, no canvas. The React Native port\n * imports exactly these functions, so its output is identical to the web's\n * by construction rather than by re-implementation.\n */\nexport const MODE_FRAMES: Record<ModeKey, ModeFrame> = {\n  orbits: frameOrbits,\n  globe: frameGlobe,\n  rubik: frameRubik,\n  wave: frameWave,\n  web: frameWeb,\n  braid: frameBraid,\n  ribbon: frameRibbon,\n  // ring shares ribbon's geometry — the `faceOn` profile flag switches it\n  ring: frameRibbon,\n  morph: frameMorph\n};\n\n/** Canvas painters, derived from the geometry. The 2D-canvas binding. */\nexport const MODE_DRAWS: Record<ModeKey, ModeDraw> = Object.fromEntries(\n  Object.entries(MODE_FRAMES).map(([key, frame]) => [\n    key,\n    ((ctx, size, t, dark, opts) => paintFrame(ctx, frame(size, t, opts), dark)) as ModeDraw\n  ])\n) as Record<ModeKey, ModeDraw>;\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/presets.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/presets.ts",
          "type": "registry:component",
          "content": "// The shipped tunings: nine states × two sizes, baked from the inkform\n// mini-page tuning session. `count`/`size` are multipliers over the base\n// fine profiles; `speed` multiplies the shared clock. Resolved once per\n// (state, size) pair and cached — the render loop sees plain numbers.\n\nimport type { ModeOpts } from './engine/profiles';\nimport { BASE_PROFILES, scaleCounts, scaleRadii } from './engine/profiles';\nimport type { OrbSize, OrbState } from './types';\n\nexport type ModeKey =\n  | 'orbits'\n  | 'globe'\n  | 'rubik'\n  | 'wave'\n  | 'web'\n  | 'braid'\n  | 'ribbon'\n  | 'ring'\n  | 'morph';\n\nexport const STATE_TO_MODE: Record<OrbState, ModeKey> = {\n  working: 'orbits',\n  searching: 'globe',\n  solving: 'rubik',\n  listening: 'wave',\n  connecting: 'web',\n  weaving: 'braid',\n  composing: 'ribbon',\n  breathing: 'ring',\n  shaping: 'morph'\n};\n\nexport interface Preset {\n  speed: number;\n  count: number;\n  size: number;\n  /** Extra mode opts merged verbatim after scaling. */\n  extra?: ModeOpts;\n}\n\n/** Exported so `scripts/extract-spec.ts` can emit them for the native ports. */\nexport const PRESETS: Record<ModeKey, Record<OrbSize, Preset>> = {\n  orbits: {\n    64: { speed: 1.885, count: 1, size: 1 },\n    32: { speed: 2.9072, count: 0.4251, size: 1.6849 },\n    20: { speed: 3.9, count: 0.238, size: 2.4 }\n  },\n  globe: {\n    64: { speed: 2.015, count: 0.42, size: 1.15, extra: { scanMul: 4.08, dimBase: 0.45 } },\n    32: { speed: 2.3803, count: 0.1839, size: 1.4769, extra: { scanMul: 4.2301, dimBase: 0.45 } },\n    20: { speed: 2.665, count: 0.105, size: 1.75, extra: { scanMul: 4.335, dimBase: 0.45 } }\n  },\n  rubik: {\n    64: { speed: 1.82, count: 0.35, size: 1.05 },\n    32: { speed: 1.8964, count: 0.1537, size: 1.4951 },\n    20: { speed: 1.95, count: 0.088, size: 1.9 }\n  },\n  wave: {\n    64: { speed: 4.388, count: 0.341, size: 1 },\n    32: { speed: 4.1512, count: 0.169, size: 1.3232 },\n    20: { speed: 3.998, count: 0.105, size: 1.6 }\n  },\n  web: {\n    64: { speed: 3.315, count: 1.35, size: 0.95 },\n    32: { speed: 5.0104, count: 0.4942, size: 1.2571 },\n    20: { speed: 6.63, count: 0.25, size: 1.52 }\n  },\n  braid: {\n    64: { speed: 1.625, count: 0.5, size: 1 },\n    32: { speed: 2.2234, count: 0.2056, size: 1.2011 },\n    20: { speed: 2.75, count: 0.1125, size: 1.36 }\n  },\n  ribbon: {\n    64: { speed: 2.34, count: 0.25, size: 0.85, extra: { spin: 0, bandMul: 3.9, wobMul: 1 } },\n    32: { speed: 2.7776, count: 0.0969, size: 0.9766, extra: { spin: 0, bandMul: 4.49, wobMul: 1 } },\n    20: { speed: 3.12, count: 0.051, size: 1.073, extra: { spin: 0, bandMul: 4.94, wobMul: 1 } }\n  },\n  ring: {\n    64: { speed: 3.24, count: 0.25, size: 0.956, extra: { spin: 0, bandMul: 3.627, wobMul: 0.368 } },\n    32: { speed: 3.5517, count: 0.0678, size: 1.31, extra: { spin: 0, bandMul: 3.8265, wobMul: 0.4751 } },\n    20: { speed: 3.78, count: 0.028, size: 1.622, extra: { spin: 0, bandMul: 3.968, wobMul: 0.565 } }\n  },\n  morph: {\n    64: { speed: 2.405, count: 0.702, size: 0.395, extra: { spread: 1.45 } },\n    32: { speed: 2.2057, count: 0.5937, size: 0.6916, extra: { spread: 1.45 } },\n    20: { speed: 2.08, count: 0.53, size: 1.011, extra: { spread: 1.45 } }\n  }\n};\n\nexport interface Resolved {\n  mode: ModeKey;\n  speed: number;\n  opts: ModeOpts;\n}\n\nconst cache = new Map<string, Resolved>();\n\n/** Resolve a (state, size) pair to its mode + fully-scaled draw options. */\nexport function resolvePreset(state: OrbState, size: OrbSize): Resolved {\n  const key = `${state}-${size}`;\n  const hit = cache.get(key);\n  if (hit) return hit;\n\n  const mode = STATE_TO_MODE[state];\n  const preset = PRESETS[mode][size];\n  let opts: ModeOpts = { ...BASE_PROFILES[mode] };\n  if (preset.count !== 1) opts = scaleCounts(opts, preset.count);\n  if (preset.size !== 1) opts = scaleRadii(opts, preset.size);\n  if (preset.extra) opts = { ...opts, ...preset.extra };\n\n  const resolved: Resolved = { mode, speed: preset.speed, opts };\n  cache.set(key, resolved);\n  return resolved;\n}\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/types.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/types.ts",
          "type": "registry:component",
          "content": "import type { CSSProperties, CanvasHTMLAttributes } from 'react';\nimport type { ModeOpts } from './engine/profiles';\nimport type { ModeFrame } from './engine/types';\nimport type { GravityOptions } from './gravity';\n\n/**\n * The nine shipped states — each a hand-tuned animation:\n * - `working`    — particles on tilted orbits\n * - `searching`  — a scan meridian sweeps a dotted globe\n * - `solving`    — bands scramble in quarter turns, then click back\n * - `listening`  — a waveform rolls through latitude rings\n * - `connecting` — a constellation wires itself, packets running the edges\n * - `weaving`    — three strands plait around the sphere\n * - `composing`  — an undulating multi-band sash\n * - `breathing`  — a face-on ring slowly morphing\n * - `shaping`    — a dotted outline morphs circle → triangle → square\n */\nexport type OrbState =\n  | 'working'\n  | 'searching'\n  | 'solving'\n  | 'listening'\n  | 'connecting'\n  | 'weaving'\n  | 'composing'\n  | 'breathing'\n  | 'shaping';\n\n/**\n * Rendered size in CSS pixels. 64 (chat-avatar scale) and 20 (inline-text\n * scale) are hand-tuned designs, not a scale factor — each carries its own\n * dot count, dot size and speed. 32 (compact avatar scale) sits between\n * them and is interpolated from the two, in log space because those knobs\n * are ratios; it reads correctly but has not had a tuning pass of its own.\n */\nexport type OrbSize = 64 | 32 | 20;\n\n/**\n * Theme mode.\n *\n * - `auto` (default) resolves in three layers, live-updating on change:\n *   1. a `data-theme=\"dark|light\"` attribute or `dark`/`light` class on\n *      any ancestor (the Tailwind / shadcn convention), watched via\n *      `MutationObserver`;\n *   2. otherwise `matchMedia('(prefers-color-scheme: dark)')`,\n *      subscribed for live OS/browser theme switches;\n *   3. during SSR (no DOM) the first client render resolves the theme\n *      before anything is painted — the canvas is client-only.\n * - `dark` / `light` pin the palette regardless of context.\n *\n * Dark renders light ink on the transparent canvas (for dark\n * backgrounds); light renders dark ink (for light backgrounds).\n */\nexport type OrbTheme = 'auto' | 'dark' | 'light';\n\n/** Props for the ThinkingOrb React component. */\nexport interface ThinkingOrbProps extends Omit<CanvasHTMLAttributes<HTMLCanvasElement>, 'style'> {\n  /** Which animation to show. @default 'working' */\n  state?: OrbState;\n\n  /** Tuned size preset — 64 or 20 CSS px. @default 64 */\n  size?: OrbSize;\n\n  /** Theme mode; `auto` detects from the host project. @default 'auto' */\n  theme?: OrbTheme;\n\n  /**\n   * Animation speed multiplier on top of the preset's baked speed.\n   * @default 1\n   */\n  speed?: number;\n\n  /** Freeze the animation on the current frame. @default false */\n  paused?: boolean;\n\n  /**\n   * Optional ink tint — any `#rgb`, `#rrggbb` or `rgb()` color. The orb's\n   * depth-shading ramp is preserved on the tint (fading toward black on\n   * dark substrates, toward white on light ones), so colored orbs read\n   * with the same 3D language as the grayscale default. Omit for the\n   * stock grayscale ink.\n   */\n  color?: string;\n\n  /**\n   * Density multiplier for the mode's dot/strand/node counts, applied with\n   * the same paired-count scaler the size presets use so the mode keeps\n   * its balance. `1` (default) is the tuned look; `0.5` halves density,\n   * `2` doubles it. Clamped to a 0.1 floor.\n   */\n  dots?: number;\n\n  /**\n   * Radius multiplier for every dot, applied with the same scaler the size\n   * presets use so near/far falloff keeps its proportion. `1` (default) is\n   * the tuned mark; `0.7` reads finer, `1.5` bolder.\n   */\n  dotSize?: number;\n\n  /**\n   * Advanced: raw draw options merged over the resolved preset, last. These\n   * are the engine's own knobs, so they reach past the tuned surface — the\n   * orbit paths' `ghostA` and `particles` (working), the globe's `scanMul`\n   * and `dimBase` (searching), the constellation's `thr`, `signals`, `lineW`\n   * and `spread` (connecting), the plait's `turns` (weaving), the sash's\n   * `wobMul`, `bandMul` and `spin` (composing, breathing), and the outline's\n   * `spread` and `shape` (shaping — `shape` 0 / 1 / 2 holds the circle,\n   * triangle or square instead of cycling). Unknown keys are ignored; a key\n   * the current state does not read does nothing.\n   */\n  opts?: ModeOpts;\n\n  /**\n   * Escape hatch below `opts`: replace the state's geometry outright. The\n   * function gets `(size, t, opts)` and returns the frame to paint — the\n   * same contract every built-in mode implements (see `MODE_FRAMES` and the\n   * helpers exported alongside it). The painter, theme, tint, pause and\n   * offscreen handling all stay the library's.\n   */\n  frame?: ModeFrame;\n\n  /**\n   * Gravity: the orb pulls at the pointer. As the pointer nears, a raster\n   * of the platform's cursor is drawn in its place with its body warped\n   * toward the orb — the tip stays put, nothing rotates or scales. Needs the\n   * platform's real pointer raster (`gravity.sprite`, or\n   * `setGravitySprite`) or it stays off; off automatically under reduced\n   * motion, forced colours, coarse pointers, zoom, and over anything but\n   * the plain arrow. `true` takes the defaults. See gravity.ts.\n   */\n  gravity?: boolean | GravityOptions;\n\n  style?: CSSProperties;\n}\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/types.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/types.ts",
          "type": "registry:component",
          "content": "// Engine-level contracts shared by every mode implementation.\n\nimport type { ModeOpts } from './profiles';\n\nexport type { Dot, Line, OrbFrame } from './core';\n\nimport type { OrbFrame } from './core';\n\n/**\n * Geometry for one instant: pure math over (size, t, opts), no rendering\n * surface and no theme — `dark` only affects ink at paint time.\n *\n * Deliberately closure-free and `Math`-only so the same function can run\n * inside a Reanimated worklet on the React Native UI thread, and so its\n * output can be compared numerically against the Swift port.\n */\nexport type ModeFrame = (size: number, t: number, opts: ModeOpts) => OrbFrame;\n\n/** One frame painter: draws a mode into a 2D context at CSS-px `size`. */\nexport type ModeDraw = (\n  ctx: CanvasRenderingContext2D,\n  size: number,\n  t: number,\n  dark: boolean,\n  opts: ModeOpts\n) => void;\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/gravity.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/gravity.ts",
          "type": "registry:component",
          "content": "/**\n * Gravity — the orb pulls the pointer in.\n *\n * An optional effect: as the pointer nears an orb, its body bends toward\n * it and the side facing it streaks toward the orb's centre, like\n * something caught in a well. The pointer itself does not move — its tip\n * stays exactly where the OS has it, and it is never rotated or scaled as\n * a whole. A page cannot move or reshape the OS cursor, so the\n * trick is the one cursorjoy (and metal-fx v2's cursor light) uses: while\n * the pointer is within reach and the element under it shows the plain\n * arrow, that element gets `cursor: none` and a raster of the platform's\n * pointer is drawn in its place, warped by the well. The raster has to be the platform's real pointer or the swap\n * shows; consumers supply it (`setGravitySprite`, or `gravity.sprite`).\n * Without one the effect stays off. Over buttons and text (hand, I-beam)\n * the OS cursor is left alone.\n *\n * Runs only on `(pointer: fine)` devices. Tracking starts when the first\n * orb attaches and stops with the last; the per-frame loop runs only while\n * the pointer is within reach of some orb (plus the fade-out).\n *\n * Fail-safes for the cursor swap (the only part that can hurt someone):\n *   • off under `prefers-reduced-motion`, `forced-colors`, coarse/no-hover\n *     pointers, and pen/touch input;\n *   • off while the page is zoomed (DPR differs from when the sprite was\n *     registered, or pinch-zoomed) — the sprite would scale, the OS cursor\n *     wouldn't;\n *   • the OS cursor is hidden by one class on <html> for exactly as long\n *     as the pointer is in a well, lifted on every leave/blur/hide/keydown,\n *     over anything with a cursor of its own, and on any exception (which\n *     also disables the effect for the session);\n *   • a frame-time watchdog disables it if it ever becomes expensive;\n *   • it never runs where the pointer is anything but the plain arrow.\n * Not detectable: Accessibility › Pointer size/colour on macOS. A user with\n * an enlarged pointer sees it swap to the stock one — ship the sprite only\n * where that trade-off is acceptable, and give them a way to turn it off.\n */\n\n/** A raster of the platform's real pointer. `width`/`height` in CSS px,\n *  `hotX`/`hotY` the click point. */\nexport interface CursorSprite {\n  src: string;\n  width: number;\n  height: number;\n  hotX: number;\n  hotY: number;\n}\n\nexport interface GravityOptions {\n  /** How far outside the orb's edge the pull is felt, CSS px. */\n  reach?: number;\n  /** How far the pointer trails toward the orb on contact, CSS px. The\n   *  pointer itself never moves; this is the length of its tail. */\n  strength?: number;\n  /** How far the pointer's body is bent toward the orb on contact, CSS\n   *  px. The tip stays pinned; the rest of the body is drawn displaced\n   *  toward the orb, more the farther a pixel sits from the tip. */\n  deform?: number;\n  /** How the bend is spread along the body (1..4): 1 bends evenly from\n   *  the tip outward, higher keeps the tip end firm and bends the far end\n   *  hardest. */\n  taper?: number;\n  /** How late the pull builds (1..4): the proximity weight is raised to\n   *  this power, so higher keeps the pointer whole until it is close. */\n  curve?: number;\n  /** Width of the band across the pointer, CSS px, over which the tail\n   *  fades from the side facing the orb to the side away from it. Small\n   *  keeps the tail to the facing edge; large lets the whole body trail. */\n  falloff?: number;\n  /** Inertia (0..1): how much the deformation lags the pointer. 0 follows\n   *  instantly; higher reads heavier. */\n  smoothing?: number;\n  /** Handover (0..1): how slowly the pull swings from one orb to the next\n   *  when the nearest changes. 0 flips at once; higher glides. */\n  handover?: number;\n  /** Squash (0..3): extra bend and tail when the orb lies off the tip's\n   *  side, where the pull shortens the body instead of stretching it. A\n   *  shortening reads far weaker than a stretch of the same size, so this\n   *  evens the two — 0 leaves them equal in pixels, not in feel. */\n  squash?: number;\n  /** Progressive blur on the tail, CSS px: none at the pointer, this much\n   *  at the tail's far end, growing along it. 0 keeps the tail crisp. */\n  blur?: number;\n  /** Envelope on enter/leave, ms (~95% settled). */\n  fadeMs?: number;\n  /** The pointer raster, if not already set with `setGravitySprite`. */\n  sprite?: CursorSprite;\n}\n\nexport const GRAVITY_DEFAULTS: Readonly<Required<Omit<GravityOptions, 'sprite'>>> = Object.freeze({\n  reach: 160,\n  strength: 11,\n  deform: 19,\n  taper: 1.95,\n  curve: 2.8,\n  falloff: 24,\n  smoothing: 0.3,\n  handover: 0.6,\n  squash: 1.2,\n  blur: 1,\n  fadeMs: 180,\n});\n\n/** Live override for tuning: while set, every orb uses these values in\n *  place of its own. Dev panels write it; ship code leaves it null. */\nlet tuning: Partial<Required<Omit<GravityOptions, 'sprite'>>> | null = null;\nexport function setGravityConfig(patch: Partial<Required<Omit<GravityOptions, 'sprite'>>> | null): void {\n  tuning = patch ? { ...(tuning ?? {}), ...patch } : null;\n  kick();\n}\nexport function getGravityConfig(): Readonly<Required<Omit<GravityOptions, 'sprite'>>> {\n  return { ...GRAVITY_DEFAULTS, ...(tuning ?? {}) };\n}\n\ntype Resolved = Required<Omit<GravityOptions, 'sprite'>>;\n\ninterface Instance {\n  el: HTMLElement;\n  opts: Resolved;\n}\n\n// ─── Sprite ────────────────────────────────────────────────────────────\n\nlet sprite: CursorSprite | null = null;\nlet spriteImg: HTMLImageElement | null = null;\n/** The sprite's pixels at the current device scale — the bend samples\n *  these. Rebuilt when the sprite or the DPR changes. */\nlet src: ImageData | null = null;\nlet srcDpr = 0;\n/** DPR when the sprite was registered — a change means browser zoom or a\n *  different display, where the sprite no longer matches the OS cursor. */\nlet spriteDpr = 0;\n/** Sticky off-switch flipped by the fail-safes, with why. Cleared by a new\n *  sprite or `resetGravity()`. */\nlet disabled = false;\nlet disabledReason = '';\nlet slowFrames = 0;\n\n/** Clear the fail-safe off-switch (a dev panel's \"re-arm\"). */\nexport function resetGravity(): void {\n  disabled = false;\n  disabledReason = '';\n  slowFrames = 0;\n  kick();\n}\n/** Supply the pointer raster (or null to turn the effect off). Must match\n *  the OS pointer pixel-for-pixel, or the swap is visible. */\nexport function setGravitySprite(next: CursorSprite | null): void {\n  if (next === sprite) return;\n  sprite = next;\n  spriteImg = null;\n  src = null;\n  disabled = false;\n  slowFrames = 0;\n  spriteDpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n  hideCursor();\n  if (!next || typeof Image === 'undefined') return;\n  const img = new Image();\n  img.decoding = 'async';\n  img.onload = () => {\n    if (sprite !== next) return;\n    spriteImg = img;\n    kick();\n  };\n  img.src = next.src;\n}\n\n// ─── Tracking ──────────────────────────────────────────────────────────\n\nconst instances = new Set<Instance>();\nlet tracking = false;\nlet raf = 0;\nlet last = 0;\nlet px = Number.NaN, py = Number.NaN; // live pointer, NaN when gone\nlet lpx = 0, lpy = 0;                 // last known, for the fade-out\nlet uS = 0;                           // smoothed proximity weight\nlet near: Instance | null = null;\nlet pointerIsMouse = true;\n/** Set on keydown, cleared by the next pointer move — keeps the sprite off\n *  while someone types, as macOS hides the pointer then. */\nlet typing = false;\n\n/** Register an orb's element. Returns the detach function. */\nexport function attachGravity(el: HTMLElement, options: GravityOptions | true = true): () => void {\n  const o = options === true ? {} : options;\n  if (o.sprite) setGravitySprite(o.sprite);\n  const inst: Instance = {\n    el,\n    opts: {\n      reach: Math.max(1, o.reach ?? GRAVITY_DEFAULTS.reach),\n      strength: Math.max(0, Math.min(64, o.strength ?? GRAVITY_DEFAULTS.strength)),\n      deform: Math.max(0, Math.min(32, o.deform ?? GRAVITY_DEFAULTS.deform)),\n      taper: Math.max(1, Math.min(4, o.taper ?? GRAVITY_DEFAULTS.taper)),\n      curve: Math.max(1, Math.min(4, o.curve ?? GRAVITY_DEFAULTS.curve)),\n      falloff: Math.max(2, Math.min(200, o.falloff ?? GRAVITY_DEFAULTS.falloff)),\n      smoothing: clamp01(o.smoothing ?? GRAVITY_DEFAULTS.smoothing),\n      handover: clamp01(o.handover ?? GRAVITY_DEFAULTS.handover),\n      squash: Math.max(0, Math.min(3, o.squash ?? GRAVITY_DEFAULTS.squash)),\n      blur: Math.max(0, Math.min(24, o.blur ?? GRAVITY_DEFAULTS.blur)),\n      fadeMs: Math.max(1, o.fadeMs ?? GRAVITY_DEFAULTS.fadeMs),\n    },\n  };\n  instances.add(inst);\n  ensureTracking();\n  kick();\n  return () => {\n    instances.delete(inst);\n    if (near === inst) near = null;\n    /* Tear down only once nothing has registered by the end of the task.\n       React runs every cleanup before any new effect in a commit, so a\n       page swapping one set of orbs for another passes through zero here\n       — stopping at once took the cursor away and gave it back a frame\n       later, a flash on every such swap. */\n    if (instances.size === 0) queueMicrotask(() => { if (instances.size === 0) stopTracking(); });\n  };\n}\n\nconst clamp01 = (v: number): number => Math.max(0, Math.min(1, v));\n/** An orb's options with any live tuning laid over them. */\nconst effective = (inst: Instance): Resolved => (tuning ? { ...inst.opts, ...tuning } : inst.opts);\nconst mq = (q: string): boolean => typeof window.matchMedia === 'function' && window.matchMedia(q).matches;\n\n/** Why the cursor swap is not acceptable right now, or null when it is.\n *  Re-checked every frame; all of these can change while the page is open. */\nfunction swapBlockedBy(): string | null {\n  if (disabled) return disabledReason || 'disabled by a fail-safe';\n  if (!sprite) return 'no pointer sprite set';\n  if (!spriteImg) return 'pointer sprite still loading';\n  if (mq('(prefers-reduced-motion: reduce)')) return 'prefers-reduced-motion is on';\n  if (mq('(forced-colors: active)')) return 'forced colours are active';\n  if (!mq('(pointer: fine)') || !mq('(hover: hover)')) return 'no fine pointer';\n  if ((window.devicePixelRatio || 1) !== spriteDpr) return 'display scale changed since the sprite was set — reload';\n  const vv = window.visualViewport;\n  if (vv && Math.abs(vv.scale - 1) > 0.001) return 'page is zoomed';\n  return null;\n}\nfunction swapAllowed(): boolean {\n  return swapBlockedBy() === null;\n}\n\n/** For dev tooling: whether the effect can run, and why not if it cannot. */\nexport function getGravityStatus(): { orbs: number; tracking: boolean; active: boolean; blockedBy: string | null } {\n  const blocked = typeof window === 'undefined' ? 'no window' : swapBlockedBy();\n  return { orbs: instances.size, tracking, active: curShown, blockedBy: instances.size === 0 ? 'no orb has gravity on' : blocked };\n}\n\nfunction ensureTracking(): void {\n  if (tracking || instances.size === 0 || typeof document === 'undefined') return;\n  if (!mq('(pointer: fine)')) return;\n  tracking = true;\n  document.addEventListener('pointermove', onMove, { passive: true });\n  document.addEventListener('pointerleave', onLeave);\n  document.addEventListener('pointercancel', onLeave);\n  document.addEventListener('keydown', onKey, { passive: true });\n  document.addEventListener('visibilitychange', onLeave);\n  window.addEventListener('blur', onLeave);\n}\n\nfunction stopTracking(): void {\n  if (!tracking) return;\n  tracking = false;\n  document.removeEventListener('pointermove', onMove);\n  document.removeEventListener('pointerleave', onLeave);\n  document.removeEventListener('pointercancel', onLeave);\n  document.removeEventListener('keydown', onKey);\n  document.removeEventListener('visibilitychange', onLeave);\n  window.removeEventListener('blur', onLeave);\n  if (raf !== 0) { cancelAnimationFrame(raf); raf = 0; }\n  near = null;\n  uS = 0;\n  hideCursor();\n  if (curEl) { curEl.remove(); curEl = null; curCanvas = null; curCtx = null; }\n  if (hideStyle) { hideStyle.remove(); hideStyle = null; }\n}\n\nfunction onMove(e: PointerEvent): void {\n  pointerIsMouse = e.pointerType === 'mouse' || e.pointerType === '';\n  typing = false;\n  moveSeq++;\n  px = lpx = e.clientX;\n  py = lpy = e.clientY;\n  if (releasePending) {\n    // The OS pointer is back with this move; the sprite has done its part.\n    releasePending = false;\n    hideSprite();\n    amp = 0; bend = 0;\n    wcx = wcy = Number.NaN;\n  }\n  kick();\n}\n\nfunction onKey(): void {\n  typing = true;\n  hideCursor();\n}\n\nfunction onLeave(): void {\n  px = py = Number.NaN;\n  kick();\n}\n\nfunction kick(): void {\n  if (!tracking || raf !== 0) return;\n  last = performance.now();\n  raf = requestAnimationFrame(step);\n}\n\n// ─── Pointer sprite ────────────────────────────────────────────────────\n\nlet curEl: HTMLDivElement | null = null;\nlet curCanvas: HTMLCanvasElement | null = null;\nlet curCtx: CanvasRenderingContext2D | null = null;\nlet curShown = false;\n/* Hiding the OS pointer. One rule on <html> while the pointer is in a\n   well — `cursor: none !important` for everything beneath it — rather than\n   an inline style on whichever element is under the pointer. Per-element\n   hiding could not keep up: an element sliding under a still pointer is\n   painted with its own cursor before the next frame claims it, and every\n   crossing was a chance for the arrow to show for a frame. The rule is\n   lifted whenever the pointer is over something with a cursor of its own\n   (a button's hand, a field's I-beam), so those still show; what an\n   element's cursor would be without the rule is read once and cached. */\nconst HIDE_CLASS = 'thinking-orb-gravity-hide';\nlet hideStyle: HTMLStyleElement | null = null;\nlet hiding = false;\nconst naturalCursor = new WeakMap<Element, string>();\n/** Pointer moves seen, and the move on which hiding began. The OS pointer\n *  is still drawn until the move AFTER the rule lands, so the sprite waits\n *  for that move rather than sit beside it. */\nlet moveSeq = 0;\nlet claimMove = -1;\n/** Frames stepped, and the frame hiding began: the hold above is capped at\n *  two frames, so a pointer that stops right then gets its sprite anyway. */\nlet stepSeq = 0;\nlet claimStep = -1;\n\nfunction ensureCursor(): boolean {\n  if (curEl) return true;\n  const el = document.createElement('div');\n  el.className = 'thinking-orb-gravity-cursor';\n  el.setAttribute('aria-hidden', 'true');\n  el.style.cssText = 'position:fixed;left:0;top:0;pointer-events:none;z-index:2147483001;will-change:transform;display:none';\n  const c = document.createElement('canvas');\n  c.style.display = 'block';\n  el.appendChild(c);\n  document.body.appendChild(el);\n  const ctx = c.getContext('2d');\n  if (!ctx) { el.remove(); return false; }\n  curEl = el; curCanvas = c; curCtx = ctx;\n  /* A new canvas starts at the default 300×150. Forget the last sizing so\n     the next draw sizes it — otherwise an orb remounting after the last\n     one detached draws into an unsized canvas, which shows scaled. */\n  curDpr = 0;\n  return true;\n}\n\nfunction ensureHideStyle(): void {\n  if (hideStyle) return;\n  hideStyle = document.createElement('style');\n  hideStyle.textContent = `html.${HIDE_CLASS}, html.${HIDE_CLASS} * { cursor: none !important; }`;\n  document.head.appendChild(hideStyle);\n}\n\n/** The cursor an element shows on its own, with our rule out of the way. */\nfunction cursorOf(el: Element): string {\n  const cached = naturalCursor.get(el);\n  if (cached) return cached;\n  const root = document.documentElement;\n  const had = root.classList.contains(HIDE_CLASS);\n  if (had) root.classList.remove(HIDE_CLASS);\n  const cur = getComputedStyle(el).cursor;\n  if (had) root.classList.add(HIDE_CLASS);\n  naturalCursor.set(el, cur);\n  return cur;\n}\n\n/** Hide the OS cursor if the element under the pointer shows the plain\n *  arrow. Returns whether the sprite may show. */\nfunction claimCursor(x: number, y: number): boolean {\n  const target = document.elementFromPoint(x, y);\n  if (!target) return false;\n  const cur = cursorOf(target);\n  if (cur !== 'auto' && cur !== 'default') {\n    releaseCursor();\n    return false;\n  }\n  if (!hiding) {\n    ensureHideStyle();\n    document.documentElement.classList.add(HIDE_CLASS);\n    hiding = true;\n    claimMove = moveSeq;\n    claimStep = stepSeq;\n  }\n  return true;\n}\n\nfunction releaseCursor(): void {\n  if (!hiding) return;\n  document.documentElement.classList.remove(HIDE_CLASS);\n  hiding = false;\n  claimMove = -1;\n}\n\n/** Hide the sprite only; the OS cursor stays hidden. */\nfunction hideSprite(): void {\n  if (curEl && curShown) { curEl.style.display = 'none'; curShown = false; }\n}\n\n/** After the pointer leaves every orb's reach the swap is kept for this\n *  long, the sprite drawn plain at the pointer: crossing from one orb to\n *  the next then never gives the OS cursor back and takes it again, which\n *  is a blank frame each way. */\nconst LINGER_MS = 500;\n/** When the nearest orb was last in reach, performance.now(). */\nlet lastReach = Number.NEGATIVE_INFINITY;\n/** The swap was released with the sprite still drawn: the OS pointer is\n *  painted again on the next move, and the sprite goes on that move. */\nlet releasePending = false;\n\nfunction hideCursor(): void {\n  releasePending = false;\n  releaseCursor();\n  hideSprite();\n  amp = 0; bend = 0;\n  wcx = wcy = Number.NaN;\n}\n\nconst _c = { cx: 0, cy: 0, r: 0 }; // nearest orb: centre and radius, viewport px\n/** Smoothed pull and bend, CSS px — what `smoothing` eases. */\nlet amp = 0, bend = 0;\n/** The well's centre as drawn, viewport px. Eases toward the nearest orb\n *  rather than snapping to it, so handing over from one orb to the next\n *  swings the pull round smoothly instead of flipping it in a frame. */\nlet wcx = Number.NaN, wcy = Number.NaN;\n/** Room around the sprite for the tail and the bend, CSS px. */\nconst PAD = 48;\n/** Ghost passes per frame: more is smoother, all are cheap canvas draws. */\nconst PASSES = 10;\nlet refCanvas: HTMLCanvasElement | null = null;\nlet refCtx: CanvasRenderingContext2D | null = null;\n/** The bent pointer — the tail is stamped from this, so it trails from\n *  the body as drawn, not from the stock sprite. */\nlet bentCanvas: HTMLCanvasElement | null = null;\nlet bentCtx: CanvasRenderingContext2D | null = null;\nlet bentData: ImageData | null = null;\nlet curDpr = 0, curW = 0, curH = 0;\n\nfunction readSprite(dpr: number): ImageData | null {\n  if (!spriteImg || !sprite) return null;\n  const c = document.createElement('canvas');\n  c.width = Math.ceil(sprite.width * dpr);\n  c.height = Math.ceil(sprite.height * dpr);\n  const g = c.getContext('2d', { willReadFrequently: true });\n  if (!g) return null;\n  g.scale(dpr, dpr);\n  g.drawImage(spriteImg, 0, 0, sprite.width, sprite.height);\n  return g.getImageData(0, 0, c.width, c.height);\n}\n\n/**\n * Bend the pointer toward the orb into `bentData`: each output pixel\n * samples the sprite from a point displaced away from the orb, by an\n * amount that grows with the pixel's distance from the tip — so the tip\n * stays exactly where it is and the body leans in behind it. Nothing is\n * rotated or scaled as a whole.\n */\nfunction bendSprite(B: number, taper: number, P: number, hx: number, hy: number, cxo: number, cyo: number): void {\n  if (!src || !bentData) return;\n  const OW = bentData.width, OH = bentData.height;\n  const S = src, SW = S.width, SH = S.height, sd = S.data;\n  const od = bentData.data;\n  od.fill(0);\n  const L = Math.max(1, Math.hypot(SW, SH));\n  /* Only the sprite's box, swept along the pull by up to the bend, can\n     hold a pixel — the rest of the padded canvas stays clear. Keeps the\n     per-frame loop to a few thousand pixels rather than the whole pad. */\n  const tdx = cxo - hx, tdy = cyo - hy;\n  const tdl = Math.hypot(tdx, tdy) || 1;\n  const tux = tdx / tdl, tuy = tdy / tdl;\n  const x1 = Math.max(0, Math.floor(P + Math.min(0, B * tux) - 3)), x2 = Math.min(OW, Math.ceil(P + SW + Math.max(0, B * tux) + 3));\n  const y1 = Math.max(0, Math.floor(P + Math.min(0, B * tuy) - 3)), y2 = Math.min(OH, Math.ceil(P + SH + Math.max(0, B * tuy) + 3));\n  for (let y = y1; y < y2; y++) {\n    for (let x = x1; x < x2; x++) {\n      const i = (y * OW + x) * 4;\n      let sx = x - P, sy = y - P;\n      if (B > 0.01) {\n        /* Where this pixel comes from: the source q with q + m(q)·u = (x, y),\n           m being the bend at q — at the source, not here. Evaluated here,\n           a pixel off the orb's side of the tip is far from the tip, gets\n           the full bend, and reads that far back into the body: a detached\n           sliver of pointer floating off the tip. The equation is solved by\n           a damped fixed-point iteration (the plain one oscillates once the\n           bend's slope passes 1), and a pixel with no solution — nothing\n           lands there — stays empty. */\n        let qx = x, qy = y;\n        let m = 0, dx = 0, dy = 0, dl = 1;\n        for (let it = 0; it < 7; it++) {\n          const s = Math.hypot(qx - hx, qy - hy) / L;\n          m = B * Math.pow(Math.min(1, s), taper);\n          dx = cxo - qx; dy = cyo - qy;\n          dl = Math.hypot(dx, dy) || 1;\n          qx += (x - (m * dx) / dl - qx) * 0.5;\n          qy += (y - (m * dy) / dl - qy) * 0.5;\n        }\n        const ex = qx + (m * dx) / dl - x, ey = qy + (m * dy) / dl - y;\n        if (ex * ex + ey * ey > 2.25) { od[i] = od[i + 1] = od[i + 2] = od[i + 3] = 0; continue; }\n        sx = qx - P; sy = qy - P;\n      }\n      const x0 = Math.floor(sx), y0 = Math.floor(sy);\n      if (x0 < -1 || y0 < -1 || x0 >= SW || y0 >= SH) { od[i] = od[i + 1] = od[i + 2] = od[i + 3] = 0; continue; }\n      const fx = sx - x0, fy = sy - y0;\n      let r = 0, g = 0, b = 0, a = 0;\n      for (let k = 0; k < 4; k++) {\n        const xx = x0 + (k & 1), yy = y0 + (k >> 1);\n        if (xx < 0 || yy < 0 || xx >= SW || yy >= SH) continue;\n        const wgt = (k & 1 ? fx : 1 - fx) * (k >> 1 ? fy : 1 - fy);\n        const j = (yy * SW + xx) * 4;\n        const wa = wgt * sd[j + 3];\n        r += sd[j] * wa; g += sd[j + 1] * wa; b += sd[j + 2] * wa; a += wa;\n      }\n      if (a > 0) { od[i] = r / a; od[i + 1] = g / a; od[i + 2] = b / a; od[i + 3] = a; }\n      else { od[i] = od[i + 1] = od[i + 2] = od[i + 3] = 0; }\n    }\n  }\n}\n\n/**\n * Draw the pointer being pulled toward the orb. Two parts, both leaving\n * the pointer's position, size and orientation exactly the OS's:\n *   • the bend — the body leans toward the orb behind its pinned tip;\n *   • the tail — fading copies of that bent pointer, stamped along the\n *     line to the orb's centre and masked to the side of the pointer that\n *     faces the orb, so that side trails toward it wherever the orb is.\n *     (Masking by depth in the well would kill the tail whenever the orb\n *     is on the tip's side, since the tip is then the closest point.)\n * `w` is the smoothed proximity weight (0 far, 1 touching).\n */\nfunction drawCursor(inst: Instance, w: number, dt: number): void {\n  if (!curCtx || !curCanvas || !curEl || !sprite || !spriteImg) return;\n  const sp = sprite;\n  const o = effective(inst);\n  const dpr = Math.min(3, window.devicePixelRatio || 1);\n  if (!refCanvas) { refCanvas = document.createElement('canvas'); refCtx = refCanvas.getContext('2d'); }\n  if (!bentCanvas) { bentCanvas = document.createElement('canvas'); bentCtx = bentCanvas.getContext('2d'); }\n  if (!refCtx || !bentCtx) return;\n  if (!src || srcDpr !== dpr) { src = readSprite(dpr); srcDpr = dpr; }\n  if (!src) return;\n  if (dpr !== curDpr || sp.width !== curW || sp.height !== curH) {\n    curDpr = dpr; curW = sp.width; curH = sp.height;\n    const OW = Math.ceil((sp.width + 2 * PAD) * dpr), OH = Math.ceil((sp.height + 2 * PAD) * dpr);\n    curCanvas.width = refCanvas.width = bentCanvas.width = OW;\n    curCanvas.height = refCanvas.height = bentCanvas.height = OH;\n    curCanvas.style.width = `${sp.width + 2 * PAD}px`;\n    curCanvas.style.height = `${sp.height + 2 * PAD}px`;\n    bentData = bentCtx.createImageData(OW, OH);\n  }\n  const OW = curCanvas.width, OH = curCanvas.height;\n\n  // Pull and bend: strength · w^curve, each eased by `smoothing`.\n  const k = Math.pow(w, o.curve);\n  const ease = 1 - Math.exp(-dt / (0.012 + o.smoothing * 0.14));\n  amp += (o.strength * k - amp) * ease;\n  bend += (o.deform * k - bend) * ease;\n  let A = amp * dpr, B = bend * dpr;\n\n  // The well's centre eases toward the nearest orb, on `handover`: at the\n  // default it takes about half a second to settle, so a switch of orb\n  // reads as the pull gliding across rather than snapping.\n  if (Number.isNaN(wcx)) { wcx = _c.cx; wcy = _c.cy; }\n  else {\n    const swing = 1 - Math.exp(-dt / (0.05 + o.handover * 0.6));\n    wcx += (_c.cx - wcx) * swing; wcy += (_c.cy - wcy) * swing;\n  }\n\n  // Geometry in canvas device px: hotspot at (P + hot), orb centre placed\n  // relative to it exactly as on screen.\n  const P = PAD * dpr;\n  const hx = P + sp.hotX * dpr, hy = P + sp.hotY * dpr;\n  const cxo = hx + (wcx - lpx) * dpr, cyo = hy + (wcy - lpy) * dpr;\n  const dTip = Math.hypot(cxo - hx, cyo - hy) || 1;\n  const ux = (cxo - hx) / dTip, uy = (cyo - hy) / dTip;\n  const F = o.falloff * dpr;\n\n  // A pull toward the tip's side shortens the body, and a shortening looks\n  // weaker than a stretch of the same size: `squash` adds to both parts in\n  // proportion to how far the pull runs against the body's axis.\n  if (o.squash > 0) {\n    const axL = Math.hypot(sp.width * 0.5 - sp.hotX, sp.height - sp.hotY) || 1;\n    const axx = (sp.width * 0.5 - sp.hotX) / axL, axy = (sp.height - sp.hotY) / axL;\n    const against = Math.max(0, -(ux * axx + uy * axy));\n    const gain = 1 + o.squash * against;\n    A *= gain; B *= gain;\n  }\n\n  // The only region any pixel can land in: the sprite's box, grown by the\n  // bend, swept along the tail. Every raster op below is clipped to it.\n  const grow = Math.ceil(Math.max(B, 1)) + 4;\n  const bx1 = Math.floor(Math.min(P, P + ux * A) - grow), by1 = Math.floor(Math.min(P, P + uy * A) - grow);\n  const bx2 = Math.ceil(Math.max(P, P + ux * A) + sp.width * dpr + grow), by2 = Math.ceil(Math.max(P, P + uy * A) + sp.height * dpr + grow);\n  const rx = Math.max(0, bx1), ry = Math.max(0, by1);\n  const rw = Math.min(OW, bx2) - rx, rh = Math.min(OH, by2) - ry;\n\n  if (B > 0.01) {\n    bendSprite(B, o.taper, P, hx, hy, cxo, cyo);\n    bentCtx.putImageData(bentData!, 0, 0, rx, ry, rw, rh);\n  } else {\n    // No bend: the stock sprite, without touching pixels.\n    bentCtx.setTransform(1, 0, 0, 1, 0, 0);\n    bentCtx.clearRect(0, 0, OW, OH);\n    bentCtx.drawImage(spriteImg, P, P, sp.width * dpr, sp.height * dpr);\n  }\n\n  const ctx = curCtx, rctx = refCtx;\n  ctx.setTransform(1, 0, 0, 1, 0, 0);\n  ctx.clearRect(0, 0, OW, OH);\n  ctx.globalAlpha = 1;\n  ctx.globalCompositeOperation = 'source-over';\n  ctx.drawImage(bentCanvas, 0, 0);\n\n  if (A > 0.5) {\n    // Mask: a band across the pointer's body along the pull axis — full on\n    // the side facing the orb, gone on the far side. Anchored on the body's\n    // centre so it behaves the same whichever side the orb is on.\n    const bcx = P + sp.width * dpr * 0.42, bcy = P + sp.height * dpr * 0.5;\n    const half = F / 2;\n    const mask = rctx.createLinearGradient(bcx - ux * half, bcy - uy * half, bcx + ux * half, bcy + uy * half);\n    mask.addColorStop(0, 'rgba(0,0,0,0)');\n    mask.addColorStop(1, 'rgba(0,0,0,1)');\n    for (let i = PASSES; i >= 1; i--) {\n      const t = i / PASSES;\n      rctx.setTransform(1, 0, 0, 1, 0, 0);\n      rctx.globalCompositeOperation = 'source-over';\n      rctx.globalAlpha = 1;\n      rctx.clearRect(rx, ry, rw, rh);\n      rctx.drawImage(bentCanvas, rx, ry, rw, rh, rx + ux * A * t, ry + uy * A * t, rw, rh);\n      rctx.globalCompositeOperation = 'destination-in';\n      rctx.fillStyle = mask;\n      rctx.fillRect(rx, ry, rw, rh);\n      // Under the pointer, fading with distance along the pull — and, on\n      // `blur`, softening with it. The blur rises as √t: the far stamps are\n      // nearly transparent already, so a blur that only peaked there would\n      // never be seen; this way the mid-tail, still visible, is soft too.\n      ctx.globalCompositeOperation = 'destination-over';\n      ctx.globalAlpha = Math.pow(1 - t, 1.6) * 0.9;\n      if (o.blur > 0) ctx.filter = `blur(${(o.blur * Math.sqrt(t) * dpr).toFixed(2)}px)`;\n      ctx.drawImage(refCanvas, rx, ry, rw, rh, rx, ry, rw, rh);\n    }\n    ctx.filter = 'none';\n    ctx.globalAlpha = 1;\n    ctx.globalCompositeOperation = 'source-over';\n  }\n\n  curEl.style.transform = `translate3d(${(lpx - sp.hotX - PAD).toFixed(2)}px,${(lpy - sp.hotY - PAD).toFixed(2)}px,0)`;\n  if (!curShown) { curEl.style.display = ''; curShown = true; }\n}\n\n// ─── Frame ─────────────────────────────────────────────────────────────\n\nfunction step(now: number): void {\n  raf = 0;\n  if (!tracking) return;\n  /* Timed from here, not from the frame's timestamp: on a page with other\n     animation loops (every orb has one) the rAF timestamp can be many ms\n     before this callback runs, and that time is not ours. */\n  const t0 = performance.now();\n  try {\n    stepInner(now);\n  } catch (err) {\n    // Whatever broke, the user must get their cursor back.\n    disabled = true;\n    disabledReason = `disabled after an error (${err instanceof Error ? err.message : String(err)})`;\n    hideCursor();\n    near = null;\n    if (typeof console !== 'undefined') console.warn('thinking-orbs: gravity disabled after error', err);\n    return;\n  }\n  // Watchdog: the bend and the tail are a few ms at most. If frames stay\n  // slower than that — a huge page, a pathological elementFromPoint —\n  // stop swapping the cursor rather than make the pointer stutter.\n  const took = performance.now() - t0;\n  if (took > 12) {\n    if (++slowFrames >= 30 && !disabled) {\n      disabled = true;\n      disabledReason = `disabled after slow frames (~${Math.round(took)}ms each)`;\n      hideCursor();\n    }\n  } else slowFrames = 0;\n}\n\nfunction stepInner(now: number): void {\n  const dt = Math.min(0.05, Math.max(0.001, (now - last) / 1000));\n  last = now;\n  stepSeq++;\n\n  // Nearest orb within reach. The orb is the disc inscribed in its element.\n  let best: Instance | null = null;\n  let u = 0;\n  if (!Number.isNaN(px) && swapAllowed()) {\n    let bestEdge = Number.POSITIVE_INFINITY;\n    for (const inst of instances) {\n      if (!inst.el.isConnected) continue;\n      const r = inst.el.getBoundingClientRect();\n      if (r.width <= 0) continue;\n      const cx = r.left + r.width / 2, cy = r.top + r.height / 2;\n      const orbR = Math.min(r.width, r.height) / 2;\n      const reach = effective(inst).reach;\n      if (px < cx - orbR - reach || px > cx + orbR + reach || py < cy - orbR - reach || py > cy + orbR + reach) continue;\n      const edge = Math.hypot(px - cx, py - cy) - orbR;\n      if (edge <= reach && edge < bestEdge) {\n        bestEdge = edge; best = inst;\n        _c.cx = cx; _c.cy = cy; _c.r = orbR;\n      }\n    }\n    if (best) {\n      const t = 1 - Math.max(0, bestEdge) / effective(best).reach;\n      u = t * t * (3 - 2 * t);\n      lastReach = now;\n    }\n  }\n\n  // Envelope on the proximity weight — no pops on enter/leave/jump.\n  const nearest = near ?? best;\n  const fade = nearest ? effective(nearest).fadeMs : GRAVITY_DEFAULTS.fadeMs;\n  const a = 1 - Math.exp(-(dt * 1000) / (fade / 3));\n  uS += (u - uS) * a;\n\n  if (best && best !== near) near = best;\n  if (!best && uS < 0.002) {\n    uS = 0;\n    if (near && hiding && !releasePending && pointerIsMouse && !typing && !Number.isNaN(px)) {\n      if (now - lastReach < LINGER_MS) {\n        // Linger: plain sprite at the pointer, swap kept, so a nearby orb\n        // can take over without the cursor changing hands.\n        if (claimCursor(px, py)) drawCursor(near, 0, dt);\n        else hideSprite();\n        raf = requestAnimationFrame(step);\n        return;\n      }\n      if (curShown) {\n        // Give the OS pointer back, but leave the sprite up until the move\n        // that repaints it — otherwise there is no cursor for a frame.\n        releaseCursor();\n        releasePending = true;\n        near = null;\n        return;\n      }\n    }\n    near = null;\n    hideCursor();\n    return;\n  }\n  if (!near) return;\n\n  if (uS > 0.002 && pointerIsMouse && !typing && !Number.isNaN(px) && ensureCursor() && claimCursor(px, py)) {\n    // A claim made on this very move: the OS pointer is still painted\n    // until the next move, so hold the sprite for that move rather than\n    // draw two pointers — but never longer than two frames, or a pointer\n    // that stops right after crossing an edge would have no cursor at all.\n    const holding = claimMove === moveSeq && stepSeq - claimStep < 2 && !curShown;\n    if (holding) hideSprite();\n    else drawCursor(near, uS, dt);\n  } else if (uS > 0.002 && !Number.isNaN(px) && pointerIsMouse && !typing) {\n    // Over something with its own cursor (a button): the rule is lifted and\n    // the sprite hidden; the OS pointer shows the hand there.\n    hideSprite();\n  } else {\n    hideCursor();\n  }\n\n  raf = requestAnimationFrame(step);\n}\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/braid.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/braid.ts",
          "type": "registry:component",
          "content": "// Braid: three strands plait around the sphere — the \"weaving\" state.\n// Each strand runs pole to pole on a helix, and a radial breathing term\n// makes them trade places, reading as the over/under of a plait.\n\nimport type { Dot, ModeFrame } from './types';\nimport { fibDir, finalizeFrame, frac, makeProj, radiusScale } from './core';\n\nexport const frameBraid: ModeFrame = (size, t, o) => {\n  const cx = size / 2;\n  const cy = size / 2;\n  const R = (size / 2) * 0.76;\n  const pt = makeProj(t * 0.4, 0.3, cx, cy, 1);\n  const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n  const dots: Dot[] = [];\n  const ghostN = o.ghostN ?? 150;\n  for (let i = 0; i < ghostN; i++) {\n    const d = fibDir(i, ghostN);\n    const [px, py, z] = pt(d[0] * R, d[1] * R, d[2] * R);\n    const depth = (z / R + 1) / 2;\n    dots.push({ x: px, y: py, z, r: 0.8 * rs, white: 0.78, a: 0.1 + 0.22 * depth });\n  }\n\n  const strandN = o.strandN ?? 52;\n  const turns = o.turns ?? 3;\n  for (let s = 0; s < 3; s++) {\n    const phase = (s / 3) * 2 * Math.PI;\n    for (let i = 0; i < strandN; i++) {\n      // u walks pole to pole; the frac() drift slides the whole strand along\n      const u = (frac(i / strandN + t * 0.045) * 2 - 1) * 0.96;\n      const surf = Math.sqrt(Math.max(0, 1 - u * u));\n      const endFade = Math.min(1, (1 - Math.abs(u)) / 0.1);\n      const a = u * Math.PI * turns + phase;\n      // radial breathing: strands trade places — the over/under of a plait\n      const weave = 1 + 0.075 * Math.sin(u * Math.PI * turns * 2 + phase * 2 + t * 0.8);\n      const rr = surf * R * weave;\n      const [px, py, zr] = pt(Math.cos(a) * rr, u * R * weave, Math.sin(a) * rr);\n      const depth = (zr / R + 1) / 2;\n      dots.push({\n        x: px,\n        y: py,\n        z: zr,\n        r: ((o.rBase ?? 1.2) + (o.rDepth ?? 1.8) * depth) * rs,\n        white: 0.55 - 0.45 * depth,\n        a: endFade * (0.45 + 0.55 * depth)\n      });\n    }\n  }\n  return finalizeFrame(dots, [], o.rMin);\n};\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/lattice.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/lattice.ts",
          "type": "registry:component",
          "content": "// The sphere-lattice modes: globe (searching), rubik (solving) and\n// wave (listening). All draw a lat/long dot field with mode-specific\n// motion, then hand off to the shared z-sorted painter.\n\nimport type { Dot, ModeFrame } from './types';\nimport { angleDelta, finalizeFrame, hashD, makeProj, radiusScale } from './core';\n\n// --- the shared solver heartbeat (rubik) ------------------------------\n// Rapid eased moves scramble, then replay in reverse (palindrome) so\n// everything clicks back to solved, rests, repeats.\n\ninterface Move {\n  axis: 0 | 1 | 2;\n  lo: number;\n  hi: number;\n  ang: number;\n}\n\nfunction solveCycle(time: number, count: number, slotDur: number, rest: number) {\n  const cyc = 2 * count * slotDur + rest;\n  const tc = time % cyc;\n  const amount = new Array<number>(count).fill(0);\n  let active = -1;\n  if (tc < 2 * count * slotDur) {\n    const slot = Math.floor(tc / slotDur);\n    const p = (tc - slot * slotDur) / slotDur;\n    const cl = Math.min(1, p / 0.7);\n    const ep = 1 - (1 - cl) ** 3; // machine ease-out\n    if (slot < count) {\n      for (let i = 0; i < slot; i++) amount[i] = 1;\n      amount[slot] = ep;\n      active = slot;\n    } else {\n      const u = 2 * count - 1 - slot;\n      for (let i = 0; i < u; i++) amount[i] = 1;\n      amount[u] = 1 - ep;\n      active = u;\n    }\n  }\n  return { amount, active };\n}\n\nfunction applyMoves(\n  pt3: [number, number, number],\n  moves: Move[],\n  sc: { amount: number[]; active: number }\n): [number, number, number, boolean] {\n  let [x, y, z] = pt3;\n  let inActive = false;\n  for (let i = 0; i < moves.length; i++) {\n    if (sc.amount[i] <= 0) continue;\n    const mv = moves[i];\n    const coord = mv.axis === 0 ? x : mv.axis === 1 ? y : z;\n    if (coord < mv.lo || coord >= mv.hi) continue;\n    if (i === sc.active) inActive = true;\n    const a = mv.ang * sc.amount[i];\n    const ca = Math.cos(a);\n    const sa = Math.sin(a);\n    if (mv.axis === 0) {\n      const y2 = y * ca - z * sa;\n      z = y * sa + z * ca;\n      y = y2;\n    } else if (mv.axis === 1) {\n      const x2 = x * ca + z * sa;\n      z = -x * sa + z * ca;\n      x = x2;\n    } else {\n      const x2 = x * ca - y * sa;\n      y = x * sa + y * ca;\n      x = x2;\n    }\n  }\n  return [x, y, z, inActive];\n}\n\nfunction makeMoves(count: number): Move[] {\n  const moves: Move[] = [];\n  for (let i = 0; i < count; i++) {\n    const axis = Math.min(2, Math.floor(hashD(i, 2.3) * 3)) as 0 | 1 | 2;\n    const lo = -1.0 + 0.5 * Math.min(3, Math.floor(hashD(i, 5.9) * 4));\n    const dir = hashD(i, 7.7) < 0.5 ? 1 : -1;\n    moves.push({ axis, lo, hi: lo + 0.5, ang: (dir * Math.PI) / 2 });\n  }\n  return moves;\n}\n\n// --- Globe: lat/long field, a scan meridian sweeps — searching --------\n\nexport const frameGlobe: ModeFrame = (size, t, o) => {\n  const spin = 0.5;\n  const cx = size / 2;\n  const cy = size / 2;\n  const radius = (size / 2) * 0.82;\n  const tilt = 0.4 + 0.06 * Math.sin(t * 0.35);\n  const pt = makeProj(t * spin, tilt, cx, cy, radius);\n  // scan sweeps relative to the spin; scanMul scales that relative rate\n  const scan = t * (spin + (1.7 - spin) * (o.scanMul ?? 1));\n  const rs = radiusScale(size, o.rsPow ?? 0.6);\n  const dimBase = o.dimBase ?? 1;\n\n  const dots: Dot[] = [];\n  const latRings = o.latRings ?? 17;\n  const lonDensity = o.lonDensity ?? 44;\n  for (let li = 0; li <= latRings; li++) {\n    const lat = -Math.PI / 2 + (li / latRings) * Math.PI;\n    const cosLat = Math.cos(lat);\n    const sinLat = Math.sin(lat);\n    const lonCount = Math.max(1, Math.round(Math.abs(cosLat) * lonDensity));\n    for (let lj = 0; lj < lonCount; lj++) {\n      const lon = (lj / lonCount) * 2 * Math.PI;\n      const [px, py, z] = pt(cosLat * Math.cos(lon), sinLat, cosLat * Math.sin(lon));\n      const depth = (z + 1) / 2;\n      // the scan: a moving meridian read as a size ripple, not a shine\n      const d = angleDelta(lon + t * spin, scan);\n      const boost = Math.exp(-(d * d) / 0.18) * Math.max(0, z);\n      dots.push({\n        x: px,\n        y: py,\n        z,\n        r: ((o.rBase ?? 0.6) + (o.rDepth ?? 1.7) * depth + (o.rBoost ?? 1) * boost) * rs,\n        white: (o.inkFar ?? 0.62) - (o.inkSpan ?? 0.54) * depth,\n        // dimBase < 1 fades un-scanned dots so the meridian reads clearly\n        a: dimBase + (1 - dimBase) * Math.min(1, boost)\n      });\n    }\n  }\n  return finalizeFrame(dots, [], o.rMin);\n};\n\n// --- Rubik: bands twist in quarter turns, scramble → solve — solving --\n\nexport const frameRubik: ModeFrame = (size, t, o) => {\n  const cx = size / 2;\n  const cy = size / 2;\n  const R = (size / 2) * 0.82;\n  const pt = makeProj(t * 0.55, 0.35 + 0.1 * Math.sin(t * 0.9), cx, cy, R);\n  const rs = radiusScale(size, o.rsPow ?? 0.6);\n  const moveCount = o.moveCount ?? 14;\n  const moves = makeMoves(moveCount);\n  const sc = solveCycle(t, moveCount, 0.42, 1.2);\n\n  const dots: Dot[] = [];\n  const latRings = o.latRings ?? 15;\n  const lonDensity = o.lonDensity ?? 40;\n  for (let li = 0; li <= latRings; li++) {\n    const lat = -Math.PI / 2 + (li / latRings) * Math.PI;\n    const cosLat = Math.cos(lat);\n    const sinLat = Math.sin(lat);\n    const lonCount = Math.max(1, Math.round(Math.abs(cosLat) * lonDensity));\n    for (let lj = 0; lj < lonCount; lj++) {\n      const lon = (lj / lonCount) * 2 * Math.PI;\n      const [x, y, z, inActive] = applyMoves([cosLat * Math.cos(lon), sinLat, cosLat * Math.sin(lon)], moves, sc);\n      const [px, py, zr] = pt(x, y, z);\n      const depth = (zr + 1) / 2;\n      // the band being turned inks a touch darker — the \"hand\"\n      dots.push({\n        x: px,\n        y: py,\n        z: zr,\n        r: ((o.rBase ?? 0.6) + (o.rDepth ?? 1.7) * depth + (inActive ? (o.rActive ?? 0.3) : 0)) * rs,\n        white: (o.inkFar ?? 0.62) - (o.inkSpan ?? 0.54) * depth - (inActive ? 0.14 : 0)\n      });\n    }\n  }\n  return finalizeFrame(dots, [], o.rMin);\n};\n\n// --- Wave: a waveform rolls through the rings — listening -------------\n\nexport const frameWave: ModeFrame = (size, t, o) => {\n  const cx = size / 2;\n  const cy = size / 2;\n  // 0.76 base × 1.15 — the undulation pulls the sphere inward, so wave read\n  // ~15% smaller than the other lattice modes; scaled up to match them\n  const R = (size / 2) * 0.874;\n  const pt = makeProj(t * 0.18, 0.38, cx, cy, 1);\n  const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n  const dots: Dot[] = [];\n  const rings = o.rings ?? 15;\n  const lonDensity = o.lonDensity ?? 40;\n  for (let ri = 0; ri <= rings; ri++) {\n    const lat = -Math.PI / 2 + (ri / rings) * Math.PI;\n    const cosLat = Math.cos(lat);\n    const sinLat = Math.sin(lat);\n    // two waves, different tempi — organic, never quite repeating\n    const w = 0.62 * Math.sin(t * 2.1 - ri * 0.52) + 0.38 * Math.sin(t * 1.27 + ri * 0.83);\n    const rr = R * (0.88 + 0.105 * w);\n    const lonCount = Math.max(1, Math.round(Math.abs(cosLat) * lonDensity));\n    for (let lj = 0; lj < lonCount; lj++) {\n      const lon = (lj / lonCount) * 2 * Math.PI;\n      const [px, py, z] = pt(cosLat * Math.cos(lon) * rr, sinLat * rr, cosLat * Math.sin(lon) * rr);\n      const depth = (z / R + 1) / 2;\n      const crest = Math.max(0, w);\n      dots.push({\n        x: px,\n        y: py,\n        z,\n        r: ((o.rBase ?? 0.6) + (o.rDepth ?? 1.7) * depth) * (1 + 0.4 * crest) * rs,\n        white: 0.66 - 0.56 * depth - 0.1 * crest\n      });\n    }\n  }\n  return finalizeFrame(dots, [], o.rMin);\n};\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/morph.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/morph.ts",
          "type": "registry:component",
          "content": "// Morph: a dotted outline cycling circle → triangle → square → circle —\n// the \"shaping\" state. Each shape is a continuous closed path\n// parameterised by arc length (top-centre start, clockwise). Every\n// frame the engine blends the two neighbouring paths, then lays the\n// dots EVENLY along the blended outline — spacing stays uniform at\n// every instant of the morph, holds and transitions alike. Plain\n// circle fills only: no canvas/SVG filters, fully cross-browser.\n\nimport type { Dot, ModeFrame } from './types';\nimport { finalizeFrame } from './core';\n\ntype Path = (f: number) => [number, number];\n\nfunction smoothE(x: number): number {\n  return x * x * (3 - 2 * x);\n}\n\nfunction polyPath(verts: ReadonlyArray<readonly [number, number]>): Path {\n  const V = verts.length;\n  const L: number[] = [];\n  let total = 0;\n  for (let i = 0; i < V; i++) {\n    const a = verts[i];\n    const b = verts[(i + 1) % V];\n    const l = Math.hypot(b[0] - a[0], b[1] - a[1]);\n    L.push(l);\n    total += l;\n  }\n  return (f) => {\n    let target = f * total;\n    let i = 0;\n    while (target > L[i] && i < V - 1) {\n      target -= L[i];\n      i++;\n    }\n    const a = verts[i];\n    const b = verts[(i + 1) % V];\n    const ff = L[i] ? Math.min(1, target / L[i]) : 0;\n    return [a[0] + (b[0] - a[0]) * ff, a[1] + (b[1] - a[1]) * ff];\n  };\n}\n\nconst CIRCLE: Path = (f) => {\n  const a = -Math.PI / 2 + f * 2 * Math.PI;\n  return [Math.cos(a) * 0.24, Math.sin(a) * 0.24];\n};\nconst TRIANGLE = polyPath([\n  [0.0, -0.26],\n  [0.24, 0.16],\n  [-0.24, 0.16]\n]);\n// 5-vertex walk so the path STARTS at top-centre like the other shapes\nconst SQUARE = polyPath([\n  [0, -0.2],\n  [0.2, -0.2],\n  [0.2, 0.2],\n  [-0.2, 0.2],\n  [-0.2, -0.2]\n]);\nconst CYCLE: Path[] = [CIRCLE, TRIANGLE, SQUARE];\n\n// low floor keeps sparse outlines possible while never degenerating\nfunction morphN(d: number): number {\n  return Math.max(6, Math.round(34 * d));\n}\n\nconst HOLD = 1.4;\nconst MORPH = 0.9;\nconst SEG = HOLD + MORPH;\n\n// This state was tuned in inkform, which paints it through a blur +\n// threshold \"goo\" filter; we draw plain circles instead, since `ctx.filter`\n// and SVG filter refs are not safe to rely on across Chrome / Safari /\n// Firefox. The dot GEOMETRY is identical either way — the threshold just\n// yields a hard edge where a plain fill has an antialiased one, so these\n// dots read a touch softer than inkform's. Don't \"correct\" for that by\n// shrinking the radius: it makes the mark genuinely smaller than the tuning.\n\nexport const frameMorph: ModeFrame = (size, t, o) => {\n  const K = CYCLE.length;\n  const tc = t % (SEG * K);\n  // `shape` 0 / 1 / 2 holds one outline instead of cycling; anything else\n  // (unset, or out of range) keeps the tuned circle → triangle → square loop\n  const held = o.shape != null && o.shape >= 0 && o.shape < K ? Math.floor(o.shape) : -1;\n  const k = held >= 0 ? held : Math.floor(tc / SEG);\n  const local = held >= 0 ? t % SEG : tc - k * SEG;\n  const m = held >= 0 ? 0 : local > HOLD ? smoothE((local - HOLD) / MORPH) : 0;\n  const sprd = o.spread ?? 1;\n\n  // blend the two shape PATHS at m, then measure the blended outline\n  const pA = CYCLE[k];\n  const pB = held >= 0 ? pA : CYCLE[(k + 1) % K];\n  const M = 160;\n  const pts: Array<[number, number]> = [];\n  for (let i = 0; i < M; i++) {\n    const f = i / M;\n    const a = pA(f);\n    const b = pB(f);\n    pts.push([(a[0] + (b[0] - a[0]) * m) * sprd, (a[1] + (b[1] - a[1]) * m) * sprd]);\n  }\n  const L: number[] = [];\n  let total = 0;\n  for (let i = 0; i < M; i++) {\n    const a = pts[i];\n    const b = pts[(i + 1) % M];\n    const l = Math.hypot(b[0] - a[0], b[1] - a[1]);\n    L.push(l);\n    total += l;\n  }\n\n  // dot radius depends ONLY on rDot (the size knob); the count sets the\n  // gaps. Formed shapes breathe a little (uniform pulse).\n  const n = morphN(o.iconD ?? 1);\n  const re = (o.rDot ?? 0.021) * 1.35 * sprd;\n  const pulse = 1 + 0.02 * Math.sin(local * 3.1);\n\n  const dots: Dot[] = [];\n  const c2 = size / 2;\n  let seg = 0;\n  let acc = 0;\n  for (let k2 = 0; k2 < n; k2++) {\n    const target = (k2 / n) * total;\n    while (acc + L[seg] < target && seg < M - 1) {\n      acc += L[seg];\n      seg++;\n    }\n    const a = pts[seg];\n    const b = pts[(seg + 1) % M];\n    const f = L[seg] ? Math.min(1, (target - acc) / L[seg]) : 0;\n    const x = (a[0] + (b[0] - a[0]) * f) * pulse;\n    const y = (a[1] + (b[1] - a[1]) * f) * pulse;\n    dots.push({\n      x: c2 + x * size,\n      y: c2 + y * size,\n      z: 0,\n      r: Math.max(0.35, re * size),\n      white: 0.1\n    });\n  }\n  return finalizeFrame(dots, [], o.rMin);\n};\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/orbits.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/orbits.ts",
          "type": "registry:component",
          "content": "// Orbits: particles on tilted orbits — the \"working\" state. No nucleus\n// (the tuned preset runs coreless): just ghost paths and the particles\n// doing the work.\n\nimport type { Dot, ModeFrame } from './types';\nimport { finalizeFrame, hashD, makeProj, radiusScale } from './core';\n\nexport const frameOrbits: ModeFrame = (size, t, o) => {\n  const cx = size / 2;\n  const cy = size / 2;\n  const R = (size / 2) * 0.82;\n  const pt = makeProj(t * 0.12, 0.3, cx, cy, 1);\n  const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n  const dots: Dot[] = [];\n  const orbitN = o.orbitN ?? 12;\n  const ghostN = o.ghostN ?? 40;\n  const particles = o.particles ?? 3;\n\n  // orbits: each a tilted circle — a ghost path + running particles\n  for (let orb = 0; orb < orbitN; orb++) {\n    const h1 = hashD(orb, 1.7);\n    const h2 = hashD(orb, 5.2);\n    const h3 = hashD(orb, 8.9);\n    const ro = R * (0.45 + 0.52 * h1);\n    const th = h1 * 2 * Math.PI;\n    const phi = Math.acos(2 * h2 - 1);\n    // orbit plane basis (u, v ⟂ normal n)\n    const nx = Math.sin(phi) * Math.cos(th);\n    const ny = Math.cos(phi);\n    const nz = Math.sin(phi) * Math.sin(th);\n    let ux = -ny;\n    let uy = nx;\n    const uz = 0;\n    const ul = Math.max(1e-6, Math.sqrt(ux * ux + uy * uy));\n    ux /= ul;\n    uy /= ul;\n    const vx = ny * uz - nz * uy;\n    const vy = nz * ux - nx * uz;\n    const vz = nx * uy - ny * ux;\n    const speed = (0.25 + 0.55 * h3) * (h3 > 0.5 ? 1 : -1);\n\n    // ghost path\n    for (let k = 0; k < ghostN; k++) {\n      const a = (k / ghostN) * 2 * Math.PI;\n      const [px, py, z] = pt(\n        (ux * Math.cos(a) + vx * Math.sin(a)) * ro,\n        (uy * Math.cos(a) + vy * Math.sin(a)) * ro,\n        (uz * Math.cos(a) + vz * Math.sin(a)) * ro\n      );\n      const depth = (z / ro + 1) / 2;\n      dots.push({\n        x: px,\n        y: py,\n        z,\n        r: (o.ghostR ?? 0.9) * rs,\n        white: 0.72,\n        a: (o.ghostA ?? 0.5) * (0.4 + 0.6 * depth)\n      });\n    }\n    // the particles doing the work\n    for (let m = 0; m < particles; m++) {\n      const a = t * speed + (m / particles) * 2 * Math.PI + h2 * 6;\n      const [px, py, z] = pt(\n        (ux * Math.cos(a) + vx * Math.sin(a)) * ro,\n        (uy * Math.cos(a) + vy * Math.sin(a)) * ro,\n        (uz * Math.cos(a) + vz * Math.sin(a)) * ro\n      );\n      const depth = (z / ro + 1) / 2;\n      dots.push({\n        x: px,\n        y: py,\n        z,\n        r: ((o.partR ?? 1.2) + (o.partRDepth ?? 1.6) * depth) * rs,\n        white: 0.3 - 0.22 * depth\n      });\n    }\n  }\n  return finalizeFrame(dots, [], o.rMin);\n};\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/ribbon.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/ribbon.ts",
          "type": "registry:component",
          "content": "// Ribbon: an undulating sash of parallel strands rides a great circle —\n// the \"composing\" state. The tuned preset freezes the 3D tumble\n// (spin 0), leaving the traveling undulation on a fixed band.\n//\n// The same painter also drives \"breathing\" (ring), via the `faceOn` flag:\n// a face-on circle whose radius — not its out-of-plane offset — undulates,\n// so it reads as a ring slowly morphing rather than a sash in orbit.\n\nimport type { Dot, ModeFrame } from './types';\nimport { fibDir, finalizeFrame, makeProj, radiusScale } from './core';\n\nexport const frameRibbon: ModeFrame = (size, t, o) => {\n  const cx = size / 2;\n  const cy = size / 2;\n  const R = (size / 2) * 0.78;\n  // spin scales the 3D tumble; spin=0 freezes the band's orientation,\n  // leaving only the traveling undulation\n  const spin = o.spin ?? 1;\n  const camTilt = 0.3;\n  const pt = makeProj(t * 0.1 * spin, camTilt, cx, cy, 1);\n  const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n  const dots: Dot[] = [];\n  const ghostN = o.ghostN ?? 150;\n  for (let i = 0; i < ghostN; i++) {\n    const d = fibDir(i, ghostN);\n    const [px, py, z] = pt(d[0] * R, d[1] * R, d[2] * R);\n    const depth = (z / R + 1) / 2;\n    dots.push({ x: px, y: py, z, r: 0.8 * rs, white: 0.78, a: 0.1 + 0.22 * depth });\n  }\n\n  // The band plane, precessing (frozen when spin=0). The projection squashes\n  // the band's great circle vertically by cos(ta + camTilt); face-on sets\n  // ta = -camTilt so that term is 1 and the band reads as a true circle\n  // rather than ribbon's tilted ellipse.\n  const ya = t * 0.24 * spin;\n  const ta = o.faceOn ? -camTilt : 0.55 + 0.3 * Math.sin(t * 0.18) * spin;\n  const ux = Math.cos(ya);\n  const uy = 0;\n  const uz = Math.sin(ya);\n  const vx = -uz * Math.sin(ta);\n  const vy = Math.cos(ta);\n  const vz = ux * Math.sin(ta);\n  // plane normal n = u × v\n  const nx = uy * vz - uz * vy;\n  const ny = uz * vx - ux * vz;\n  const nz = ux * vy - uy * vx;\n\n  // Radial lobes swell past R, so pull the base radius in by (most of) the\n  // wobble amplitude. The silhouette then stays inside the frame however far\n  // the deformation is pushed, while lobes keep getting deeper relative to\n  // the mean radius.\n  const wobAmp = 0.23 * (o.wobMul ?? 1);\n  const baseR = o.faceOn ? R / (1 + 0.85 * wobAmp) : R;\n\n  const baseLanes = o.lanes ?? 5;\n  const segs = o.segs ?? 88;\n  const lanes = Math.max(1, Math.round(baseLanes * (o.bandMul ?? 1)));\n  for (let w = 0; w < lanes; w++) {\n    const laneOff = (w - (lanes - 1) / 2) * 0.075;\n    const edge = Math.abs(w - (lanes - 1) / 2) / Math.max(1, (lanes - 1) / 2);\n    for (let k = 0; k < segs; k++) {\n      const a = (k / segs) * 2 * Math.PI;\n      // the undulation: two traveling waves along the band; wobMul\n      // scales the deformation — 0 is a clean band\n      const wob =\n        (0.16 * Math.sin(a * 3 - t * 1.7 + w * 0.22) + 0.07 * Math.sin(a * 5 + t * 1.1)) * (o.wobMul ?? 1);\n      // A normal-direction wobble is cancelled by the re-normalisation below:\n      // the point lands back on the sphere, so the silhouette is pinned at R\n      // and the deformation can only ever pull dots inward. Face-on instead\n      // modulates the in-plane RADIUS, so lobes genuinely swell outward and\n      // pinch inward. Ribbon keeps the original out-of-plane sash wobble.\n      const radial = o.faceOn ? 1 + wob : 1;\n      const off = o.faceOn ? laneOff : laneOff + wob;\n      const x = ux * Math.cos(a) + vx * Math.sin(a) + nx * off;\n      const y = uy * Math.cos(a) + vy * Math.sin(a) + ny * off;\n      const z = uz * Math.cos(a) + vz * Math.sin(a) + nz * off;\n      const l = Math.sqrt(x * x + y * y + z * z);\n      const rr = baseR * radial;\n      const [px, py, zr] = pt((x / l) * rr, (y / l) * rr, (z / l) * rr);\n      const depth = (zr / R + 1) / 2;\n      dots.push({\n        x: px,\n        y: py,\n        z: zr,\n        r: ((o.rBase ?? 1.1) + (o.rDepth ?? 1.7) * depth) * (1 - 0.25 * edge) * rs,\n        white: 0.52 - 0.44 * depth + 0.18 * edge,\n        a: 0.4 + 0.6 * depth\n      });\n    }\n  }\n  return finalizeFrame(dots, [], o.rMin);\n};\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/web.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/web.ts",
          "type": "registry:component",
          "content": "// Web: a constellation wires itself — the \"connecting\" state. Nodes drift\n// on the sphere under slow value noise; any pair closer than `thr` grows an\n// edge, and bright packets run along randomly re-picked node pairs.\n\nimport type { Dot, Line, ModeFrame } from './types';\nimport { fibDir, finalizeFrame, frac, hashD, lerp, makeProj, radiusScale, vnoise } from './core';\n\nexport const frameWeb: ModeFrame = (size, t, o) => {\n  const cx = size / 2;\n  const cy = size / 2;\n  const R = (size / 2) * 0.8 * (o.spread ?? 1);\n  // note the projector carries the radius as its scale, so node vectors stay\n  // unit-length and distances below are in unit-sphere space\n  const pt = makeProj(t * 0.12, 0.32, cx, cy, R);\n  const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n  const nodeN = o.nodeN ?? 30;\n  const thr = o.thr ?? 0.72;\n  const nodeR = o.nodeR ?? 1.4;\n  const nodeRDepth = o.nodeRDepth ?? 1.8;\n\n  // nodes: fib lattice + slow noise wander, renormalised to the surface\n  const nodes: Array<[number, number, number]> = [];\n  for (let i = 0; i < nodeN; i++) {\n    const d = fibDir(i, nodeN);\n    const x = d[0] + 0.3 * (vnoise(i * 0.31 + 9, t * 0.24) - 0.5) * 2;\n    const y = d[1] + 0.3 * (vnoise(i * 0.53 + 27, t * 0.21) - 0.5) * 2;\n    const z = d[2] + 0.3 * (vnoise(i * 0.77 + 55, t * 0.27) - 0.5) * 2;\n    const l = Math.sqrt(x * x + y * y + z * z);\n    nodes.push([x / l, y / l, z / l]);\n  }\n\n  const lines: Line[] = [];\n  const dots: Dot[] = [];\n\n  // edges between close neighbours, alpha by proximity + depth\n  for (let i = 0; i < nodeN; i++) {\n    for (let j = i + 1; j < nodeN; j++) {\n      const dx = nodes[i][0] - nodes[j][0];\n      const dy = nodes[i][1] - nodes[j][1];\n      const dz = nodes[i][2] - nodes[j][2];\n      const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);\n      if (dist >= thr) continue;\n      const [x1, y1, z1] = pt(nodes[i][0], nodes[i][1], nodes[i][2]);\n      const [x2, y2, z2] = pt(nodes[j][0], nodes[j][1], nodes[j][2]);\n      const depth = ((z1 + z2) / 2 + 1) / 2;\n      lines.push({\n        x1,\n        y1,\n        x2,\n        y2,\n        white: 0.42,\n        a: (1 - dist / thr) * (0.3 + 0.55 * depth),\n        w: Math.max(0.6, (o.lineW ?? 0.8) * rs)\n      });\n    }\n  }\n\n  for (let i = 0; i < nodeN; i++) {\n    const [px, py, z] = pt(nodes[i][0], nodes[i][1], nodes[i][2]);\n    const depth = (z + 1) / 2;\n    const pulse = 1 + 0.25 * Math.sin(t * 1.4 + i * 2.7);\n    dots.push({\n      x: px,\n      y: py,\n      z,\n      r: (nodeR + nodeRDepth * depth) * pulse * rs,\n      white: 0.55 - 0.45 * depth\n    });\n  }\n\n  // signals: bright packets running between paired nodes\n  const signals = o.signals ?? 5;\n  for (let s = 0; s < signals; s++) {\n    const seg = Math.floor(t * 0.55 + s * 7.31);\n    const a = Math.floor(hashD(seg, s * 3.1 + 1.7) * nodeN);\n    const b = Math.floor(hashD(seg, s * 5.7 + 4.2) * nodeN);\n    if (a === b) continue;\n    const f = frac(t * 0.55 + s * 7.31);\n    const x = lerp(nodes[a][0], nodes[b][0], f);\n    const y = lerp(nodes[a][1], nodes[b][1], f);\n    const z = lerp(nodes[a][2], nodes[b][2], f);\n    const l = Math.max(1e-6, Math.sqrt(x * x + y * y + z * z));\n    const [px, py, zr] = pt(x / l, y / l, z / l);\n    const depth = (zr + 1) / 2;\n    dots.push({\n      x: px,\n      y: py,\n      z: zr,\n      r: (nodeR * 1.5 + nodeRDepth * depth) * rs,\n      white: 0.05,\n      a: 0.5 + 0.5 * depth\n    });\n  }\n\n  return finalizeFrame(dots, lines, o.rMin);\n};\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/theme.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/theme.ts",
          "type": "registry:component",
          "content": "// Theme resolution: explicit prop → ancestor data-theme/.dark|.light\n// class (watched live) → prefers-color-scheme (subscribed live).\n// SSR-safe: everything runs in effects; the pre-mount fallback is dark.\n\nimport type { RefObject } from 'react';\nimport { useEffect, useState } from 'react';\nimport type { OrbTheme } from './types';\n\nfunction ancestorTheme(el: Element | null): boolean | null {\n  let node: Element | null = el;\n  while (node) {\n    const attr = node.getAttribute('data-theme');\n    if (attr === 'dark') return true;\n    if (attr === 'light') return false;\n    if (node.classList.contains('dark')) return true;\n    if (node.classList.contains('light')) return false;\n    node = node.parentElement;\n  }\n  return null;\n}\n\nfunction systemDark(): boolean {\n  return typeof matchMedia === 'undefined' || matchMedia('(prefers-color-scheme: dark)').matches;\n}\n\n/** Resolve the effective dark/light substrate for a mounted element. */\nexport function useResolvedDark(theme: OrbTheme, hostRef: RefObject<Element | null>): boolean {\n  const [dark, setDark] = useState(true);\n\n  useEffect(() => {\n    if (theme === 'dark') {\n      setDark(true);\n      return;\n    }\n    if (theme === 'light') {\n      setDark(false);\n      return;\n    }\n\n    const resolve = () => {\n      const fromTree = ancestorTheme(hostRef.current);\n      setDark(fromTree ?? systemDark());\n    };\n    resolve();\n\n    // live OS/browser theme switches\n    const mq = typeof matchMedia !== 'undefined' ? matchMedia('(prefers-color-scheme: dark)') : null;\n    const onMq = () => resolve();\n    mq?.addEventListener('change', onMq);\n\n    // live app-level toggles: watch class/data-theme flips on ancestors\n    let mo: MutationObserver | null = null;\n    if (typeof MutationObserver !== 'undefined' && hostRef.current) {\n      mo = new MutationObserver(resolve);\n      mo.observe(document.documentElement, {\n        attributes: true,\n        attributeFilter: ['class', 'data-theme'],\n        subtree: true\n      });\n    }\n\n    return () => {\n      mq?.removeEventListener('change', onMq);\n      mo?.disconnect();\n    };\n  }, [theme, hostRef]);\n\n  return dark;\n}\n\n/** Live `prefers-reduced-motion` — reduced users get a static frame. */\nexport function useReducedMotion(): boolean {\n  const [reduced, setReduced] = useState(false);\n  useEffect(() => {\n    if (typeof matchMedia === 'undefined') return;\n    const mq = matchMedia('(prefers-reduced-motion: reduce)');\n    setReduced(mq.matches);\n    const on = (e: MediaQueryListEvent) => setReduced(e.matches);\n    mq.addEventListener('change', on);\n    return () => mq.removeEventListener('change', on);\n  }, []);\n  return reduced;\n}\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/index.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/index.ts",
          "type": "registry:component",
          "content": "export { ThinkingOrb } from './ThinkingOrb';\n\nexport type { ThinkingOrbProps, OrbState, OrbSize, OrbTheme } from './types';\n\n// Power-user surface: the resolved presets + raw frame painters, for\n// consumers driving their own canvas outside React.\nexport { resolvePreset, STATE_TO_MODE, type ModeKey, type Resolved } from './presets';\nexport { MODE_DRAWS, MODE_FRAMES } from './engine/registry';\nexport { countDots, scaleCounts, scaleRadii } from './engine/profiles';\n// The geometry toolkit the built-in modes are written with, so a custom\n// `frame` can be built from the same parts.\nexport {\n  finalizeFrame, makeProj, radiusScale, fibDir, hashD, vnoise, lerp, frac, angleDelta,\n} from './engine/core';\nexport type { ModeFrame, ModeOpts, OrbFrame, Dot, Line } from './engine/index';\n// Gravity: the orb pulls the pointer in. The sprite has to be the\n// platform's real pointer, so the consumer supplies it.\nexport { attachGravity, setGravitySprite, setGravityConfig, getGravityConfig, getGravityStatus, resetGravity, GRAVITY_DEFAULTS } from './gravity';\nexport type { GravityOptions, CursorSprite } from './gravity';\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/upstream/engine/index.ts",
          "target": "@components/agents-ui/application/thinking-indicator/upstream/engine/index.ts",
          "type": "registry:component",
          "content": "// The `thinking-orbs/engine` entry point: pure geometry, zero React, zero\n// DOM. Import this to drive your own renderer — a Skia canvas in React\n// Native, an offscreen canvas in a worker, a server-side rasteriser.\n//\n// The contract is deliberately small: resolve a (state, size) pair to its\n// draw options once, then call the mode's frame function per instant. What\n// comes back is a finished, z-sorted list of circles (and, for `connecting`,\n// line segments) with every value final — draw them in order and you have\n// the same picture the React component paints.\n//\n//   import { resolvePreset } from 'thinking-orbs/engine';\n//   import { MODE_FRAMES } from 'thinking-orbs/engine';\n//\n//   const { mode, speed, opts } = resolvePreset('searching', 64);\n//   const { dots, lines } = MODE_FRAMES[mode](64, elapsedSeconds * speed, opts);\n//\n// Ink convention: `white` is the paper-theme ink value in [0,1]; on a dark\n// substrate a renderer mirrors it (`1 - white`) so near dots read bright.\n\nexport { MODE_FRAMES, MODE_DRAWS } from './registry';\nexport { resolvePreset, STATE_TO_MODE, type ModeKey, type Resolved } from '../presets';\nexport type { Dot, Line, OrbFrame, ModeFrame, ModeDraw } from './types';\nexport type { ModeOpts } from './profiles';\nexport type { OrbState, OrbSize } from '../types';\n\n// Escape hatches for renderers that want the primitives themselves.\nexport { finalizeFrame, paintFrame, paint, paintLines, radiusScale, makeProj } from './core';\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/LICENSE",
          "target": "@components/agents-ui/application/thinking-indicator/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Jakub Antalik\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/NOTICE.md",
          "target": "@components/agents-ui/application/thinking-indicator/NOTICE.md",
          "type": "registry:file",
          "content": "# Source notice\n\nThe `upstream/` directory is a source-faithful copy of `packages/thinking-orbs/src` from the public [Libraries.dev](https://github.com/Jakubantalik/Libraries.dev) repository at the revision recorded in `SOURCE.json`.\n\nThe local `ThinkingIndicator` wrapper is independently implemented with visible status text. The complete upstream MIT license is distributed in this folder.\n"
        },
        {
          "path": "components/agents-ui/application/thinking-indicator/SOURCE.json",
          "target": "@components/agents-ui/application/thinking-indicator/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"thinking-orbs\",\n  \"repository\": \"https://github.com/Jakubantalik/Libraries.dev\",\n  \"revision\": \"422180dd7a5ac646c85deedc65500c4a74339127\",\n  \"packageVersion\": \"0.3.1\",\n  \"license\": \"MIT\",\n  \"copiedPath\": \"upstream/\",\n  \"sourcePath\": \"packages/thinking-orbs/src/\",\n  \"copiedFiles\": [\n    \"src/ThinkingOrb.tsx\",\n    \"src/types.ts\",\n    \"src/theme.ts\",\n    \"src/presets.ts\",\n    \"src/gravity.ts\",\n    \"src/engine/**\"\n  ],\n  \"relationship\": \"Source-faithful copy of the pinned public React canvas implementation and engine. The surrounding ThinkingIndicator wrapper and presentation are local.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-tool-approval",
      "type": "registry:block",
      "title": "Agent Tool Approval",
      "description": "agent tool approval",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-tool-approval.tsx",
          "target": "@components/agents-ui/agent-tool-approval.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { ToolApproval } from \"@/components/agents-ui/application/tool-approval/tool-approval\"\n\nexport type RiskLevel = \"low\" | \"medium\" | \"high\"\nexport interface ToolApprovalRequest {\n  toolName: string\n  description: string\n  parameters: Record<string, string>\n  riskLevel: RiskLevel\n  reasoning: string\n}\nexport interface ToolApprovalHistoryItem {\n  id: string\n  toolName: string\n  decision: \"approved\" | \"rejected\"\n  timestamp: string\n  actor?: string\n}\nexport interface ToolExecutionResult {\n  success: boolean\n  output: string\n  duration?: string\n}\nexport interface AgentToolApprovalProps {\n  pendingApproval?: ToolApprovalRequest | null\n  approvalHistory?: ToolApprovalHistoryItem[]\n  executionResult?: ToolExecutionResult | null\n  onApprove?: () => void\n  onReject?: () => void\n  onAlwaysAllow?: (toolName: string) => void\n  className?: string\n}\nexport function AgentToolApproval(props: AgentToolApprovalProps) {\n  return <ToolApproval {...props} />\n}\n"
        },
        {
          "path": "components/agents-ui/application/tool-approval/tool-approval.tsx",
          "target": "@components/agents-ui/application/tool-approval/tool-approval.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport type {\n  AgentToolApprovalProps,\n  ToolApprovalHistoryItem,\n  ToolApprovalRequest,\n  ToolExecutionResult,\n} from \"@/components/agents-ui/agent-tool-approval\"\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Checkbox } from \"@/components/boardui/base/checkbox/checkbox\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, ChevronDown, Clock, Shield, X } from \"lucide-react\"\nimport * as React from \"react\"\n\nconst fallback: ToolApprovalRequest = {\n  toolName: \"create_salesforce_tasks\",\n  description: \"Create 12 follow-up tasks in Salesforce\",\n  parameters: {\n    scope: \"12 account records\",\n    target: \"Task records only\",\n    reversibility: \"Tasks can be deleted\",\n    due_date: \"This Friday\",\n    owner: \"Current account owner\",\n  },\n  riskLevel: \"medium\",\n  reasoning:\n    \"The renewal review found four accounts that need executive outreach this week. Creating assigned tasks keeps the work visible without contacting customers.\",\n}\nconst riskLabel = {\n  low: \"Low risk\",\n  medium: \"Medium risk\",\n  high: \"High risk\",\n} as const\n\nfunction ApprovalRecord({ item }: { item: ToolApprovalHistoryItem }) {\n  const approved = item.decision === \"approved\"\n  return (\n    <li className=\"grid grid-cols-[18px_1fr_auto] items-start gap-2 py-2.5\">\n      <span\n        className={\n          approved\n            ? \"text-green-700 dark:text-green-400\"\n            : \"text-red-700 dark:text-red-400\"\n        }\n      >\n        {approved ? <Check className=\"size-4\" /> : <X className=\"size-4\" />}\n      </span>\n      <div className=\"min-w-0\">\n        <p className=\"text-text-primary truncate font-mono text-xs\">\n          {item.toolName}\n        </p>\n        <p className=\"text-text-secondary mt-0.5 text-xs\">\n          {approved ? \"Approved\" : \"Rejected\"}\n          {item.actor ? ` by ${item.actor}` : \"\"}\n        </p>\n      </div>\n      <span className=\"text-text-secondary flex items-center gap-1 text-xs\">\n        <Clock className=\"size-3\" />\n        {item.timestamp}\n      </span>\n    </li>\n  )\n}\n\nfunction ResultAndHistory({\n  result,\n  history,\n}: {\n  result?: ToolExecutionResult | null\n  history: ToolApprovalHistoryItem[]\n}) {\n  if (!result && history.length === 0) return null\n  return (\n    <div className=\"mt-4 space-y-4\">\n      {result && (\n        <section\n          aria-label=\"Execution result\"\n          className=\"bg-background-secondary-default rounded-lg p-3 text-sm\"\n        >\n          <p\n            className={\n              result.success\n                ? \"text-green-700 dark:text-green-400\"\n                : \"text-red-700 dark:text-red-400\"\n            }\n          >\n            {result.success ? \"Execution complete\" : \"Execution failed\"}\n            {result.duration ? ` · ${result.duration}` : \"\"}\n          </p>\n          <pre className=\"text-text-secondary mt-2 max-h-40 overflow-auto font-mono text-xs leading-5 whitespace-pre-wrap\">\n            {result.output}\n          </pre>\n        </section>\n      )}\n      {history.length > 0 && (\n        <section aria-labelledby=\"approval-history-heading\">\n          <h3\n            id=\"approval-history-heading\"\n            className=\"text-text-primary text-sm font-medium\"\n          >\n            Approval history\n          </h3>\n          <ol className=\"divide-separator-border border-separator-border mt-2 divide-y border-y\">\n            {history.map((item) => (\n              <ApprovalRecord key={item.id} item={item} />\n            ))}\n          </ol>\n        </section>\n      )}\n    </div>\n  )\n}\n\nexport function ToolApproval({\n  pendingApproval,\n  approvalHistory = [],\n  executionResult,\n  onApprove,\n  onReject,\n  onAlwaysAllow,\n  className,\n}: AgentToolApprovalProps) {\n  const request = pendingApproval === undefined ? fallback : pendingApproval\n  const [remember, setRemember] = React.useState(false)\n  if (!request)\n    return (\n      <section\n        className={cx(\n          \"border-separator-border bg-background-primary-default rounded-xl border p-5\",\n          className\n        )}\n      >\n        <p className=\"text-text-primary text-sm font-medium\">\n          No approvals waiting\n        </p>\n        <p className=\"text-text-secondary mt-1 text-sm\">\n          Requests appear here when an agent needs a decision.\n        </p>\n        <ResultAndHistory result={executionResult} history={approvalHistory} />\n        {approvalHistory.length > 0 && (\n          <p className=\"border-separator-border text-text-secondary mt-4 border-t pt-3 text-xs\">\n            {approvalHistory.length} previous{\" \"}\n            {approvalHistory.length === 1 ? \"decision\" : \"decisions\"}\n          </p>\n        )}\n      </section>\n    )\n\n  const scope = request.parameters.scope\n  const target = request.parameters.target\n  const reversibility = request.parameters.reversibility\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full max-w-[620px] rounded-xl border p-5\",\n        className\n      )}\n    >\n      <header className=\"flex items-start justify-between gap-4\">\n        <div>\n          <p className=\"text-text-secondary flex items-center gap-2 text-xs\">\n            <Shield className=\"size-4\" />\n            Approval required\n          </p>\n          <h2 className=\"text-text-primary mt-2 text-lg font-semibold\">\n            {request.description}\n          </h2>\n        </div>\n        <span\n          className={cx(\n            \"rounded-sm border px-2 py-1 text-xs\",\n            request.riskLevel === \"high\"\n              ? \"border-red-400 text-red-700 dark:text-red-400\"\n              : request.riskLevel === \"medium\"\n                ? \"border-amber-400 text-amber-700 dark:text-amber-400\"\n                : \"border-separator-border text-text-secondary\"\n          )}\n        >\n          {riskLabel[request.riskLevel]}\n        </span>\n      </header>\n      <p className=\"border-separator-border text-text-secondary mt-4 border-l-2 pl-3 text-sm\">\n        Review the requested operation and supplied parameters before deciding.\n      </p>\n      <dl className=\"border-separator-border mt-5 grid grid-cols-[120px_1fr] gap-x-4 gap-y-2 border-y py-4 text-sm\">\n        <dt className=\"text-text-secondary\">Tool</dt>\n        <dd className=\"text-text-primary font-mono\">{request.toolName}</dd>\n        <dt className=\"text-text-secondary\">Scope</dt>\n        <dd>{scope ?? \"Not specified\"}</dd>\n        <dt className=\"text-text-secondary\">Target</dt>\n        <dd>{target ?? \"Not specified\"}</dd>\n        {reversibility !== undefined && (\n          <>\n            <dt className=\"text-text-secondary\">Reversibility</dt>\n            <dd>{reversibility}</dd>\n          </>\n        )}\n      </dl>\n      <div className=\"border-separator-border mt-4 overflow-hidden rounded-lg border\">\n        <p className=\"border-separator-border bg-background-secondary-default text-text-secondary border-b px-3 py-2 text-xs\">\n          Proposed parameters\n        </p>\n        {Object.entries(request.parameters).map(([key, value]) => (\n          <div\n            key={key}\n            className=\"border-separator-border grid grid-cols-[120px_1fr] gap-3 border-b px-3 py-2.5 text-sm last:border-0\"\n          >\n            <span className=\"text-text-secondary font-mono text-xs\">{key}</span>\n            <span className=\"text-text-primary break-words\">{value}</span>\n          </div>\n        ))}\n      </div>\n      <details className=\"group border-separator-border mt-3 border-b\">\n        <summary className=\"flex min-h-10 cursor-pointer list-none items-center justify-between text-sm font-medium\">\n          Why this action\n          <ChevronDown className=\"size-4 transition-transform group-open:rotate-180\" />\n        </summary>\n        <p className=\"text-text-secondary pb-3 text-sm leading-6\">\n          {request.reasoning}\n        </p>\n      </details>\n      <ResultAndHistory result={executionResult} history={approvalHistory} />\n      <div className=\"mt-5 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        {onAlwaysAllow ? (\n          <Checkbox isSelected={remember} onChange={setRemember} size=\"sm\">\n            Remember permission for this tool\n          </Checkbox>\n        ) : (\n          <span />\n        )}\n        <div className=\"flex justify-end gap-2\">\n          <Button variant=\"secondary\" onClick={onReject}>\n            Decline\n          </Button>\n          <Button\n            onClick={() => {\n              if (remember) onAlwaysAllow?.(request.toolName)\n              onApprove?.()\n            }}\n          >\n            {remember ? \"Always allow\" : \"Allow once\"}\n          </Button>\n        </div>\n      </div>\n      <p className=\"border-separator-border text-text-secondary mt-5 border-t pt-3 text-xs\">\n        {request.toolName} · {approvalHistory.length} previous{\" \"}\n        {approvalHistory.length === 1 ? \"decision\" : \"decisions\"}\n      </p>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/checkbox/checkbox.tsx",
          "target": "@components/boardui/base/checkbox/checkbox.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport { Checkbox as AriaCheckbox } from \"react-aria-components\";\nimport type { CheckboxProps as AriaCheckboxProps } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\nimport { CheckboxGlyph, checkboxSizes } from \"./checkbox-glyph\";\nimport type { CheckboxSize } from \"./checkbox-glyph\";\n\n/**\n * Figma source: Board UI → Checkbox (node 3699:2557 family; used in\n * dashboard 1 table, nodes 3731:3258 etc.).\n *\n * radius/sm (4px). Two sizes:\n *   md  16×16, label Body 1/Medium (14)\n *   sm  14×14, label Body 2/Medium (13)\n *\n * States (per Figma):\n *   default        bg background/primary/default, 1px border/checkbox/default,\n *                  shadow/xs\n *   hover          border darkens to neutral/400\n *   checked /      Button/Primary gradient (blue/500 → blue/600) with the\n *   indeterminate  checkbox inner highlight (see --shadow-checkbox-selected),\n *                  white 2px rounded stroke glyph; on hover the gradient\n *                  lightens to blue/400 → blue/500\n *\n * Built on react-aria Checkbox: keyboard toggling, aria-checked=\"mixed\" for\n * indeterminate, label association when `children` is passed.\n */\n\nexport interface CheckboxProps extends Omit<AriaCheckboxProps, \"children\"> {\n  children?: ReactNode;\n  size?: CheckboxSize;\n  ref?: Ref<HTMLLabelElement>;\n}\n\nexport function Checkbox({ className, children, size = \"md\", ref, ...props }: CheckboxProps) {\n  const s = checkboxSizes[size];\n\n  return (\n    <AriaCheckbox\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"group inline-flex items-center select-none\",\n          s.gap,\n          state.isDisabled ? \"cursor-not-allowed\" : \"cursor-pointer\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    >\n      {(state) => (\n        <>\n          <CheckboxGlyph state={state} size={size} />\n          {children !== undefined && children !== null && (\n            <span className={cx(s.label, \"text-text-primary\")}>{children}</span>\n          )}\n        </>\n      )}\n    </AriaCheckbox>\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/checkbox/checkbox-glyph.tsx",
          "target": "@components/boardui/base/checkbox/checkbox-glyph.tsx",
          "type": "registry:component",
          "content": "import { cx } from \"@/components/boardui/utils/cx\"\n\nexport type CheckboxSize = \"sm\" | \"md\"\n\nexport const checkboxSizes: Record<\n  CheckboxSize,\n  { box: string; glyph: string; label: string; gap: string }\n> = {\n  md: {\n    box: \"size-4\",\n    glyph: \"size-4\",\n    label: \"text-body-medium\",\n    gap: \"gap-2\",\n  },\n  sm: {\n    box: \"size-3.5\",\n    glyph: \"size-3.5\",\n    label: \"text-body-2-medium\",\n    gap: \"gap-1.5\",\n  },\n}\n\nexport interface CheckboxGlyphState {\n  isSelected: boolean\n  isIndeterminate: boolean\n  isFocusVisible: boolean\n  isDisabled: boolean\n  isHovered: boolean\n}\n\n/**\n * The 16px (or 14px) checkbox box + tick/indeterminate glyph. Shared by the\n * standalone Checkbox and the CheckboxCard so their visuals stay identical.\n */\nexport function CheckboxGlyph({\n  state,\n  size = \"md\",\n}: {\n  state: CheckboxGlyphState\n  size?: CheckboxSize\n}) {\n  const { isSelected, isIndeterminate, isFocusVisible, isDisabled, isHovered } =\n    state\n  const s = checkboxSizes[size]\n  const isMarked = isSelected || isIndeterminate\n  const hover = isHovered && !isDisabled\n\n  return (\n    <span\n      aria-hidden\n      className={cx(\n        \"flex shrink-0 items-center justify-center rounded-sm\",\n        \"ease transition-[background-color,border-color,box-shadow] duration-150\",\n        s.box,\n        isMarked\n          ? cx(\"bg-accent-500\", hover ? \"bg-accent-400\" : \"bg-accent-500\")\n          : cx(\n              \"bg-background-primary-default border shadow-xs\",\n              hover\n                ? \"border-border-checkbox-hover\"\n                : \"border-border-checkbox-default\"\n            ),\n        isDisabled && \"opacity-50\",\n        isFocusVisible && \"ring-border-focus-ring ring-2 ring-offset-2\"\n      )}\n    >\n      <svg viewBox=\"0 0 16 16\" fill=\"none\" className={s.glyph}>\n        {isIndeterminate ? (\n          <path\n            d=\"M4.5 8H8H11.5\"\n            stroke=\"white\"\n            strokeWidth=\"2\"\n            strokeLinecap=\"round\"\n          />\n        ) : isSelected ? (\n          <path\n            d=\"M4 7.7002L6.64645 10.3466C6.84171 10.5419 7.15829 10.5419 7.35355 10.3466L12 5.7002\"\n            stroke=\"white\"\n            strokeWidth=\"2\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n            pathLength={1}\n            className=\"animate-check-draw\"\n          />\n        ) : null}\n      </svg>\n    </span>\n  )\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-tool-palette",
      "type": "registry:block",
      "title": "Agent Tool Palette",
      "description": "agent tool palette",
      "dependencies": [
        "@remixicon/react@^4.9.0",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-tool-palette.tsx",
          "target": "@components/agents-ui/agent-tool-palette.tsx",
          "type": "registry:component",
          "content": "export {\n  AgentToolkit,\n  AgentToolPalette,\n} from \"./application/tool-palette/tool-palette\"\nexport type {\n  AgentTool,\n  AgentToolPaletteProps,\n  ToolCategory,\n} from \"./application/tool-palette/tool-palette\"\n"
        },
        {
          "path": "components/agents-ui/application/tool-palette/tool-palette.tsx",
          "target": "@components/agents-ui/application/tool-palette/tool-palette.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Input } from \"@/components/boardui/base/input/input\"\nimport {\n  Tab,\n  TabList,\n  TabPanel,\n  Tabs,\n} from \"@/components/boardui/base/tabs/tabs\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Search } from \"lucide-react\"\nimport { useMemo, useState } from \"react\"\n\nexport type ToolCategory =\n  | \"all\"\n  | \"data\"\n  | \"creative\"\n  | \"utility\"\n  | \"communication\"\nexport interface AgentTool {\n  id: string\n  name: string\n  description: string\n  category: ToolCategory\n  icon?: React.ReactNode\n  enabled?: boolean\n  usageCount?: number\n  lastUsed?: Date\n  parameters?: {\n    name: string\n    type: string\n    required: boolean\n    description?: string\n  }[]\n}\nexport interface AgentToolPaletteProps {\n  tools: AgentTool[]\n  onToolClick?: (tool: AgentTool) => void\n  onToolToggle?: (toolId: string, enabled: boolean) => void\n  showUsageStats?: boolean\n  gridView?: boolean\n  className?: string\n}\nconst categories: { id: ToolCategory; label: string }[] = [\n  { id: \"all\", label: \"All tools\" },\n  { id: \"data\", label: \"Data\" },\n  { id: \"creative\", label: \"Creative\" },\n  { id: \"utility\", label: \"Utility\" },\n  { id: \"communication\", label: \"Communication\" },\n]\nfunction lastUsed(date: Date) {\n  const hours = Math.floor((Date.now() - date.getTime()) / 3600000)\n  return hours < 1\n    ? \"Just now\"\n    : hours < 24\n      ? `${hours}h ago`\n      : `${Math.floor(hours / 24)}d ago`\n}\nfunction ToolRow({\n  tool,\n  grid,\n  usage,\n  onOpen,\n  onToggle,\n}: {\n  tool: AgentTool\n  grid: boolean\n  usage: boolean\n  onOpen?: () => void\n  onToggle?: () => void\n}) {\n  const enabled = tool.enabled !== false\n  return (\n    <article\n      className={cx(\n        \"border-separator-border flex min-w-0 gap-3 p-3\",\n        grid\n          ? \"flex-col rounded-lg border\"\n          : \"items-start border-b last:border-b-0\",\n        !enabled && \"opacity-60\"\n      )}\n    >\n      <button\n        type=\"button\"\n        disabled={!enabled}\n        onClick={onOpen}\n        className={cx(\"min-w-0 flex-1 text-left\", grid && \"w-full\")}\n      >\n        <div className=\"flex items-center gap-2\">\n          {tool.icon && (\n            <span className=\"text-text-secondary\">{tool.icon}</span>\n          )}\n          <h3 className=\"text-body-medium truncate\">{tool.name}</h3>\n          {!enabled && (\n            <span className=\"text-caption-1-medium text-text-secondary ml-auto\">\n              Disabled\n            </span>\n          )}\n        </div>\n        <p className=\"text-caption-1-regular text-text-secondary mt-1 leading-4\">\n          {tool.description}\n        </p>\n        {usage && (\n          <p className=\"text-caption-1-regular text-text-tertiary mt-2\">\n            {tool.usageCount ?? 0} uses\n            {tool.lastUsed ? `  |  ${lastUsed(tool.lastUsed)}` : \"\"}\n          </p>\n        )}\n        {tool.parameters && tool.parameters.length > 0 && (\n          <p className=\"text-caption-1-regular text-text-tertiary mt-2\">\n            {tool.parameters.length} parameters\n          </p>\n        )}\n      </button>\n      {onToggle && (\n        <Button size=\"small\" variant=\"secondary\" onClick={onToggle}>\n          {enabled ? \"Disable\" : \"Enable\"}\n        </Button>\n      )}\n    </article>\n  )\n}\nexport function AgentToolkit({\n  tools,\n  onToolClick,\n  onToolToggle,\n  showUsageStats = false,\n  gridView = true,\n  className,\n}: AgentToolPaletteProps) {\n  const [query, setQuery] = useState(\"\")\n  const [category, setCategory] = useState<ToolCategory>(\"all\")\n  const filtered = useMemo(\n    () =>\n      tools\n        .filter(\n          (tool) =>\n            (category === \"all\" || tool.category === category) &&\n            (!query ||\n              `${tool.name} ${tool.description}`\n                .toLowerCase()\n                .includes(query.toLowerCase()))\n        )\n        .sort(\n          (a, b) =>\n            Number(b.enabled !== false) - Number(a.enabled !== false) ||\n            (showUsageStats ? (b.usageCount ?? 0) - (a.usageCount ?? 0) : 0)\n        ),\n    [tools, query, category, showUsageStats]\n  )\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3\">\n        <div>\n          <h2 className=\"text-headline-semibold\">Available tools</h2>\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {tools.filter((tool) => tool.enabled !== false).length} enabled |{\" \"}\n            {tools.length} total\n          </p>\n        </div>\n        <div className=\"w-full sm:w-64\">\n          <Input\n            value={query}\n            onChange={setQuery}\n            placeholder=\"Search tools\"\n            leadingIcon={Search}\n          />\n        </div>\n      </header>\n      <Tabs\n        selectedKey={category}\n        onSelectionChange={(key) => setCategory(key as ToolCategory)}\n      >\n        <TabList className=\"overflow-x-auto px-2\">\n          {categories.map((item) => (\n            <Tab key={item.id} id={item.id}>\n              {item.label}\n            </Tab>\n          ))}\n        </TabList>\n        <TabPanel id={category} className=\"p-3\">\n          {filtered.length > 0 ? (\n            <div\n              className={cx(\n                gridView\n                  ? \"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\"\n                  : \"border-separator-border overflow-hidden rounded-lg border\"\n              )}\n            >\n              {filtered.map((tool) => (\n                <ToolRow\n                  key={tool.id}\n                  tool={tool}\n                  grid={gridView}\n                  usage={showUsageStats}\n                  onOpen={\n                    tool.enabled === false\n                      ? undefined\n                      : () => onToolClick?.(tool)\n                  }\n                  onToggle={\n                    onToolToggle\n                      ? () => onToolToggle(tool.id, tool.enabled === false)\n                      : undefined\n                  }\n                />\n              ))}\n            </div>\n          ) : (\n            <div className=\"grid min-h-40 place-items-center text-center\">\n              <div>\n                <p className=\"text-body-medium\">No tools found</p>\n                <p className=\"text-body-2-regular text-text-secondary mt-1\">\n                  Try another search or category.\n                </p>\n              </div>\n            </div>\n          )}\n        </TabPanel>\n      </Tabs>\n    </section>\n  )\n}\nexport const AgentToolPalette = AgentToolkit\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/input/input.tsx",
          "target": "@components/boardui/base/input/input.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  createContext,\n  useContext,\n  type ComponentType,\n  type ReactNode,\n  type Ref,\n} from \"react\";\nimport {\n  Group as AriaGroup,\n  Input as AriaInput,\n  TextField as AriaTextField,\n} from \"react-aria-components\";\nimport type {\n  InputProps as AriaInputProps,\n  TextFieldProps as AriaTextFieldProps,\n} from \"react-aria-components\";\nimport { Label } from \"./label\";\nimport { HintText } from \"./hint-text\";\nimport { cx, sortCx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Figma source: Board UI → Input (node 3665:1849).\n *\n * Architecture (mirrors the Untitled UI / React Aria pattern):\n *\n *   InputBase   - the styled field shell. Renders <AriaGroup> + adornments\n *                 + <AriaInput>. State (hover / focus / disabled / invalid)\n *                 arrives as render-prop booleans from Aria.\n *   TextField   - wraps <AriaTextField> and a TextFieldContext so size /\n *                 classes can flow from the composer down into InputBase\n *                 without prop drilling.\n *   Input       - opinionated composition: TextField → Label → InputBase\n *                 → HintText. The component most consumers use.\n *\n * Why React Aria:\n *   - Label ↔ input ↔ hint association via aria-labelledby / aria-describedby\n *   - aria-required, aria-invalid auto-applied\n *   - Form library / native validation integration\n *   - i18n, RTL, autofill edge cases handled\n *   - Render-prop state surfaces `isFocusWithin`, `isHovered`, `isDisabled`,\n *     `isInvalid`, `isRequired` - no CSS pseudo gymnastics\n *\n * Visuals stay 1:1 with Figma - see `styles/theme.css` for the tokens.\n */\n\ntype InputSize = \"medium\" | \"small\";\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\n/* -------------------------------------------------------------------------- */\n/*  TextFieldContext                                                           */\n/* -------------------------------------------------------------------------- */\n\ninterface TextFieldContextValue {\n  size?: InputSize;\n  fieldClassName?: string;\n  inputClassName?: string;\n}\n\nconst TextFieldContext = createContext<TextFieldContextValue>({});\n\n/* -------------------------------------------------------------------------- */\n/*  TextField                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface TextFieldProps\n  extends Omit<AriaTextFieldProps, \"className\">,\n    TextFieldContextValue {\n  className?: string;\n  children?: ReactNode | ((state: { isRequired: boolean; isInvalid: boolean; isDisabled: boolean; isReadOnly: boolean }) => ReactNode);\n}\n\nexport function TextField({\n  size = \"medium\",\n  fieldClassName,\n  inputClassName,\n  className,\n  children,\n  ...props\n}: TextFieldProps) {\n  return (\n    <TextFieldContext.Provider value={{ size, fieldClassName, inputClassName }}>\n      <AriaTextField\n        {...props}\n        data-input-size={size}\n        className={cx(\n          \"group flex h-max w-full flex-col items-start gap-1\",\n          className,\n        )}\n      >\n        {children as never /* RAC accepts render-prop children */}\n      </AriaTextField>\n    </TextFieldContext.Provider>\n  );\n}\n\nTextField.displayName = \"TextField\";\n\n/* -------------------------------------------------------------------------- */\n/*  InputBase                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputBaseProps extends Omit<AriaInputProps, \"size\" | \"className\"> {\n  size?: InputSize;\n  className?: string;\n  leadingIcon?: IconComponent;\n  trailingIcon?: IconComponent;\n  /** Custom element rendered in the leading slot (Phone basic uses this). */\n  leadingAddon?: ReactNode;\n  /** Class for the field shell. */\n  fieldClassName?: string;\n  /** Ref to the <input> element. */\n  ref?: Ref<HTMLInputElement>;\n  /** Ref to the field shell wrapper. */\n  groupRef?: Ref<HTMLDivElement>;\n}\n\nconst inputStyles = sortCx({\n  field: [\n    \"relative flex w-full items-center\",\n    \"rounded-2lg\",\n    \"bg-background-tertiary-default text-foreground-icon-tertiary\",\n    \"ring-2 ring-inset ring-transparent\",\n    \"transition-[background-color,box-shadow,color] duration-[var(--input-transition-ms)] ease\",\n  ].join(\" \"),\n\n  fieldSize: {\n    medium: \"p-2\",                // 8px all sides → h auto = 36\n    small:  \"h-8 px-1.5 py-2\",    // 32 / 6 / 8\n  },\n\n  // When a leadingAddon is present (Phone basic): tighten left padding.\n  fieldWithAddonSize: {\n    medium: \"h-9 pl-1 pr-2 py-2\", // 36 / 4 / 8 / 8\n    small:  \"h-8 pl-1 pr-1.5 py-2\",\n  },\n\n  content: \"flex w-full items-center gap-2 min-w-0\",\n  leftSection: \"flex flex-1 items-center gap-0.5 min-w-0\",\n\n  input: [\n    \"min-w-0 flex-1 bg-transparent border-0 outline-none p-0 m-0\",\n    \"font-sans text-body-regular text-text-primary pl-1\",\n    \"placeholder:text-text-tertiary\",\n    \"focus:placeholder:text-text-primary\",\n    \"disabled:text-input-disabled-text disabled:placeholder:text-input-disabled-text\",\n    \"disabled:cursor-not-allowed\",\n    \"aria-invalid:placeholder:text-text-error-placeholder\",\n  ].join(\" \"),\n\n  icon: \"size-5 shrink-0\",\n});\n\nexport function InputBase({\n  size: sizeProp,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  leadingAddon,\n  fieldClassName,\n  className,\n  ref,\n  groupRef,\n  ...inputProps\n}: InputBaseProps) {\n  const ctx = useContext(TextFieldContext);\n  const size: InputSize = sizeProp ?? ctx.size ?? \"medium\";\n  const hasAddon = leadingAddon !== undefined && leadingAddon !== null;\n\n  return (\n    <AriaGroup\n      ref={groupRef}\n      className={({ isFocusWithin, isHovered, isDisabled, isInvalid }) =>\n        cx(\n          inputStyles.field,\n          hasAddon\n            ? inputStyles.fieldWithAddonSize[size]\n            : inputStyles.fieldSize[size],\n          // Hover: idle, no focus, no disabled, no invalid\n          isHovered &&\n            !isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-hover\",\n          // Focus wins over hover\n          isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-active\",\n          // Disabled\n          isDisabled &&\n            \"bg-input-disabled-background text-input-disabled-foreground\",\n          // Invalid\n          isInvalid && \"bg-background-tertiary-error text-foreground-icon-error\",\n          ctx.fieldClassName,\n          fieldClassName,\n        )\n      }\n    >\n      <div className={inputStyles.content}>\n        <div className={inputStyles.leftSection}>\n          {hasAddon ? (\n            leadingAddon\n          ) : Leading ? (\n            <Leading className={inputStyles.icon} aria-hidden />\n          ) : null}\n          <AriaInput\n            ref={ref}\n            {...inputProps}\n            className={cx(inputStyles.input, ctx.inputClassName, className)}\n          />\n        </div>\n        {Trailing ? (\n          <Trailing className={inputStyles.icon} aria-hidden />\n        ) : null}\n      </div>\n    </AriaGroup>\n  );\n}\n\nInputBase.displayName = \"InputBase\";\n\n/* -------------------------------------------------------------------------- */\n/*  Input (composed)                                                           */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputProps\n  extends Omit<TextFieldProps, \"children\">,\n    Pick<\n      InputBaseProps,\n      | \"leadingIcon\"\n      | \"trailingIcon\"\n      | \"leadingAddon\"\n      | \"fieldClassName\"\n      | \"groupRef\"\n      | \"ref\"\n    > {\n  label?: ReactNode;\n  hint?: ReactNode;\n  /** Show an info icon next to the label. Replace with tooltip when Tooltip lands. */\n  tooltip?: boolean | string;\n  placeholder?: string;\n}\n\nexport function Input({\n  label,\n  hint,\n  tooltip,\n  placeholder,\n  leadingIcon,\n  trailingIcon,\n  leadingAddon,\n  fieldClassName,\n  ref,\n  groupRef,\n  className,\n  ...textFieldProps\n}: InputProps) {\n  return (\n    <TextField\n      {...textFieldProps}\n      className={className}\n      // Don't clobber an explicit aria-label; fall back to the placeholder\n      // only for unlabelled fields that don't provide one.\n      aria-label={\n        textFieldProps[\"aria-label\"] ??\n        (!label && typeof placeholder === \"string\" ? placeholder : undefined)\n      }\n    >\n      {({ isRequired, isInvalid }) => (\n        <>\n          {label && (\n            <Label\n              isRequired={isRequired}\n              isInvalid={isInvalid}\n              tooltip={tooltip}\n            >\n              {label}\n            </Label>\n          )}\n          <InputBase\n            ref={ref}\n            groupRef={groupRef}\n            placeholder={placeholder}\n            leadingIcon={leadingIcon}\n            trailingIcon={trailingIcon}\n            leadingAddon={leadingAddon}\n            fieldClassName={fieldClassName}\n          />\n          {hint && <HintText isInvalid={isInvalid}>{hint}</HintText>}\n        </>\n      )}\n    </TextField>\n  );\n}\n\nInput.displayName = \"Input\";\n"
        },
        {
          "path": "components/boardui/base/input/label.tsx",
          "target": "@components/boardui/base/input/label.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport { RiInformationFill } from \"@remixicon/react\";\nimport type { LabelProps as AriaLabelProps } from \"react-aria-components\";\nimport { Label as AriaLabel } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Field label. Wraps `react-aria-components`' Label so the parent `TextField`\n * automatically wires `htmlFor` / `aria-labelledby`.\n *\n * Visuals come from Figma:\n *   - Inter Medium 14/20, color text/primary\n *   - 2px gap between label + required asterisk + info icon\n *   - asterisk is text/error-primary (red/500)\n *   - info icon is 16×16 in foreground/icon/quaternary\n *\n * Pass `isRequired` to show the asterisk. Pass `tooltip` to show the info\n * icon (currently a static glyph - when the Tooltip component lands it'll\n * wire up here).\n */\n\nexport interface LabelProps extends AriaLabelProps {\n  children: ReactNode;\n  isRequired?: boolean;\n  /** Reserved for invalid-aware styling (asterisk color, etc.) once we need it. */\n  isInvalid?: boolean;\n  /** Show the info icon next to the label. */\n  tooltip?: boolean | string;\n  ref?: Ref<HTMLLabelElement>;\n}\n\nexport function Label({\n  isRequired = false,\n  isInvalid: _isInvalid,\n  tooltip,\n  className,\n  children,\n  ...props\n}: LabelProps) {\n  void _isInvalid;\n  return (\n    <AriaLabel\n      data-label=\"true\"\n      {...props}\n      className={cx(\n        \"flex cursor-default items-center gap-0.5\",\n        \"text-body-medium text-text-primary\",\n        className,\n      )}\n    >\n      {children}\n      {isRequired && (\n        <span\n          aria-hidden=\"true\"\n          className=\"text-body-medium text-text-error-primary\"\n        >\n          *\n        </span>\n      )}\n      {tooltip && (\n        <RiInformationFill\n          className=\"size-4 shrink-0 text-foreground-icon-quaternary\"\n          aria-hidden\n        />\n      )}\n    </AriaLabel>\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/input/hint-text.tsx",
          "target": "@components/boardui/base/input/hint-text.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport type { TextProps as AriaTextProps } from \"react-aria-components\";\nimport { Text as AriaText } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Caption text rendered below a field. Wraps `react-aria-components`' Text\n * so the parent `TextField` automatically wires `aria-describedby` (when\n * `slot=\"description\"`) or `aria-errormessage` (when `slot=\"errorMessage\"`).\n *\n * Visuals come from Figma:\n *   - Inter Medium 12/16, letter-spacing 0.15px\n *   - color text/secondary (default) or text/error-primary (invalid)\n *   - 1px top padding to align with the field's bottom edge\n */\n\nexport interface HintTextProps extends AriaTextProps {\n  children: ReactNode;\n  isInvalid?: boolean;\n  ref?: Ref<HTMLElement>;\n}\n\nexport function HintText({\n  isInvalid = false,\n  className,\n  ...props\n}: HintTextProps) {\n  return (\n    <AriaText\n      slot={isInvalid ? \"errorMessage\" : \"description\"}\n      {...props}\n      className={cx(\n        \"pt-px text-caption-1-medium text-text-secondary\",\n        isInvalid && \"text-text-error-primary\",\n        className,\n      )}\n    />\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/tabs/tabs.tsx",
          "target": "@components/boardui/base/tabs/tabs.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type { ComponentType, ReactNode, Ref } from \"react\";\nimport {\n  Tab as AriaTab,\n  TabList as AriaTabList,\n  TabPanel as AriaTabPanel,\n  Tabs as AriaTabs,\n} from \"react-aria-components\";\nimport type {\n  TabListProps as AriaTabListProps,\n  TabPanelProps as AriaTabPanelProps,\n  TabProps as AriaTabProps,\n  TabsProps as AriaTabsProps,\n} from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\nconst useIsomorphicLayoutEffect = typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Figma source: Board UI → Tab (node 3793:2942).\n *\n * Underline tabs. The tab strip sits on a 1px border/button/default baseline;\n * the active tab paints a 2px foreground underline over it.\n *   tab       px 10, py 8, gap 10 (label ↔ count), Body 1 (14/20)\n *     active     text/primary, Medium weight, 2px foreground underline\n *     inactive   text/primary, Regular weight, transparent underline\n *   count     radius/sm, px 4, py 1, Caption 1/Medium (12/16)\n *     active     selected count background, text/primary\n *     inactive   bg black/10 @ 50% opacity, text/primary\n *   icon      optional 16px leading glyph, inherits the label color\n *\n * Built on react-aria Tabs: roving-tabindex arrow-key navigation, automatic\n * activation, and TabList/TabPanel association.\n */\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\nexport interface TabsProps extends AriaTabsProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tabs({ className, ref, ...props }: TabsProps) {\n  return (\n    <AriaTabs\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"flex w-full flex-col gap-4\",\n          state.orientation === \"vertical\" && \"flex-row\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n\nexport interface TabListProps<T extends object> extends AriaTabListProps<T> {\n  ref?: Ref<HTMLDivElement>;\n}\n\ntype Underline = { left: number; width: number };\n\nexport function TabList<T extends object>({ className, ref, ...props }: TabListProps<T>) {\n  const wrapperRef = useRef<HTMLDivElement>(null);\n  const [underline, setUnderline] = useState<Underline | null>(null);\n\n  useIsomorphicLayoutEffect(() => {\n    const el = wrapperRef.current;\n    if (!el) return;\n    const measure = () => {\n      const selected = el.querySelector<HTMLElement>(\"[role='tab'][data-selected]\");\n      if (selected) {\n        setUnderline({ left: selected.offsetLeft, width: selected.offsetWidth });\n      }\n    };\n    measure();\n    // Re-measure when selection flips (data-selected toggles) or size changes.\n    const mo = new MutationObserver(measure);\n    mo.observe(el, { attributes: true, subtree: true, attributeFilter: [\"data-selected\"] });\n    const ro = new ResizeObserver(measure);\n    ro.observe(el);\n    return () => {\n      mo.disconnect();\n      ro.disconnect();\n    };\n  }, []);\n\n  return (\n    <div ref={wrapperRef} className=\"relative w-full\">\n      <AriaTabList\n        ref={ref}\n        {...props}\n        className={(state) =>\n          cx(\n            \"flex w-full items-center gap-1 border-b border-separator-border\",\n            typeof className === \"function\" ? className(state) : className,\n          )\n        }\n      />\n      {underline && (\n        <span\n          aria-hidden\n          className=\"pointer-events-none absolute bottom-0 left-0 h-0.5 bg-text-primary transition-[transform,width] duration-200 ease\"\n          style={{\n            transform: `translateX(${underline.left}px)`,\n            width: underline.width,\n          }}\n        />\n      )}\n    </div>\n  );\n}\n\nexport interface TabProps extends Omit<AriaTabProps, \"children\"> {\n  children?: ReactNode;\n  /** Optional leading icon (16px). Inherits the label color. */\n  icon?: IconComponent;\n  /** Optional trailing count badge. */\n  count?: ReactNode;\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Tab({ className, children, icon: Icon, count, ref, ...props }: TabProps) {\n  return (\n    <AriaTab\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"relative inline-flex cursor-pointer items-center gap-2.5 px-2.5 py-2 whitespace-nowrap\",\n          \"outline-none transition-colors duration-150 ease\",\n          \"focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          state.isDisabled && \"cursor-not-allowed opacity-50\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    >\n      {({ isSelected }) => (\n        <>\n          <span\n            className={cx(\n              \"inline-flex items-center gap-1.5\",\n              isSelected\n                ? \"text-body-medium text-text-primary\"\n                : \"text-body-regular text-text-primary\",\n            )}\n          >\n            {Icon && <Icon className=\"size-4 shrink-0\" aria-hidden />}\n            {children}\n          </span>\n          {count != null && (\n            <span\n              className={cx(\n                \"inline-flex items-center justify-center rounded-sm px-1 py-px text-caption-1-medium whitespace-nowrap\",\n                isSelected\n                  ? \"bg-tab-count-selected-background text-text-primary\"\n                  : \"bg-black/10 text-text-primary opacity-50\",\n              )}\n            >\n              {count}\n            </span>\n          )}\n        </>\n      )}\n    </AriaTab>\n  );\n}\n\nexport interface TabPanelProps extends AriaTabPanelProps {\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function TabPanel({ className, ref, ...props }: TabPanelProps) {\n  return (\n    <AriaTabPanel\n      ref={ref}\n      {...props}\n      className={(state) =>\n        cx(\n          \"outline-none focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-video-editor",
      "type": "registry:block",
      "title": "Agent Video Editor",
      "description": "agent video editor",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-video-editor.tsx",
          "target": "@components/agents-ui/agent-video-editor.tsx",
          "type": "registry:component",
          "content": "export { AgentVideoEditor } from \"./application/media/video-editor\"\nexport type {\n  AgentVideoEditorProps,\n  VideoClip,\n} from \"./application/media/video-editor\"\n"
        },
        {
          "path": "components/agents-ui/application/media/video-editor.tsx",
          "target": "@components/agents-ui/application/media/video-editor.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  Clock,\n  Copy,\n  Download,\n  Edit2,\n  Pause,\n  Play,\n  RefreshCw,\n  Scissors,\n  SkipBack,\n  SkipForward,\n  Video,\n} from \"lucide-react\"\nimport { useState } from \"react\"\n\nexport interface VideoClip {\n  id: string\n  name: string\n  duration: number\n  startTime: number\n  endTime: number\n  thumbnail?: string\n}\nexport interface AgentVideoEditorProps {\n  videoUrl?: string\n  isGenerating?: boolean\n  isPlaying?: boolean\n  currentTime?: number\n  duration?: number\n  clips?: VideoClip[]\n  onPlay?: () => void\n  onPause?: () => void\n  onSeek?: (time: number) => void\n  onSkipBack?: () => void\n  onSkipForward?: () => void\n  onExport?: (format?: \"mp4\" | \"mov\" | \"avi\") => void\n  onCopy?: () => void\n  onEdit?: () => void\n  onTrim?: () => void\n  onRegenerateResponse?: () => void\n  className?: string\n  timestamp?: string\n}\nconst time = (seconds: number) =>\n  `${Math.floor(seconds / 60)}:${Math.floor(seconds % 60)\n    .toString()\n    .padStart(2, \"0\")}`\n\nexport function AgentVideoEditor({\n  videoUrl,\n  isGenerating = false,\n  isPlaying = false,\n  currentTime = 12,\n  duration = 45,\n  clips = [],\n  onPlay,\n  onPause,\n  onSeek,\n  onSkipBack,\n  onSkipForward,\n  onExport,\n  onCopy,\n  onEdit,\n  onTrim,\n  onRegenerateResponse,\n  className,\n  timestamp = \"Just now\",\n}: AgentVideoEditorProps) {\n  const [isExporting, setIsExporting] = useState(false)\n  const handleExport = async () => {\n    if (!videoUrl || isGenerating || isExporting) return\n    setIsExporting(true)\n    try {\n      await onExport?.()\n    } finally {\n      setIsExporting(false)\n    }\n  }\n\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-wrap items-center justify-between gap-2 border-b px-4 py-3\">\n        <div>\n          <h3 className=\"text-headline-semibold\">Video output</h3>\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {isGenerating\n              ? \"Rendering video\"\n              : isExporting\n                ? \"Preparing export\"\n                : `${time(duration)}  |  ${clips.length} clips  |  ${timestamp}`}\n          </p>\n        </div>\n        <div className=\"flex gap-1\">\n          {onEdit && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Edit2}\n              onClick={onEdit}\n            >\n              Edit\n            </Button>\n          )}\n          {onTrim && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Scissors}\n              onClick={onTrim}\n            >\n              Trim\n            </Button>\n          )}\n          <Button\n            size=\"small\"\n            variant=\"secondary\"\n            leadingIcon={isExporting ? RefreshCw : Download}\n            onClick={handleExport}\n            disabled={!videoUrl || isGenerating || isExporting}\n          >\n            {isExporting ? \"Exporting\" : \"Export\"}\n          </Button>\n        </div>\n      </header>\n      <div className=\"bg-background-secondary-default p-4\">\n        <div className=\"relative aspect-video overflow-hidden rounded-lg bg-neutral-950\">\n          {videoUrl ? (\n            <video\n              src={videoUrl}\n              className=\"h-full w-full object-contain\"\n              aria-label=\"Video preview\"\n            />\n          ) : (\n            <div className=\"grid h-full place-items-center text-center text-neutral-400\">\n              <div>\n                <Video className=\"mx-auto size-8\" />\n                <p className=\"text-body-2-regular mt-2\">\n                  {isGenerating ? \"Rendering preview\" : \"No video available\"}\n                </p>\n              </div>\n            </div>\n          )}\n          {isGenerating && (\n            <div className=\"absolute inset-x-0 top-0 h-0.5 bg-neutral-800\">\n              <span className=\"block h-full w-1/2 animate-pulse bg-white\" />\n            </div>\n          )}\n        </div>\n      </div>\n      <div className=\"border-separator-border flex flex-wrap items-center gap-2 border-t px-4 py-3\">\n        <Button\n          size=\"small\"\n          variant=\"ghost\"\n          iconOnly\n          leadingIcon={SkipBack}\n          aria-label=\"Skip back\"\n          onClick={onSkipBack}\n        />\n        <Button\n          size=\"small\"\n          iconOnly\n          leadingIcon={isPlaying ? Pause : Play}\n          aria-label={isPlaying ? \"Pause video\" : \"Play video\"}\n          disabled={isGenerating || !videoUrl}\n          onClick={isPlaying ? onPause : onPlay}\n        />\n        <Button\n          size=\"small\"\n          variant=\"ghost\"\n          iconOnly\n          leadingIcon={SkipForward}\n          aria-label=\"Skip forward\"\n          onClick={onSkipForward}\n        />\n        <span className=\"text-caption-1-regular text-text-secondary tabular-nums\">\n          {time(currentTime)}\n        </span>\n        <input\n          type=\"range\"\n          min={0}\n          max={duration}\n          value={currentTime}\n          onChange={(event) => onSeek?.(Number(event.target.value))}\n          aria-label=\"Video position\"\n          className=\"min-w-32 flex-1 accent-blue-600\"\n        />\n        <span className=\"text-caption-1-regular text-text-secondary tabular-nums\">\n          {time(duration)}\n        </span>\n      </div>\n      {clips.length > 0 && (\n        <div className=\"border-separator-border border-t\">\n          <h4 className=\"text-caption-1-medium text-text-secondary px-4 pt-3 pb-1\">\n            Timeline\n          </h4>\n          {clips.map((clip) => (\n            <div\n              key={clip.id}\n              className=\"border-separator-border flex min-h-11 items-center gap-3 border-t px-4\"\n            >\n              <Clock className=\"text-text-tertiary size-4\" />\n              <span className=\"text-body-medium min-w-0 flex-1 truncate\">\n                {clip.name}\n              </span>\n              <span className=\"text-caption-1-regular text-text-secondary tabular-nums\">\n                {time(clip.startTime)} to {time(clip.endTime)}\n              </span>\n            </div>\n          ))}\n        </div>\n      )}\n      {(onCopy || onRegenerateResponse) && (\n        <footer className=\"border-separator-border flex gap-1 border-t px-3 py-2\">\n          {onCopy && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={Copy}\n              onClick={onCopy}\n            >\n              Copy\n            </Button>\n          )}\n          {onRegenerateResponse && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={RefreshCw}\n              onClick={onRegenerateResponse}\n            >\n              Regenerate\n            </Button>\n          )}\n        </footer>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-web-search",
      "type": "registry:block",
      "title": "Agent Web Search",
      "description": "agent web search",
      "dependencies": [
        "@remixicon/react@^4.9.0",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-web-search.tsx",
          "target": "@components/agents-ui/agent-web-search.tsx",
          "type": "registry:component",
          "content": "export { AgentWebSearch } from \"./application/web-search/web-search\"\nexport type {\n  AgentWebSearchProps,\n  SearchResult,\n} from \"./application/web-search/web-search\"\n"
        },
        {
          "path": "components/agents-ui/application/web-search/web-search.tsx",
          "target": "@components/agents-ui/application/web-search/web-search.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Input } from \"@/components/boardui/base/input/input\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  Calendar,\n  Copy,\n  ExternalLink,\n  Filter,\n  Globe,\n  RefreshCw,\n  Search,\n} from \"lucide-react\"\nimport { useState } from \"react\"\n\nexport interface SearchResult {\n  id: string\n  title: string\n  url: string\n  domain: string\n  snippet: string\n  aiSummary?: string\n  publishedDate?: string\n  credibilityScore?: number\n  relevanceScore?: number\n  imageUrl?: string\n}\nexport interface AgentWebSearchProps {\n  query?: string\n  results?: SearchResult[]\n  isSearching?: boolean\n  selectedDomains?: string[]\n  dateFilter?: \"all\" | \"day\" | \"week\" | \"month\" | \"year\"\n  onSearch?: (query: string) => void\n  onResultClick?: (result: SearchResult) => void\n  onCopyLink?: (url: string) => void\n  onDomainFilter?: (domains: string[]) => void\n  onDateFilter?: (filter: \"all\" | \"day\" | \"week\" | \"month\" | \"year\") => void\n  onRefresh?: () => void\n  showBottomActions?: boolean\n  className?: string\n  timestamp?: string\n}\nconst dateOptions = [\"all\", \"day\", \"week\", \"month\", \"year\"] as const\nexport function AgentWebSearch({\n  query = \"AI agent interfaces\",\n  results = [],\n  isSearching = false,\n  selectedDomains = [],\n  dateFilter = \"all\",\n  onSearch,\n  onResultClick,\n  onCopyLink,\n  onDomainFilter,\n  onDateFilter,\n  onRefresh,\n  showBottomActions = true,\n  className,\n  timestamp = \"2:34 PM\",\n}: AgentWebSearchProps) {\n  const [localQuery, setLocalQuery] = useState(query)\n  const [filtersOpen, setFiltersOpen] = useState(false)\n  const domains = Array.from(new Set(results.map((result) => result.domain)))\n  const toggleDomain = (domain: string) =>\n    onDomainFilter?.(\n      selectedDomains.includes(domain)\n        ? selectedDomains.filter((item) => item !== domain)\n        : [...selectedDomains, domain]\n    )\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-2xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border border-b p-3\">\n        <form\n          className=\"flex gap-2\"\n          onSubmit={(event) => {\n            event.preventDefault()\n            onSearch?.(localQuery)\n          }}\n        >\n          <Input\n            aria-label=\"Search query\"\n            value={localQuery}\n            onChange={setLocalQuery}\n            placeholder=\"Search the web\"\n            isDisabled={isSearching}\n            leadingIcon={Search}\n          />\n          <Button\n            type=\"submit\"\n            size=\"medium\"\n            disabled={isSearching || !localQuery.trim()}\n            leadingIcon={isSearching ? RefreshCw : undefined}\n          >\n            {isSearching ? \"Searching\" : \"Search\"}\n          </Button>\n          <Button\n            size=\"medium\"\n            variant=\"secondary\"\n            iconOnly\n            leadingIcon={Filter}\n            aria-label=\"Search filters\"\n            aria-expanded={filtersOpen}\n            onClick={() => setFiltersOpen((open) => !open)}\n          />\n        </form>\n        {filtersOpen && (\n          <div className=\"bg-background-secondary-default mt-3 grid gap-3 rounded-lg p-3 sm:grid-cols-2\">\n            <fieldset>\n              <legend className=\"text-caption-1-medium text-text-secondary mb-2\">\n                Date\n              </legend>\n              <div className=\"flex flex-wrap gap-1\">\n                {dateOptions.map((date) => (\n                  <Button\n                    key={date}\n                    size=\"small\"\n                    variant={dateFilter === date ? \"primary\" : \"ghost\"}\n                    onClick={() => onDateFilter?.(date)}\n                  >\n                    {date === \"all\" ? \"Any time\" : `Past ${date}`}\n                  </Button>\n                ))}\n              </div>\n            </fieldset>\n            {domains.length > 0 && (\n              <fieldset>\n                <legend className=\"text-caption-1-medium text-text-secondary mb-2\">\n                  Domains\n                </legend>\n                <div className=\"flex flex-wrap gap-1\">\n                  {domains.map((domain) => (\n                    <Button\n                      key={domain}\n                      size=\"small\"\n                      variant={\n                        selectedDomains.includes(domain) ? \"primary\" : \"ghost\"\n                      }\n                      onClick={() => toggleDomain(domain)}\n                    >\n                      {domain}\n                    </Button>\n                  ))}\n                </div>\n              </fieldset>\n            )}\n          </div>\n        )}\n      </header>\n      <div className=\"divide-separator-border divide-y\">\n        {isSearching ? (\n          <div className=\"text-body-2-regular text-text-secondary flex min-h-48 items-center justify-center gap-2\">\n            <RefreshCw className=\"size-4 animate-spin\" />\n            Searching the web\n          </div>\n        ) : (\n          results.map((result, index) => (\n            <article\n              key={result.id}\n              className=\"hover:bg-background-secondary-hover px-4 py-3\"\n            >\n              <div className=\"flex items-start gap-3\">\n                <span className=\"text-caption-1-regular text-text-tertiary pt-0.5 tabular-nums\">\n                  {index + 1}\n                </span>\n                <button\n                  type=\"button\"\n                  onClick={() => onResultClick?.(result)}\n                  className=\"min-w-0 flex-1 text-left\"\n                >\n                  <h3 className=\"text-body-medium\">{result.title}</h3>\n                  <p className=\"text-caption-1-regular text-text-secondary mt-0.5 flex flex-wrap gap-x-2\">\n                    <span className=\"inline-flex items-center gap-1\">\n                      <Globe className=\"size-3.5\" />\n                      {result.domain}\n                    </span>\n                    {result.publishedDate && (\n                      <span className=\"inline-flex items-center gap-1\">\n                        <Calendar className=\"size-3.5\" />\n                        {new Date(result.publishedDate).toLocaleDateString()}\n                      </span>\n                    )}\n                    {result.credibilityScore !== undefined && (\n                      <span>\n                        {Math.round(result.credibilityScore * 100)}% credibility\n                      </span>\n                    )}\n                    {result.relevanceScore !== undefined && (\n                      <span>\n                        {Math.round(result.relevanceScore * 100)}% relevance\n                      </span>\n                    )}\n                  </p>\n                  <p className=\"text-body-2-regular text-text-secondary mt-2 leading-5\">\n                    {result.snippet}\n                  </p>\n                  {result.aiSummary && (\n                    <p className=\"border-separator-border text-body-2-regular mt-2 border-l pl-3 leading-5\">\n                      {result.aiSummary}\n                    </p>\n                  )}\n                </button>\n                <div className=\"flex gap-1\">\n                  <Button\n                    size=\"small\"\n                    variant=\"ghost\"\n                    iconOnly\n                    leadingIcon={ExternalLink}\n                    aria-label={`Open ${result.title}`}\n                    onClick={() =>\n                      window.open(result.url, \"_blank\", \"noopener,noreferrer\")\n                    }\n                  />\n                  {onCopyLink && (\n                    <Button\n                      size=\"small\"\n                      variant=\"ghost\"\n                      iconOnly\n                      leadingIcon={Copy}\n                      aria-label={`Copy ${result.title} link`}\n                      onClick={() => onCopyLink(result.url)}\n                    />\n                  )}\n                </div>\n              </div>\n            </article>\n          ))\n        )}\n        {!isSearching && results.length === 0 && (\n          <div className=\"grid min-h-48 place-items-center p-8 text-center\">\n            <div>\n              <p className=\"text-body-medium\">No search results</p>\n              <p className=\"text-body-2-regular text-text-secondary mt-1\">\n                Run a search to view sources.\n              </p>\n            </div>\n          </div>\n        )}\n      </div>\n      {showBottomActions && (\n        <footer className=\"border-separator-border flex items-center justify-between gap-3 border-t px-4 py-2.5\">\n          <p className=\"text-caption-1-regular text-text-secondary\">\n            {results.length} results | Updated {timestamp}\n          </p>\n          {onRefresh && (\n            <Button\n              size=\"small\"\n              variant=\"ghost\"\n              leadingIcon={RefreshCw}\n              onClick={onRefresh}\n            >\n              Refresh\n            </Button>\n          )}\n        </footer>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/input/input.tsx",
          "target": "@components/boardui/base/input/input.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  createContext,\n  useContext,\n  type ComponentType,\n  type ReactNode,\n  type Ref,\n} from \"react\";\nimport {\n  Group as AriaGroup,\n  Input as AriaInput,\n  TextField as AriaTextField,\n} from \"react-aria-components\";\nimport type {\n  InputProps as AriaInputProps,\n  TextFieldProps as AriaTextFieldProps,\n} from \"react-aria-components\";\nimport { Label } from \"./label\";\nimport { HintText } from \"./hint-text\";\nimport { cx, sortCx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Figma source: Board UI → Input (node 3665:1849).\n *\n * Architecture (mirrors the Untitled UI / React Aria pattern):\n *\n *   InputBase   - the styled field shell. Renders <AriaGroup> + adornments\n *                 + <AriaInput>. State (hover / focus / disabled / invalid)\n *                 arrives as render-prop booleans from Aria.\n *   TextField   - wraps <AriaTextField> and a TextFieldContext so size /\n *                 classes can flow from the composer down into InputBase\n *                 without prop drilling.\n *   Input       - opinionated composition: TextField → Label → InputBase\n *                 → HintText. The component most consumers use.\n *\n * Why React Aria:\n *   - Label ↔ input ↔ hint association via aria-labelledby / aria-describedby\n *   - aria-required, aria-invalid auto-applied\n *   - Form library / native validation integration\n *   - i18n, RTL, autofill edge cases handled\n *   - Render-prop state surfaces `isFocusWithin`, `isHovered`, `isDisabled`,\n *     `isInvalid`, `isRequired` - no CSS pseudo gymnastics\n *\n * Visuals stay 1:1 with Figma - see `styles/theme.css` for the tokens.\n */\n\ntype InputSize = \"medium\" | \"small\";\n\ntype IconComponent = ComponentType<{\n  className?: string;\n  \"aria-hidden\"?: boolean | \"true\" | \"false\";\n}>;\n\n/* -------------------------------------------------------------------------- */\n/*  TextFieldContext                                                           */\n/* -------------------------------------------------------------------------- */\n\ninterface TextFieldContextValue {\n  size?: InputSize;\n  fieldClassName?: string;\n  inputClassName?: string;\n}\n\nconst TextFieldContext = createContext<TextFieldContextValue>({});\n\n/* -------------------------------------------------------------------------- */\n/*  TextField                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface TextFieldProps\n  extends Omit<AriaTextFieldProps, \"className\">,\n    TextFieldContextValue {\n  className?: string;\n  children?: ReactNode | ((state: { isRequired: boolean; isInvalid: boolean; isDisabled: boolean; isReadOnly: boolean }) => ReactNode);\n}\n\nexport function TextField({\n  size = \"medium\",\n  fieldClassName,\n  inputClassName,\n  className,\n  children,\n  ...props\n}: TextFieldProps) {\n  return (\n    <TextFieldContext.Provider value={{ size, fieldClassName, inputClassName }}>\n      <AriaTextField\n        {...props}\n        data-input-size={size}\n        className={cx(\n          \"group flex h-max w-full flex-col items-start gap-1\",\n          className,\n        )}\n      >\n        {children as never /* RAC accepts render-prop children */}\n      </AriaTextField>\n    </TextFieldContext.Provider>\n  );\n}\n\nTextField.displayName = \"TextField\";\n\n/* -------------------------------------------------------------------------- */\n/*  InputBase                                                                  */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputBaseProps extends Omit<AriaInputProps, \"size\" | \"className\"> {\n  size?: InputSize;\n  className?: string;\n  leadingIcon?: IconComponent;\n  trailingIcon?: IconComponent;\n  /** Custom element rendered in the leading slot (Phone basic uses this). */\n  leadingAddon?: ReactNode;\n  /** Class for the field shell. */\n  fieldClassName?: string;\n  /** Ref to the <input> element. */\n  ref?: Ref<HTMLInputElement>;\n  /** Ref to the field shell wrapper. */\n  groupRef?: Ref<HTMLDivElement>;\n}\n\nconst inputStyles = sortCx({\n  field: [\n    \"relative flex w-full items-center\",\n    \"rounded-2lg\",\n    \"bg-background-tertiary-default text-foreground-icon-tertiary\",\n    \"ring-2 ring-inset ring-transparent\",\n    \"transition-[background-color,box-shadow,color] duration-[var(--input-transition-ms)] ease\",\n  ].join(\" \"),\n\n  fieldSize: {\n    medium: \"p-2\",                // 8px all sides → h auto = 36\n    small:  \"h-8 px-1.5 py-2\",    // 32 / 6 / 8\n  },\n\n  // When a leadingAddon is present (Phone basic): tighten left padding.\n  fieldWithAddonSize: {\n    medium: \"h-9 pl-1 pr-2 py-2\", // 36 / 4 / 8 / 8\n    small:  \"h-8 pl-1 pr-1.5 py-2\",\n  },\n\n  content: \"flex w-full items-center gap-2 min-w-0\",\n  leftSection: \"flex flex-1 items-center gap-0.5 min-w-0\",\n\n  input: [\n    \"min-w-0 flex-1 bg-transparent border-0 outline-none p-0 m-0\",\n    \"font-sans text-body-regular text-text-primary pl-1\",\n    \"placeholder:text-text-tertiary\",\n    \"focus:placeholder:text-text-primary\",\n    \"disabled:text-input-disabled-text disabled:placeholder:text-input-disabled-text\",\n    \"disabled:cursor-not-allowed\",\n    \"aria-invalid:placeholder:text-text-error-placeholder\",\n  ].join(\" \"),\n\n  icon: \"size-5 shrink-0\",\n});\n\nexport function InputBase({\n  size: sizeProp,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  leadingAddon,\n  fieldClassName,\n  className,\n  ref,\n  groupRef,\n  ...inputProps\n}: InputBaseProps) {\n  const ctx = useContext(TextFieldContext);\n  const size: InputSize = sizeProp ?? ctx.size ?? \"medium\";\n  const hasAddon = leadingAddon !== undefined && leadingAddon !== null;\n\n  return (\n    <AriaGroup\n      ref={groupRef}\n      className={({ isFocusWithin, isHovered, isDisabled, isInvalid }) =>\n        cx(\n          inputStyles.field,\n          hasAddon\n            ? inputStyles.fieldWithAddonSize[size]\n            : inputStyles.fieldSize[size],\n          // Hover: idle, no focus, no disabled, no invalid\n          isHovered &&\n            !isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-hover\",\n          // Focus wins over hover\n          isFocusWithin &&\n            !isDisabled &&\n            !isInvalid &&\n            \"ring-border-button-active\",\n          // Disabled\n          isDisabled &&\n            \"bg-input-disabled-background text-input-disabled-foreground\",\n          // Invalid\n          isInvalid && \"bg-background-tertiary-error text-foreground-icon-error\",\n          ctx.fieldClassName,\n          fieldClassName,\n        )\n      }\n    >\n      <div className={inputStyles.content}>\n        <div className={inputStyles.leftSection}>\n          {hasAddon ? (\n            leadingAddon\n          ) : Leading ? (\n            <Leading className={inputStyles.icon} aria-hidden />\n          ) : null}\n          <AriaInput\n            ref={ref}\n            {...inputProps}\n            className={cx(inputStyles.input, ctx.inputClassName, className)}\n          />\n        </div>\n        {Trailing ? (\n          <Trailing className={inputStyles.icon} aria-hidden />\n        ) : null}\n      </div>\n    </AriaGroup>\n  );\n}\n\nInputBase.displayName = \"InputBase\";\n\n/* -------------------------------------------------------------------------- */\n/*  Input (composed)                                                           */\n/* -------------------------------------------------------------------------- */\n\nexport interface InputProps\n  extends Omit<TextFieldProps, \"children\">,\n    Pick<\n      InputBaseProps,\n      | \"leadingIcon\"\n      | \"trailingIcon\"\n      | \"leadingAddon\"\n      | \"fieldClassName\"\n      | \"groupRef\"\n      | \"ref\"\n    > {\n  label?: ReactNode;\n  hint?: ReactNode;\n  /** Show an info icon next to the label. Replace with tooltip when Tooltip lands. */\n  tooltip?: boolean | string;\n  placeholder?: string;\n}\n\nexport function Input({\n  label,\n  hint,\n  tooltip,\n  placeholder,\n  leadingIcon,\n  trailingIcon,\n  leadingAddon,\n  fieldClassName,\n  ref,\n  groupRef,\n  className,\n  ...textFieldProps\n}: InputProps) {\n  return (\n    <TextField\n      {...textFieldProps}\n      className={className}\n      // Don't clobber an explicit aria-label; fall back to the placeholder\n      // only for unlabelled fields that don't provide one.\n      aria-label={\n        textFieldProps[\"aria-label\"] ??\n        (!label && typeof placeholder === \"string\" ? placeholder : undefined)\n      }\n    >\n      {({ isRequired, isInvalid }) => (\n        <>\n          {label && (\n            <Label\n              isRequired={isRequired}\n              isInvalid={isInvalid}\n              tooltip={tooltip}\n            >\n              {label}\n            </Label>\n          )}\n          <InputBase\n            ref={ref}\n            groupRef={groupRef}\n            placeholder={placeholder}\n            leadingIcon={leadingIcon}\n            trailingIcon={trailingIcon}\n            leadingAddon={leadingAddon}\n            fieldClassName={fieldClassName}\n          />\n          {hint && <HintText isInvalid={isInvalid}>{hint}</HintText>}\n        </>\n      )}\n    </TextField>\n  );\n}\n\nInput.displayName = \"Input\";\n"
        },
        {
          "path": "components/boardui/base/input/label.tsx",
          "target": "@components/boardui/base/input/label.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport { RiInformationFill } from \"@remixicon/react\";\nimport type { LabelProps as AriaLabelProps } from \"react-aria-components\";\nimport { Label as AriaLabel } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Field label. Wraps `react-aria-components`' Label so the parent `TextField`\n * automatically wires `htmlFor` / `aria-labelledby`.\n *\n * Visuals come from Figma:\n *   - Inter Medium 14/20, color text/primary\n *   - 2px gap between label + required asterisk + info icon\n *   - asterisk is text/error-primary (red/500)\n *   - info icon is 16×16 in foreground/icon/quaternary\n *\n * Pass `isRequired` to show the asterisk. Pass `tooltip` to show the info\n * icon (currently a static glyph - when the Tooltip component lands it'll\n * wire up here).\n */\n\nexport interface LabelProps extends AriaLabelProps {\n  children: ReactNode;\n  isRequired?: boolean;\n  /** Reserved for invalid-aware styling (asterisk color, etc.) once we need it. */\n  isInvalid?: boolean;\n  /** Show the info icon next to the label. */\n  tooltip?: boolean | string;\n  ref?: Ref<HTMLLabelElement>;\n}\n\nexport function Label({\n  isRequired = false,\n  isInvalid: _isInvalid,\n  tooltip,\n  className,\n  children,\n  ...props\n}: LabelProps) {\n  void _isInvalid;\n  return (\n    <AriaLabel\n      data-label=\"true\"\n      {...props}\n      className={cx(\n        \"flex cursor-default items-center gap-0.5\",\n        \"text-body-medium text-text-primary\",\n        className,\n      )}\n    >\n      {children}\n      {isRequired && (\n        <span\n          aria-hidden=\"true\"\n          className=\"text-body-medium text-text-error-primary\"\n        >\n          *\n        </span>\n      )}\n      {tooltip && (\n        <RiInformationFill\n          className=\"size-4 shrink-0 text-foreground-icon-quaternary\"\n          aria-hidden\n        />\n      )}\n    </AriaLabel>\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/input/hint-text.tsx",
          "target": "@components/boardui/base/input/hint-text.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport type { ReactNode, Ref } from \"react\";\nimport type { TextProps as AriaTextProps } from \"react-aria-components\";\nimport { Text as AriaText } from \"react-aria-components\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Caption text rendered below a field. Wraps `react-aria-components`' Text\n * so the parent `TextField` automatically wires `aria-describedby` (when\n * `slot=\"description\"`) or `aria-errormessage` (when `slot=\"errorMessage\"`).\n *\n * Visuals come from Figma:\n *   - Inter Medium 12/16, letter-spacing 0.15px\n *   - color text/secondary (default) or text/error-primary (invalid)\n *   - 1px top padding to align with the field's bottom edge\n */\n\nexport interface HintTextProps extends AriaTextProps {\n  children: ReactNode;\n  isInvalid?: boolean;\n  ref?: Ref<HTMLElement>;\n}\n\nexport function HintText({\n  isInvalid = false,\n  className,\n  ...props\n}: HintTextProps) {\n  return (\n    <AriaText\n      slot={isInvalid ? \"errorMessage\" : \"description\"}\n      {...props}\n      className={cx(\n        \"pt-px text-caption-1-medium text-text-secondary\",\n        isInvalid && \"text-text-error-primary\",\n        className,\n      )}\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "agent-workflow-planner",
      "type": "registry:block",
      "title": "Agent Workflow Planner",
      "description": "agent workflow planner",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/agents-ui/agent-workflow-planner.tsx",
          "target": "@components/agents-ui/agent-workflow-planner.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { WorkflowPlanner } from \"@/components/agents-ui/application/workflow-planner/workflow-planner\"\nimport type { AgentWorkflowPlannerProps } from \"@/components/agents-ui/application/workflow-planner/workflow-planner\"\nimport { createElement } from \"react\"\n\nexport type {\n  ActionItem,\n  AgentWorkflowPlannerProps,\n  WorkflowCheckpoint,\n  WorkflowPlaybook,\n} from \"@/components/agents-ui/application/workflow-planner/workflow-planner\"\nexport function AgentWorkflowPlanner(props: AgentWorkflowPlannerProps) {\n  return createElement(WorkflowPlanner, props)\n}\n"
        },
        {
          "path": "components/agents-ui/application/workflow-planner/workflow-planner.tsx",
          "target": "@components/agents-ui/application/workflow-planner/workflow-planner.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDown, RefreshCw } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport interface WorkflowCheckpoint {\n  id: string\n  title: string\n  owner: string\n  eta: string\n  status: \"upcoming\" | \"active\" | \"done\"\n  notes?: string\n}\nexport interface WorkflowPlaybook {\n  label: string\n  description: string\n  tasks: string[]\n  handoff?: string\n}\nexport interface ActionItem {\n  id: string\n  label: string\n  detail: string\n  type: \"agent\" | \"human\"\n}\nexport interface AgentWorkflowPlannerProps {\n  programName?: string\n  timeframe?: string\n  checkpoints?: WorkflowCheckpoint[]\n  playbooks?: WorkflowPlaybook[]\n  nextActions?: ActionItem[]\n  onReplan?: () => void\n  onAcknowledge?: (item: ActionItem) => void\n  className?: string\n}\nconst checkpointDefaults: WorkflowCheckpoint[] = [\n  {\n    id: \"scope\",\n    title: \"Confirm requirements\",\n    owner: \"Product team\",\n    eta: \"Due today\",\n    status: \"done\",\n    notes: \"Validated against customer requests\",\n  },\n  {\n    id: \"design\",\n    title: \"Review design handoff\",\n    owner: \"Design team\",\n    eta: \"12:30 PM\",\n    status: \"active\",\n    notes: \"Review updated interaction notes\",\n  },\n  {\n    id: \"enablement\",\n    title: \"Prepare enablement\",\n    owner: \"Operations\",\n    eta: \"Tomorrow\",\n    status: \"upcoming\",\n    notes: \"Prepare launch documentation\",\n  },\n]\nconst playbookDefaults: WorkflowPlaybook[] = [\n  {\n    label: \"Agent onboarding\",\n    description: \"Configure and validate a new agent\",\n    tasks: [\n      \"Provision credentials\",\n      \"Sync policies\",\n      \"Validate prompt behavior\",\n    ],\n    handoff: \"Human quality review\",\n  },\n  {\n    label: \"Lifecycle announcement\",\n    description: \"Prepare and schedule product communication\",\n    tasks: [\"Draft copy\", \"Review localization\", \"Schedule rollout\"],\n  },\n]\nconst actionDefaults: ActionItem[] = [\n  {\n    id: \"design\",\n    label: \"Upload annotated design document\",\n    detail: \"The review is waiting for updated callouts\",\n    type: \"human\",\n  },\n  {\n    id: \"pricing\",\n    label: \"Approve pricing adjustments\",\n    detail: \"Three options are ready for review\",\n    type: \"human\",\n  },\n  {\n    id: \"email\",\n    label: \"Generate onboarding email\",\n    detail: \"A copy draft is queued\",\n    type: \"agent\",\n  },\n]\nconst statusText: Record<WorkflowCheckpoint[\"status\"], string> = {\n  upcoming: \"Upcoming\",\n  active: \"Active\",\n  done: \"Complete\",\n}\nconst statusTone: Record<WorkflowCheckpoint[\"status\"], string> = {\n  upcoming: \"text-text-secondary\",\n  active: \"text-accent-600\",\n  done: \"text-green-600\",\n}\nexport function WorkflowPlanner({\n  programName = \"Launch readiness\",\n  timeframe = \"Week of March 17\",\n  checkpoints = checkpointDefaults,\n  playbooks = playbookDefaults,\n  nextActions = actionDefaults,\n  onReplan,\n  onAcknowledge,\n  className,\n}: AgentWorkflowPlannerProps) {\n  const [expanded, setExpanded] = React.useState<string | undefined>(\n    playbooks[0]?.label\n  )\n  return (\n    <section\n      className={cn(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-start sm:justify-between\">\n        <div>\n          <p className=\"text-text-secondary text-xs font-medium\">{timeframe}</p>\n          <h2 className=\"text-text-primary mt-1 text-lg font-semibold\">\n            {programName}\n          </h2>\n          <p className=\"text-text-secondary mt-1 text-sm\">\n            Review milestones, reusable procedures, and the next required\n            decisions.\n          </p>\n        </div>\n        <Button\n          size=\"small\"\n          variant=\"secondary\"\n          leadingIcon={RefreshCw}\n          onClick={onReplan}\n        >\n          Replan\n        </Button>\n      </header>\n      <div>\n        {checkpoints.map((item, index) => (\n          <article\n            key={item.id}\n            className=\"border-separator-border grid grid-cols-[2rem_1fr_auto] gap-3 border-b px-4 py-3\"\n          >\n            <span className=\"text-text-secondary text-xs\">\n              {String(index + 1).padStart(2, \"0\")}\n            </span>\n            <div>\n              <div className=\"flex flex-wrap gap-x-3\">\n                <h3 className=\"text-text-primary text-sm font-medium\">\n                  {item.title}\n                </h3>\n                <span className={cn(\"text-xs\", statusTone[item.status])}>\n                  {statusText[item.status]}\n                </span>\n              </div>\n              <p className=\"text-text-secondary mt-1 text-xs\">{item.notes}</p>\n            </div>\n            <div className=\"text-right text-xs\">\n              <p className=\"text-text-primary\">{item.owner}</p>\n              <p className=\"text-text-secondary mt-1\">{item.eta}</p>\n            </div>\n          </article>\n        ))}\n      </div>\n      <div className=\"grid lg:grid-cols-2\">\n        <div className=\"border-separator-border border-b p-4 lg:border-r lg:border-b-0\">\n          <p className=\"text-text-primary text-sm font-medium\">Playbooks</p>\n          <div className=\"divide-separator-border bg-background-secondary-default mt-3 divide-y rounded-lg px-3\">\n            {playbooks.map((playbook) => (\n              <div key={playbook.label}>\n                <button\n                  type=\"button\"\n                  className=\"flex w-full items-center justify-between gap-3 py-2.5 text-left\"\n                  aria-expanded={expanded === playbook.label}\n                  onClick={() =>\n                    setExpanded(\n                      expanded === playbook.label ? undefined : playbook.label\n                    )\n                  }\n                >\n                  <span>\n                    <strong className=\"text-text-primary block text-xs font-medium\">\n                      {playbook.label}\n                    </strong>\n                    <span className=\"text-text-secondary mt-1 block text-xs\">\n                      {playbook.description}\n                    </span>\n                  </span>\n                  <ChevronDown\n                    className={cn(\n                      \"text-text-secondary size-3.5\",\n                      expanded === playbook.label && \"rotate-180\"\n                    )}\n                  />\n                </button>\n                {expanded === playbook.label && (\n                  <div className=\"pb-3\">\n                    <ol className=\"text-text-secondary space-y-1.5 text-xs\">\n                      {playbook.tasks.map((task, index) => (\n                        <li key={task}>\n                          {index + 1}. {task}\n                        </li>\n                      ))}\n                    </ol>\n                    {playbook.handoff && (\n                      <p className=\"border-separator-border text-text-secondary mt-2 border-t pt-2 text-xs\">\n                        Handoff: {playbook.handoff}\n                      </p>\n                    )}\n                  </div>\n                )}\n              </div>\n            ))}\n          </div>\n        </div>\n        <div className=\"p-4\">\n          <p className=\"text-text-primary text-sm font-medium\">Next actions</p>\n          <div className=\"divide-separator-border mt-3 divide-y\">\n            {nextActions.map((item) => (\n              <div key={item.id} className=\"flex items-start gap-3 py-2.5\">\n                <div className=\"min-w-0 flex-1\">\n                  <p className=\"text-text-primary text-xs font-medium\">\n                    {item.label}\n                  </p>\n                  <p className=\"text-text-secondary mt-1 text-xs\">\n                    {item.detail}\n                  </p>\n                </div>\n                <Button\n                  size=\"xs\"\n                  variant=\"secondary\"\n                  onClick={() => onAcknowledge?.(item)}\n                >\n                  {item.type === \"human\" ? \"Review\" : \"Start\"}\n                </Button>\n              </div>\n            ))}\n          </div>\n        </div>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/agents-ui/LICENSE.md",
          "target": "@components/agents-ui/LICENSE.md",
          "type": "registry:file",
          "content": "Non-Commercial License\n======================\n\nCopyright (c) 2025 Abhishek Gahlot\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use, copy, modify, merge, publish, and distribute the Software for **non-commercial purposes only**, subject to the following conditions:\n\n1. Commercial Use Prohibited\n   --------------------------\n   The Software may not be used, in whole or in part, for any commercial purpose without prior written permission. Commercial use includes (but is not limited to) selling access to the Software, incorporating the Software into products or services offered for a fee, or using the Software within a commercial SaaS product.\n\n2. Attribution\n   -----------\n   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n3. Warranty Disclaimer\n   --------------------\n   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nCommercial Licensing\n--------------------\n\nFor commercial licensing, partnership discussions, or private support, please contact:\n\n**Email:** me@abhishek.it\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Agents Kit"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "blocks-so-ai-01",
      "type": "registry:block",
      "title": "Blocks So Ai 01",
      "description": "ai 01",
      "dependencies": [
        "@radix-ui/react-dropdown-menu@^2.1.14",
        "@radix-ui/react-slot@^1.2.2",
        "@tabler/icons-react@3.34.1",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/ai-01.tsx",
          "target": "@components/blocks-so/ai-01.tsx",
          "type": "registry:component",
          "content": "export { BlocksAi01, type BlocksAi01Props } from \"./ai/ai-01\"\nexport { default } from \"./ai/ai-01\"\n"
        },
        {
          "path": "components/blocks-so/ai/ai-01.tsx",
          "target": "@components/blocks-so/ai/ai-01.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n// Adapted from Blocks ai-01 (MIT), pinned in components/blocks-so/SOURCE.json.\nimport {\n  IconMicrophone,\n  IconPaperclip,\n  IconPlus,\n  IconSearch,\n  IconSend,\n  IconSparkles,\n  IconWaveSine,\n} from \"@tabler/icons-react\"\nimport * as React from \"react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { Textarea } from \"@/components/ui/textarea\"\nimport { cn } from \"@/lib/utils\"\n\nexport type BlocksAi01Props = {\n  className?: string\n  onFilesSelected?: (files: File[]) => void\n  onModeChange?: (mode: \"agent\" | \"research\") => void\n  onSubmit?: (message: string) => void\n  title?: string\n}\n\nexport function BlocksAi01({\n  className,\n  onFilesSelected,\n  onModeChange,\n  onSubmit,\n  title = \"What should we investigate?\",\n}: BlocksAi01Props) {\n  const [message, setMessage] = React.useState(\"\")\n  const [expanded, setExpanded] = React.useState(false)\n  const textareaRef = React.useRef<HTMLTextAreaElement>(null)\n  const fileInputRef = React.useRef<HTMLInputElement>(null)\n\n  const send = () => {\n    const value = message.trim()\n    if (!value) return\n    onSubmit?.(value)\n    setMessage(\"\")\n    setExpanded(false)\n    if (textareaRef.current) textareaRef.current.style.height = \"auto\"\n  }\n\n  return (\n    <div className={cn(\"w-full\", className)} data-blocks-ai=\"ai-01\">\n      <h2 className=\"mx-auto mb-4 max-w-2xl text-balance text-center text-xl leading-tight font-medium tracking-tight\">\n        {title}\n      </h2>\n      <form\n        className=\"group/composer w-full\"\n        onSubmit={(event) => {\n          event.preventDefault()\n          send()\n        }}\n      >\n        <input\n          className=\"sr-only\"\n          multiple\n          onChange={(event) => {\n            const files = Array.from(event.currentTarget.files ?? [])\n            if (files.length) onFilesSelected?.(files)\n            event.currentTarget.value = \"\"\n          }}\n          ref={fileInputRef}\n          type=\"file\"\n        />\n        <div\n          className={cn(\n            \"mx-auto w-full max-w-2xl cursor-text overflow-clip bg-background bg-clip-padding p-2.5 shadow-[0_0_0_1px_oklch(0_0_0/0.08),0_1px_2px_-1px_oklch(0_0_0/0.08),0_4px_12px_-2px_oklch(0_0_0/0.08)] transition-[border-radius,box-shadow] duration-200 dark:bg-muted/50 dark:shadow-[0_0_0_1px_oklch(1_0_0/0.1)]\",\n            expanded\n              ? \"grid rounded-[28px] [grid-template-areas:'primary'_'footer'] [grid-template-columns:1fr] [grid-template-rows:auto_auto]\"\n              : \"grid rounded-full [grid-template-areas:'leading_primary_trailing'] [grid-template-columns:auto_1fr_auto] [grid-template-rows:1fr]\"\n          )}\n        >\n          <div\n            className={cn(\n              \"flex overflow-x-hidden\",\n              expanded ? \"px-2 pt-1.5 pb-2\" : \"-my-2.5 min-h-14 items-center px-1.5\"\n            )}\n            style={{ gridArea: \"primary\" }}\n          >\n            <div className=\"max-h-52 flex-1 overflow-auto\">\n              <Textarea\n                aria-label=\"Message\"\n                className=\"min-h-0 resize-none rounded-none border-0 p-0 text-base shadow-none focus-visible:ring-0 focus-visible:outline-none md:text-base dark:bg-transparent\"\n                onChange={(event) => {\n                  const value = event.currentTarget.value\n                  setMessage(value)\n                  event.currentTarget.style.height = \"auto\"\n                  event.currentTarget.style.height = `${event.currentTarget.scrollHeight}px`\n                  setExpanded(value.length > 100 || value.includes(\"\\n\"))\n                }}\n                onKeyDown={(event) => {\n                  if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n                    event.preventDefault()\n                    send()\n                  }\n                }}\n                placeholder=\"Ask anything\"\n                ref={textareaRef}\n                rows={1}\n                value={message}\n              />\n            </div>\n          </div>\n\n          <div\n            className={cn(\"flex items-center\", expanded && \"hidden\")}\n            style={{ gridArea: \"leading\" }}\n          >\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button\n                  aria-label=\"Add context\"\n                  className=\"size-9 rounded-full transition-[background-color,transform] duration-150 active:scale-[0.96]\"\n                  type=\"button\"\n                  variant=\"ghost\"\n                >\n                  <IconPlus className=\"size-5 text-muted-foreground\" stroke={1.5} />\n                </Button>\n              </DropdownMenuTrigger>\n              <DropdownMenuContent align=\"start\" className=\"w-64 rounded-2xl p-1.5\">\n                <DropdownMenuGroup className=\"space-y-1\">\n                  <DropdownMenuItem className=\"rounded-[10px] px-2.5 py-2\" onSelect={() => fileInputRef.current?.click()}>\n                    <IconPaperclip className=\"opacity-60\" size={20} stroke={1.5} />\n                    Add photos & files\n                  </DropdownMenuItem>\n                  <DropdownMenuItem className=\"rounded-[10px] px-2.5 py-2\" onSelect={() => onModeChange?.(\"agent\")}>\n                    <IconSparkles className=\"opacity-60\" size={20} stroke={1.5} />\n                    Field agent mode\n                  </DropdownMenuItem>\n                  <DropdownMenuItem className=\"rounded-[10px] px-2.5 py-2\" onSelect={() => onModeChange?.(\"research\")}>\n                    <IconSearch className=\"opacity-60\" size={20} stroke={1.5} />\n                    Deep research\n                  </DropdownMenuItem>\n                </DropdownMenuGroup>\n              </DropdownMenuContent>\n            </DropdownMenu>\n          </div>\n\n          <div\n            className=\"flex items-center gap-2\"\n            style={{ gridArea: expanded ? \"footer\" : \"trailing\" }}\n          >\n            <div className=\"ms-auto flex items-center gap-1.5\">\n              <Button aria-label=\"Record audio message\" className=\"size-9 rounded-full transition-[background-color,transform] duration-150 active:scale-[0.96]\" type=\"button\" variant=\"ghost\">\n                <IconMicrophone className=\"size-5 text-muted-foreground\" stroke={1.5} />\n              </Button>\n              <Button aria-label=\"Audio visualization\" className=\"size-9 rounded-full transition-[background-color,transform] duration-150 active:scale-[0.96]\" type=\"button\" variant=\"ghost\">\n                <IconWaveSine className=\"size-5 text-muted-foreground\" stroke={1.5} />\n              </Button>\n              <Button aria-label=\"Send message\" className=\"size-9 rounded-full transition-[background-color,transform,opacity] duration-150 active:scale-[0.96] disabled:opacity-40\" disabled={!message.trim()} type=\"submit\">\n                <IconSend className=\"size-[18px]\" stroke={1.5} />\n              </Button>\n            </div>\n          </div>\n        </div>\n      </form>\n    </div>\n  )\n}\n\nexport default BlocksAi01\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/dropdown-menu.tsx",
          "target": "@components/ui/dropdown-menu.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction DropdownMenu({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  return (\n    <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n  )\n}\n\nfunction DropdownMenuTrigger({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-md\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return (\n    <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return (\n    <DropdownMenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CircleIcon className=\"size-2 fill-current\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-semibold data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPrimitive.SubContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "blocks-so-ai-02",
      "type": "registry:block",
      "title": "Blocks So Ai 02",
      "description": "ai 02",
      "dependencies": [
        "@base-ui/react@1.6.0",
        "@radix-ui/react-slot@^1.2.2",
        "@tabler/icons-react@3.34.1",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/ai-02.tsx",
          "target": "@components/blocks-so/ai-02.tsx",
          "type": "registry:component",
          "content": "export {\n  BlocksAi02,\n  blocksAi02Models,\n  type BlocksAi02Props,\n} from \"./ai/ai-02\"\nexport { default } from \"./ai/ai-02\"\n"
        },
        {
          "path": "components/blocks-so/ai/ai-02.tsx",
          "target": "@components/blocks-so/ai/ai-02.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n// Adapted from Blocks ai-02 (MIT), pinned in components/blocks-so/SOURCE.json.\nimport {\n  IconAlertTriangle,\n  IconArrowUp,\n  IconCloud,\n  IconFileSpark,\n  IconGauge,\n  IconPhotoScan,\n} from \"@tabler/icons-react\"\nimport * as React from \"react\"\n\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/blocks-so/ai/_ui/select\"\nimport { Button } from \"@/components/ui/button\"\nimport { Textarea } from \"@/components/ui/textarea\"\nimport { cn } from \"@/lib/utils\"\n\nexport const blocksAi02Models = [\n  { value: \"gpt-5\", name: \"GPT-5\", description: \"Most advanced model\", max: true },\n  { value: \"gpt-4o\", name: \"GPT-4o\", description: \"Fast and capable\", max: false },\n  { value: \"claude-3.5\", name: \"Claude 3.5 Sonnet\", description: \"Great for coding tasks\", max: false },\n] as const\n\nconst prompts = [\n  {\n    icon: IconFileSpark,\n    label: \"Summarize field notes\",\n    prompt: \"Summarize the latest field notes into decisions, evidence, and open questions.\",\n  },\n  {\n    icon: IconGauge,\n    label: \"Compare survey runs\",\n    prompt: \"Compare the two survey runs and explain the largest changes with supporting evidence.\",\n  },\n  {\n    icon: IconAlertTriangle,\n    label: \"Flag missing evidence\",\n    prompt: \"Review this workspace and flag the three most important claims that still need evidence.\",\n  },\n] as const\n\nexport type BlocksAi02Props = {\n  className?: string\n  defaultModel?: (typeof blocksAi02Models)[number][\"value\"]\n  onFilesSelected?: (files: File[]) => void\n  onSubmit?: (message: string, model: string) => void\n  renderComposer?: (composer: React.ReactNode) => React.ReactNode\n}\n\nexport function BlocksAi02({\n  className,\n  defaultModel = \"gpt-5\",\n  onFilesSelected,\n  onSubmit,\n  renderComposer,\n}: BlocksAi02Props) {\n  const [message, setMessage] = React.useState(\"\")\n  const [model, setModel] = React.useState<string>(defaultModel)\n  const textareaRef = React.useRef<HTMLTextAreaElement>(null)\n  const fileInputRef = React.useRef<HTMLInputElement>(null)\n  const selectedModel =\n    blocksAi02Models.find((candidate) => candidate.value === model) ??\n    blocksAi02Models[0]\n\n  React.useEffect(() => {\n    const textarea = textareaRef.current\n    if (!textarea) return\n    textarea.style.height = \"auto\"\n    textarea.style.height = `${Math.min(textarea.scrollHeight, 258)}px`\n  }, [message])\n\n  const choosePrompt = (prompt: string) => {\n    setMessage(prompt)\n    textareaRef.current?.focus()\n  }\n\n  const submit = (event: React.FormEvent) => {\n    event.preventDefault()\n    const value = message.trim()\n    if (!value) return\n    onSubmit?.(value, model)\n    setMessage(\"\")\n  }\n\n  const maxBadge = (\n    <span className=\"inline-flex h-[15px] items-center rounded-[4px] border border-border/80 bg-muted/40 px-[5px]\">\n      <span className=\"bg-gradient-to-r from-slate-500 to-violet-500 bg-clip-text text-[9px] font-bold leading-none tracking-[0.06em] text-transparent uppercase\">\n        Max\n      </span>\n    </span>\n  )\n\n  const composer = (\n    <div className=\"flex min-h-[120px] cursor-text flex-col rounded-2xl border border-border bg-card shadow-lg transition-[border-color,box-shadow] duration-200 focus-within:border-foreground/20 focus-within:shadow-xl\">\n      <div className=\"relative max-h-[258px] flex-1 overflow-y-auto\">\n        <Textarea\n          aria-label=\"Message\"\n          className=\"min-h-[72px] w-full resize-none whitespace-pre-wrap break-words border-0 bg-transparent p-3 text-base shadow-none outline-none transition-[padding] duration-200 focus-visible:ring-0 focus-visible:outline-none\"\n          onChange={(event) => setMessage(event.currentTarget.value)}\n          onKeyDown={(event) => {\n            if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n              event.preventDefault()\n              event.currentTarget.form?.requestSubmit()\n            }\n          }}\n          placeholder=\"Ask about this fieldwork\"\n          ref={textareaRef}\n          rows={1}\n          value={message}\n        />\n      </div>\n\n      <div className=\"flex min-h-10 items-center gap-2 p-2 pt-1\">\n        <div aria-label=\"Workspace context\" className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-muted\" role=\"img\">\n          <IconCloud className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />\n        </div>\n\n        <Select onValueChange={(value) => value && setModel(value)} value={model}>\n          <SelectTrigger\n            aria-label={`Model: ${selectedModel.name}`}\n            className=\"h-7 rounded-full border-transparent bg-transparent px-2 font-medium text-foreground shadow-none transition-[background-color,color] hover:bg-muted data-popup-open:bg-muted dark:bg-transparent dark:hover:bg-muted\"\n            size=\"sm\"\n          >\n            <SelectValue>\n              <span className=\"flex items-center gap-1.5\">\n                <span>{selectedModel.name}</span>\n                {selectedModel.max && maxBadge}\n              </span>\n            </SelectValue>\n          </SelectTrigger>\n          <SelectContent align=\"start\" alignItemWithTrigger={false} className=\"w-64 p-1\" sideOffset={6}>\n            {blocksAi02Models.map((candidate) => (\n              <SelectItem className=\"rounded-md py-1.5\" key={candidate.value} value={candidate.value}>\n                <span className=\"flex flex-col gap-0.5\">\n                  <span className=\"flex items-center gap-1.5 font-medium\">\n                    {candidate.name}\n                    {candidate.max && maxBadge}\n                  </span>\n                  <span className=\"text-xs text-muted-foreground\">{candidate.description}</span>\n                </span>\n              </SelectItem>\n            ))}\n          </SelectContent>\n        </Select>\n\n        <div className=\"ml-auto flex items-center gap-1.5\">\n          <Button\n            aria-label=\"Attach images\"\n            className=\"size-8 rounded-full text-muted-foreground transition-[background-color,color,transform] duration-150 hover:text-foreground active:scale-[0.96]\"\n            onClick={() => fileInputRef.current?.click()}\n            title=\"Attach images\"\n            type=\"button\"\n            variant=\"ghost\"\n          >\n            <IconPhotoScan className=\"size-[18px]\" />\n          </Button>\n          <Button\n            aria-label=\"Send message\"\n            className=\"size-8 rounded-full transition-[background-color,transform,opacity] duration-150 active:scale-[0.96]\"\n            disabled={!message.trim()}\n            type=\"submit\"\n          >\n            <IconArrowUp className=\"size-4\" />\n          </Button>\n        </div>\n      </div>\n    </div>\n  )\n\n  return (\n    <form\n      className={cn(\"flex w-full max-w-[37rem] flex-col gap-4\", className)}\n      data-blocks-ai=\"ai-02\"\n      onSubmit={submit}\n    >\n      <input\n        aria-label=\"Attach images\"\n        className=\"sr-only\"\n        multiple\n        onChange={(event) => {\n          const files = Array.from(event.currentTarget.files ?? [])\n          if (files.length) onFilesSelected?.(files)\n          event.currentTarget.value = \"\"\n        }}\n        ref={fileInputRef}\n        type=\"file\"\n      />\n\n      {renderComposer ? renderComposer(composer) : composer}\n\n      <div className=\"flex flex-wrap justify-center gap-2\" aria-label=\"Suggested prompts\" role=\"group\">\n        {prompts.map(({ icon: Icon, label, prompt }) => (\n          <Button\n            className=\"h-8 gap-1.5 rounded-full border-border bg-background pr-3.5 pl-2.5 font-normal shadow-[0_1px_2px_oklch(0_0_0/0.05)] transition-[background-color,color,transform,box-shadow] duration-150 hover:bg-muted active:scale-[0.96] dark:bg-muted/40\"\n            key={label}\n            onClick={() => choosePrompt(prompt)}\n            type=\"button\"\n            variant=\"outline\"\n          >\n            <Icon className=\"size-4 text-muted-foreground\" />\n            {label}\n          </Button>\n        ))}\n      </div>\n    </form>\n  )\n}\n\nexport default BlocksAi02\n"
        },
        {
          "path": "components/blocks-so/ai/_ui/select.tsx",
          "target": "@components/blocks-so/ai/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n// Blocks/shadcn Select primitive (MIT), scoped locally to keep the public host untouched.\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport type * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Select = SelectPrimitive.Root\n\nfunction SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {\n  return <SelectPrimitive.Value className={cn(\"flex flex-1 text-left\", className)} data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({ className, size = \"default\", children, ...props }: SelectPrimitive.Trigger.Props & { size?: \"sm\" | \"default\" }) {\n  return (\n    <SelectPrimitive.Trigger\n      className={cn(\n        \"flex w-fit select-none items-center justify-between gap-1.5 whitespace-nowrap rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm outline-none transition-colors focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-placeholder:text-muted-foreground *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n        className\n      )}\n      data-size={size}\n      data-slot=\"select-trigger\"\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon render={<ChevronDownIcon className=\"pointer-events-none size-4 text-muted-foreground\" />} />\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  side = \"bottom\",\n  sideOffset = 4,\n  align = \"center\",\n  alignOffset = 0,\n  alignItemWithTrigger = true,\n  ...props\n}: SelectPrimitive.Popup.Props & Pick<SelectPrimitive.Positioner.Props, \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\">) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Positioner align={align} alignItemWithTrigger={alignItemWithTrigger} alignOffset={alignOffset} className=\"isolate z-50\" side={side} sideOffset={sideOffset}>\n        <SelectPrimitive.Popup\n          className={cn(\n            \"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:fade-in-0 data-open:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-closed:animate-out data-open:animate-in\",\n            className\n          )}\n          data-align-trigger={alignItemWithTrigger}\n          data-slot=\"select-content\"\n          {...props}\n        >\n          <SelectPrimitive.ScrollUpArrow className=\"top-0 z-10 flex w-full items-center justify-center bg-popover py-1\"><ChevronUpIcon className=\"size-4\" /></SelectPrimitive.ScrollUpArrow>\n          <SelectPrimitive.List>{children}</SelectPrimitive.List>\n          <SelectPrimitive.ScrollDownArrow className=\"bottom-0 z-10 flex w-full items-center justify-center bg-popover py-1\"><ChevronDownIcon className=\"size-4\" /></SelectPrimitive.ScrollDownArrow>\n        </SelectPrimitive.Popup>\n      </SelectPrimitive.Positioner>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectItem({ className, children, ...props }: SelectPrimitive.Item.Props) {\n  return (\n    <SelectPrimitive.Item\n      className={cn(\n        \"relative flex w-full cursor-default select-none items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n        className\n      )}\n      data-slot=\"select-item\"\n      {...props}\n    >\n      <SelectPrimitive.ItemText className=\"flex flex-1 shrink-0 gap-2 whitespace-nowrap\">{children}</SelectPrimitive.ItemText>\n      <SelectPrimitive.ItemIndicator render={<span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />}>\n        <CheckIcon className=\"size-4\" />\n      </SelectPrimitive.ItemIndicator>\n    </SelectPrimitive.Item>\n  )\n}\n\nexport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "blocks-so-ai-03",
      "type": "registry:block",
      "title": "Blocks So Ai 03",
      "description": "ai 03",
      "dependencies": [
        "@radix-ui/react-dropdown-menu@^2.1.14",
        "@radix-ui/react-slot@^1.2.2",
        "@tabler/icons-react@3.34.1",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/ai-03.tsx",
          "target": "@components/blocks-so/ai-03.tsx",
          "type": "registry:component",
          "content": "export { BlocksAi03, type BlocksAi03Options, type BlocksAi03Props } from \"./ai/ai-03\"\nexport { default } from \"./ai/ai-03\"\n"
        },
        {
          "path": "components/blocks-so/ai/ai-03.tsx",
          "target": "@components/blocks-so/ai/ai-03.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n// Adapted from Blocks ai-03 (MIT), pinned in components/blocks-so/SOURCE.json.\nimport {\n  IconBolt,\n  IconChevronDown,\n  IconCircle,\n  IconCircleDashed,\n  IconCloud,\n  IconCode,\n  IconDeviceLaptop,\n  IconHistory,\n  IconPaperclip,\n  IconPlus,\n  IconProgress,\n  IconRobot,\n  IconSend,\n  IconUser,\n  IconWand,\n  IconWorld,\n} from \"@tabler/icons-react\"\nimport * as React from \"react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { Textarea } from \"@/components/ui/textarea\"\nimport { cn } from \"@/lib/utils\"\n\nexport type BlocksAi03Options = {\n  agent: string\n  auto: boolean\n  model: string\n  performance: string\n}\n\nexport type BlocksAi03Props = {\n  className?: string\n  onFilesSelected?: (files: File[]) => void\n  onSubmit?: (message: string, options: BlocksAi03Options) => void\n}\n\nfunction CompactMenu({\n  children,\n  label,\n}: {\n  children: React.ReactNode\n  label: React.ReactNode\n}) {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button className=\"h-6 gap-1 rounded-full border border-transparent px-2 text-xs text-muted-foreground hover:bg-accent\" type=\"button\" variant=\"ghost\">\n          {label}\n          <IconChevronDown className=\"size-3\" />\n        </Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent align=\"start\" className=\"max-w-xs rounded-2xl border-border bg-popover p-1.5\">\n        <DropdownMenuGroup className=\"space-y-1\">{children}</DropdownMenuGroup>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n\nfunction CompactItem({\n  children,\n  icon: Icon,\n  onSelect,\n}: {\n  children: React.ReactNode\n  icon: React.ComponentType<{ className?: string; size?: number }>\n  onSelect?: () => void\n}) {\n  return (\n    <DropdownMenuItem className=\"rounded-[calc(1rem-6px)] text-xs\" onSelect={onSelect}>\n      <Icon className=\"opacity-60\" size={16} />\n      {children}\n    </DropdownMenuItem>\n  )\n}\n\nexport function BlocksAi03({ className, onFilesSelected, onSubmit }: BlocksAi03Props) {\n  const [message, setMessage] = React.useState(\"\")\n  const [model, setModel] = React.useState(\"Local\")\n  const [agent, setAgent] = React.useState(\"Agent\")\n  const [performance, setPerformance] = React.useState(\"High\")\n  const [auto, setAuto] = React.useState(false)\n  const fileInputRef = React.useRef<HTMLInputElement>(null)\n\n  const submit = (event: React.FormEvent) => {\n    event.preventDefault()\n    const value = message.trim()\n    if (!value) return\n    onSubmit?.(value, { agent, auto, model, performance })\n    setMessage(\"\")\n  }\n\n  return (\n    <form className={cn(\"w-full max-w-xl\", className)} data-blocks-ai=\"ai-03\" onSubmit={submit}>\n      <div className=\"overflow-hidden rounded-2xl border border-border bg-background transition-[border-color,box-shadow] duration-200 focus-within:border-foreground/20 focus-within:shadow-sm\">\n        <input\n          className=\"sr-only\"\n          multiple\n          onChange={(event) => {\n            const files = Array.from(event.currentTarget.files ?? [])\n            if (files.length) onFilesSelected?.(files)\n            event.currentTarget.value = \"\"\n          }}\n          ref={fileInputRef}\n          type=\"file\"\n        />\n        <div className=\"grow px-3 pt-3 pb-2\">\n          <Textarea\n            aria-label=\"Message\"\n            className=\"max-h-[25vh] min-h-10 w-full resize-none border-0 bg-transparent p-0 text-sm shadow-none outline-none focus-visible:ring-0 focus-visible:outline-none\"\n            onChange={(event) => setMessage(event.currentTarget.value)}\n            onInput={(event) => {\n              event.currentTarget.style.height = \"auto\"\n              event.currentTarget.style.height = `${event.currentTarget.scrollHeight}px`\n            }}\n            onKeyDown={(event) => {\n              if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n                event.preventDefault()\n                event.currentTarget.form?.requestSubmit()\n              }\n            }}\n            placeholder=\"Ask anything\"\n            rows={1}\n            value={message}\n          />\n        </div>\n\n        <div className=\"mb-2 flex items-center justify-between px-2\">\n          <div className=\"flex items-center gap-1\">\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button aria-label=\"Add tools\" className=\"size-7 rounded-full border border-border p-0 hover:bg-accent\" type=\"button\" variant=\"ghost\">\n                  <IconPlus className=\"size-3\" />\n                </Button>\n              </DropdownMenuTrigger>\n              <DropdownMenuContent align=\"start\" className=\"max-w-xs rounded-2xl p-1.5\">\n                <DropdownMenuGroup className=\"space-y-1\">\n                  <CompactItem icon={IconPaperclip} onSelect={() => fileInputRef.current?.click()}>Attach files</CompactItem>\n                  <CompactItem icon={IconCode}>Code interpreter</CompactItem>\n                  <CompactItem icon={IconWorld}>Web search</CompactItem>\n                  <CompactItem icon={IconHistory}>Chat history</CompactItem>\n                </DropdownMenuGroup>\n              </DropdownMenuContent>\n            </DropdownMenu>\n            <Button\n              aria-pressed={auto}\n              className={cn(\n                \"h-7 gap-1 rounded-full border border-border px-2 hover:bg-accent\",\n                auto ? \"border-primary/30 bg-primary/10 text-primary\" : \"text-muted-foreground\"\n              )}\n              onClick={() => setAuto((value) => !value)}\n              type=\"button\"\n              variant=\"ghost\"\n            >\n              <IconWand className=\"size-3\" />\n              <span className=\"text-xs\">Auto</span>\n            </Button>\n          </div>\n          <Button aria-label=\"Send message\" className=\"size-7 rounded-full p-0\" disabled={!message.trim()} type=\"submit\">\n            <IconSend className=\"size-3\" />\n          </Button>\n        </div>\n      </div>\n\n      <div className=\"flex flex-wrap items-center gap-0 pt-2\">\n        <CompactMenu label={<><IconDeviceLaptop className=\"size-3\" /><span>{model}</span></>}>\n          <CompactItem icon={IconDeviceLaptop} onSelect={() => setModel(\"Local\")}>Local</CompactItem>\n          <CompactItem icon={IconCloud} onSelect={() => setModel(\"Cloud\")}>Cloud</CompactItem>\n        </CompactMenu>\n        <CompactMenu label={<><IconUser className=\"size-3\" /><span>{agent}</span></>}>\n          <CompactItem icon={IconUser} onSelect={() => setAgent(\"Agent\")}>Agent</CompactItem>\n          <CompactItem icon={IconRobot} onSelect={() => setAgent(\"Assistant\")}>Assistant</CompactItem>\n        </CompactMenu>\n        <CompactMenu label={<><IconBolt className=\"size-3\" /><span>{performance}</span></>}>\n          <CompactItem icon={IconCircle} onSelect={() => setPerformance(\"High\")}>High</CompactItem>\n          <CompactItem icon={IconProgress} onSelect={() => setPerformance(\"Medium\")}>Medium</CompactItem>\n          <CompactItem icon={IconCircleDashed} onSelect={() => setPerformance(\"Low\")}>Low</CompactItem>\n        </CompactMenu>\n      </div>\n    </form>\n  )\n}\n\nexport default BlocksAi03\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/dropdown-menu.tsx",
          "target": "@components/ui/dropdown-menu.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction DropdownMenu({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  return (\n    <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n  )\n}\n\nfunction DropdownMenuTrigger({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-md\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return (\n    <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return (\n    <DropdownMenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CircleIcon className=\"size-2 fill-current\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-semibold data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPrimitive.SubContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "blocks-so-ai-04",
      "type": "registry:block",
      "title": "Blocks So Ai 04",
      "description": "ai 04",
      "dependencies": [
        "@base-ui/react@1.6.0",
        "@radix-ui/react-dropdown-menu@^2.1.14",
        "@radix-ui/react-label@^2.1.6",
        "@radix-ui/react-slot@^1.2.2",
        "@tabler/icons-react@3.34.1",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "next@15.5.25",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/ai-04.tsx",
          "target": "@components/blocks-so/ai-04.tsx",
          "type": "registry:component",
          "content": "export {\n  BlocksAi04,\n  type BlocksAi04File,\n  type BlocksAi04Props,\n  type BlocksAi04Settings,\n} from \"./ai/ai-04\"\nexport { default } from \"./ai/ai-04\"\n"
        },
        {
          "path": "components/blocks-so/ai/ai-04.tsx",
          "target": "@components/blocks-so/ai/ai-04.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n// Adapted from Blocks ai-04 (MIT), pinned in components/blocks-so/SOURCE.json.\nimport {\n  IconAdjustmentsHorizontal,\n  IconArrowUp,\n  IconCamera,\n  IconCirclePlus,\n  IconClipboard,\n  IconFileUpload,\n  IconHistory,\n  IconLink,\n  IconMap,\n  IconPaperclip,\n  IconPlayerPlay,\n  IconPlus,\n  IconReportAnalytics,\n  IconSparkles,\n  IconTemplate,\n  IconX,\n} from \"@tabler/icons-react\"\nimport Image from \"next/image\"\nimport * as React from \"react\"\n\nimport { Switch } from \"@/components/blocks-so/ai/_ui/switch\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { Label } from \"@/components/ui/label\"\nimport { Textarea } from \"@/components/ui/textarea\"\nimport { cn } from \"@/lib/utils\"\n\nexport type BlocksAi04File = {\n  file: File\n  id: string\n  name: string\n  preview?: string\n}\n\nexport type BlocksAi04Settings = {\n  autoComplete: boolean\n  showHistory: boolean\n  streaming: boolean\n}\n\nexport type BlocksAi04Props = {\n  className?: string\n  onAction?: (action: string) => void\n  onFilesChange?: (files: BlocksAi04File[]) => void\n  onSubmit?: (prompt: string, files: File[], settings: BlocksAi04Settings) => void\n}\n\nconst actions = [\n  { id: \"capture\", icon: IconCamera, label: \"Capture field evidence\" },\n  { id: \"map\", icon: IconMap, label: \"Connect survey map\" },\n  { id: \"upload\", icon: IconFileUpload, label: \"Upload observations\" },\n  { id: \"report\", icon: IconReportAnalytics, label: \"Draft field report\" },\n] as const\n\nexport function BlocksAi04({ className, onAction, onFilesChange, onSubmit }: BlocksAi04Props) {\n  const [prompt, setPrompt] = React.useState(\"\")\n  const [dragOver, setDragOver] = React.useState(false)\n  const [files, setFiles] = React.useState<BlocksAi04File[]>([])\n  const [settings, setSettings] = React.useState<BlocksAi04Settings>({\n    autoComplete: true,\n    showHistory: false,\n    streaming: false,\n  })\n  const fileInputRef = React.useRef<HTMLInputElement>(null)\n\n  const commitFiles = (next: BlocksAi04File[]) => {\n    setFiles(next)\n    onFilesChange?.(next)\n  }\n\n  const processFiles = (incoming: File[]) => {\n    const additions = incoming.map((file) => ({\n      file,\n      id: `${file.name}-${file.lastModified}-${Math.random().toString(36).slice(2, 8)}`,\n      name: file.name,\n    }))\n    const next = [...files, ...additions]\n    commitFiles(next)\n\n    additions.forEach(({ file, id }) => {\n      if (file.type.startsWith(\"image/\")) {\n        const reader = new FileReader()\n        reader.onload = () => {\n          setFiles((current) =>\n            current.map((candidate) =>\n              candidate.id === id ? { ...candidate, preview: String(reader.result) } : candidate\n            )\n          )\n        }\n        reader.readAsDataURL(file)\n      }\n    })\n  }\n\n  const submit = (event?: React.FormEvent) => {\n    event?.preventDefault()\n    const value = prompt.trim()\n    if (!value) return\n    onSubmit?.(value, files.map(({ file }) => file), settings)\n    setPrompt(\"\")\n  }\n\n  const updateSetting = (key: keyof BlocksAi04Settings, value: boolean) =>\n    setSettings((current) => ({ ...current, [key]: value }))\n\n  return (\n    <div className={cn(\"mx-auto flex w-full flex-col gap-4\", className)} data-blocks-ai=\"ai-04\">\n      <div>\n        <h2 className=\"text-balance text-center text-xl font-medium tracking-tight\">\n          Collect. Compare. Report.\n        </h2>\n        <p className=\"mt-1 text-balance text-center text-sm text-muted-foreground\">\n          Turn field evidence into a working brief.\n        </p>\n      </div>\n\n      <div className=\"relative z-10 mx-auto flex w-full max-w-2xl flex-col\">\n        <form\n          className=\"relative overflow-visible rounded-xl border border-input bg-card p-2 shadow-sm transition-[border-color,box-shadow] duration-200 focus-within:border-ring\"\n          onDragLeave={(event) => {\n            event.preventDefault()\n            setDragOver(false)\n          }}\n          onDragOver={(event) => {\n            event.preventDefault()\n            setDragOver(true)\n          }}\n          onDrop={(event) => {\n            event.preventDefault()\n            setDragOver(false)\n            processFiles(Array.from(event.dataTransfer.files))\n          }}\n          onSubmit={submit}\n        >\n          {files.length > 0 && (\n            <div className=\"relative mb-2 flex flex-wrap items-center gap-2 overflow-hidden\">\n              {files.map((file) => (\n                <Badge className=\"group relative h-6 max-w-36 cursor-default overflow-hidden px-0 text-[13px] transition-colors hover:bg-accent\" key={file.id} variant=\"outline\">\n                  <span className=\"flex h-full items-center gap-1.5 overflow-hidden pl-1 font-normal\">\n                    <span className=\"relative flex h-4 min-w-4 items-center justify-center\">\n                      {file.preview ? (\n                        <Image alt=\"\" className=\"absolute inset-0 size-4 rounded border object-cover\" height={16} src={file.preview} width={16} />\n                      ) : (\n                        <IconPaperclip className=\"opacity-60\" size={12} />\n                      )}\n                    </span>\n                    <span className=\"truncate pr-6\">{file.name}</span>\n                  </span>\n                  <button\n                    aria-label={`Remove ${file.name}`}\n                    className=\"absolute right-1 z-10 rounded-sm p-0.5 text-muted-foreground opacity-0 transition-opacity focus-visible:opacity-100 group-hover:opacity-100\"\n                    onClick={() => commitFiles(files.filter((candidate) => candidate.id !== file.id))}\n                    type=\"button\"\n                  >\n                    <IconX size={12} />\n                  </button>\n                </Badge>\n              ))}\n            </div>\n          )}\n\n          <Textarea\n            aria-label=\"Prompt\"\n            className=\"max-h-50 min-h-12 resize-none rounded-none border-0 bg-transparent p-0 text-sm shadow-none focus-visible:ring-0 focus-visible:outline-none\"\n            onChange={(event) => setPrompt(event.currentTarget.value)}\n            onKeyDown={(event) => {\n              if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n                event.preventDefault()\n                submit()\n              }\n            }}\n            placeholder=\"Describe what the field team should examine\"\n            value={prompt}\n          />\n\n          <div className=\"flex items-center gap-1\">\n            <input\n              className=\"sr-only\"\n              multiple\n              onChange={(event) => {\n                processFiles(Array.from(event.currentTarget.files ?? []))\n                event.currentTarget.value = \"\"\n              }}\n              ref={fileInputRef}\n              type=\"file\"\n            />\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button aria-label=\"Add attachments\" className=\"size-8 rounded-md\" type=\"button\" variant=\"ghost\"><IconPlus size={16} /></Button>\n              </DropdownMenuTrigger>\n              <DropdownMenuContent align=\"start\" className=\"max-w-xs rounded-2xl p-1.5\">\n                <DropdownMenuGroup className=\"space-y-1\">\n                  <DropdownMenuItem className=\"rounded-md text-xs\" onSelect={() => fileInputRef.current?.click()}><IconPaperclip size={16} />Attach files</DropdownMenuItem>\n                  <DropdownMenuItem className=\"rounded-md text-xs\"><IconLink size={16} />Import from URL</DropdownMenuItem>\n                  <DropdownMenuItem className=\"rounded-md text-xs\"><IconClipboard size={16} />Paste from clipboard</DropdownMenuItem>\n                  <DropdownMenuItem className=\"rounded-md text-xs\"><IconTemplate size={16} />Use template</DropdownMenuItem>\n                </DropdownMenuGroup>\n              </DropdownMenuContent>\n            </DropdownMenu>\n\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button aria-label=\"Adjust settings\" className=\"size-8 rounded-md\" type=\"button\" variant=\"ghost\"><IconAdjustmentsHorizontal size={16} /></Button>\n              </DropdownMenuTrigger>\n              <DropdownMenuContent align=\"start\" className=\"w-56 rounded-2xl p-3\">\n                <DropdownMenuGroup className=\"space-y-3\">\n                  {([\n                    [\"autoComplete\", \"Auto-complete\", IconSparkles],\n                    [\"streaming\", \"Streaming\", IconPlayerPlay],\n                    [\"showHistory\", \"Show history\", IconHistory],\n                  ] as const).map(([key, label, Icon]) => (\n                    <div className=\"flex items-center justify-between gap-4\" key={key}>\n                      <Label className=\"gap-2 text-xs\"><Icon className=\"text-muted-foreground\" size={16} />{label}</Label>\n                      <Switch aria-label={label} checked={settings[key]} onCheckedChange={(value) => updateSetting(key, value)} />\n                    </div>\n                  ))}\n                </DropdownMenuGroup>\n              </DropdownMenuContent>\n            </DropdownMenu>\n\n            <Button aria-label=\"Send prompt\" className=\"ml-auto size-8 rounded-md\" disabled={!prompt.trim()} type=\"submit\">\n              <IconArrowUp size={16} />\n            </Button>\n          </div>\n\n          <div\n            aria-hidden={!dragOver}\n            className={cn(\n              \"pointer-events-none absolute inset-0 z-20 flex items-center justify-center rounded-[inherit] border border-dashed bg-muted/95 text-sm transition-opacity duration-200\",\n              dragOver ? \"opacity-100\" : \"opacity-0\"\n            )}\n          >\n            <span className=\"flex items-center gap-1 font-medium\"><IconCirclePlus size={16} />Drop files here to attach</span>\n          </div>\n        </form>\n      </div>\n\n      <div className=\"mx-auto flex flex-wrap items-center justify-center gap-3\">\n        {actions.map(({ id, icon: Icon, label }) => (\n          <Button className=\"gap-2 rounded-full transition-transform duration-150 active:scale-[0.96]\" key={id} onClick={() => onAction?.(id)} size=\"sm\" type=\"button\" variant=\"outline\">\n            <Icon size={16} />{label}\n          </Button>\n        ))}\n      </div>\n    </div>\n  )\n}\n\nexport default BlocksAi04\n"
        },
        {
          "path": "components/blocks-so/ai/_ui/switch.tsx",
          "target": "@components/blocks-so/ai/_ui/switch.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n// Blocks/shadcn Switch primitive (MIT), scoped locally to keep the public host untouched.\nimport { Switch as SwitchPrimitive } from \"@base-ui/react/switch\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport function Switch({ className, size = \"default\", ...props }: SwitchPrimitive.Root.Props & { size?: \"sm\" | \"default\" }) {\n  return (\n    <SwitchPrimitive.Root\n      className={cn(\n        \"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent outline-none transition-all focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 data-[size=default]:h-[18.4px] data-[size=sm]:h-[14px] data-[size=default]:w-8 data-[size=sm]:w-6 data-checked:bg-primary data-disabled:cursor-not-allowed data-disabled:opacity-50 data-unchecked:bg-input dark:data-unchecked:bg-input/80\",\n        className\n      )}\n      data-size={size}\n      data-slot=\"switch\"\n      {...props}\n    >\n      <SwitchPrimitive.Thumb className=\"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-checked:bg-primary-foreground dark:data-unchecked:bg-foreground\" />\n    </SwitchPrimitive.Root>\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/badge.tsx",
          "target": "@components/ui/badge.tsx",
          "type": "registry:component",
          "content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        destructive:\n          \"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80\",\n        outline: \"text-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nexport interface BadgeProps\n  extends React.HTMLAttributes<HTMLDivElement>,\n    VariantProps<typeof badgeVariants> {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n  return (\n    <div className={cn(badgeVariants({ variant }), className)} {...props} />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ui/dropdown-menu.tsx",
          "target": "@components/ui/dropdown-menu.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction DropdownMenu({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  return (\n    <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n  )\n}\n\nfunction DropdownMenuTrigger({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-md\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return (\n    <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return (\n    <DropdownMenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CircleIcon className=\"size-2 fill-current\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-semibold data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPrimitive.SubContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-lg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"
        },
        {
          "path": "components/ui/label.tsx",
          "target": "@components/ui/label.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Label({\n  className,\n  ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n  return (\n    <LabelPrimitive.Root\n      data-slot=\"label\"\n      className={cn(\n        \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Label }\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "blocks-so-ai-05",
      "type": "registry:block",
      "title": "Blocks So Ai 05",
      "description": "ai 05",
      "dependencies": [
        "@radix-ui/react-slot@^1.2.2",
        "@tabler/icons-react@3.34.1",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "react-markdown@^10.1.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/ai-05.tsx",
          "target": "@components/blocks-so/ai-05.tsx",
          "type": "registry:component",
          "content": "export { BlocksAi05, type BlocksAi05Message, type BlocksAi05Props } from \"./ai/ai-05\"\nexport { default } from \"./ai/ai-05\"\n"
        },
        {
          "path": "components/blocks-so/ai/ai-05.tsx",
          "target": "@components/blocks-so/ai/ai-05.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\n// Adapted from Blocks ai-05 and its AI Elements dependencies (MIT), pinned in SOURCE.json.\nimport {\n  IconAdjustmentsHorizontal,\n  IconArrowDown,\n  IconArrowUp,\n  IconBolt,\n  IconLoader2,\n  IconPaperclip,\n  IconPlus,\n} from \"@tabler/icons-react\"\nimport * as React from \"react\"\nimport ReactMarkdown from \"react-markdown\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { Textarea } from \"@/components/ui/textarea\"\nimport { cn } from \"@/lib/utils\"\n\nexport type BlocksAi05Message = {\n  content: string\n  id: string\n  role: \"assistant\" | \"user\"\n}\n\nexport type BlocksAi05Props = {\n  className?: string\n  initialMessages?: BlocksAi05Message[]\n  onSubmit?: (message: string) => Promise<string | void> | string | void\n}\n\nconst fieldworkMessages: BlocksAi05Message[] = [\n  {\n    id: \"intro\",\n    role: \"assistant\",\n    content: \"I can compare observations, trace evidence, and turn field notes into a brief. What should we examine?\",\n  },\n  {\n    id: \"question\",\n    role: \"user\",\n    content: \"Summarize the river survey in three findings.\",\n  },\n  {\n    id: \"answer\",\n    role: \"assistant\",\n    content: \"- **Water clarity improved** at four upstream sites.\\n- **Bank erosion increased** after the August storms.\\n- **Two readings need review** because their timestamps overlap.\",\n  },\n]\n\nconst suggestions = [\"Draft the field brief\", \"List evidence gaps\", \"Turn findings into tasks\"]\nconst responses = [\n  \"Here is a concise field brief:\\n\\n1. Confirm the two overlapping readings.\\n2. Compare erosion against the August rainfall log.\\n3. Preserve the upstream clarity measurements as the baseline.\",\n  \"The main evidence gaps are the missing downstream photo set and an unverified timestamp on station R-14.\",\n  \"I split the work into three tasks: verify readings, annotate the rainfall comparison, and prepare the final evidence table.\",\n]\n\nexport function BlocksAi05({ className, initialMessages = fieldworkMessages, onSubmit }: BlocksAi05Props) {\n  const [messages, setMessages] = React.useState(initialMessages)\n  const [message, setMessage] = React.useState(\"\")\n  const [submitting, setSubmitting] = React.useState(false)\n  const [atBottom, setAtBottom] = React.useState(true)\n  const scrollerRef = React.useRef<HTMLDivElement>(null)\n\n  const scrollToBottom = (behavior: ScrollBehavior = \"smooth\") => {\n    const scroller = scrollerRef.current\n    if (scroller) scroller.scrollTo({ behavior, top: scroller.scrollHeight })\n  }\n\n  React.useEffect(() => scrollToBottom(), [messages, submitting])\n\n  const send = async (text: string) => {\n    const value = text.trim()\n    if (!value || submitting) return\n    setMessages((current) => [...current, { content: value, id: `user-${Date.now()}`, role: \"user\" }])\n    setMessage(\"\")\n    setSubmitting(true)\n    try {\n      const supplied = await onSubmit?.(value)\n      await new Promise((resolve) => window.setTimeout(resolve, 650))\n      setMessages((current) => [\n        ...current,\n        {\n          content: supplied || responses[current.length % responses.length],\n          id: `assistant-${Date.now()}`,\n          role: \"assistant\",\n        },\n      ])\n    } finally {\n      setSubmitting(false)\n    }\n  }\n\n  return (\n    <div className={cn(\"w-full px-4\", className)} data-blocks-ai=\"ai-05\">\n      <div className=\"mx-auto flex h-[560px] w-full max-w-2xl flex-col overflow-hidden rounded-3xl bg-card shadow-[0_0_0_1px_oklch(0_0_0/0.06),0_1px_2px_oklch(0_0_0/0.04),0_12px_32px_-12px_oklch(0_0_0/0.18)] dark:shadow-[0_0_0_1px_oklch(1_0_0/0.1),0_12px_32px_-12px_oklch(0_0_0/0.6)]\">\n        <header className=\"flex items-center justify-between gap-4 px-5 py-4\">\n          <div className=\"flex flex-col\">\n            <span className=\"text-sm leading-tight font-semibold\">Fieldwork assistant</span>\n            <span className=\"inline-flex items-center gap-1.5 text-xs text-muted-foreground\">\n              <span className=\"size-1.5 rounded-full bg-emerald-500\" />Online\n            </span>\n          </div>\n          <div className=\"flex items-center gap-1\">\n            <Button\n              className=\"h-8 gap-1.5 px-2.5 text-xs\"\n              onClick={() => {\n                setMessages(initialMessages.slice(0, 1))\n                setMessage(\"\")\n                setSubmitting(false)\n              }}\n              size=\"sm\"\n              type=\"button\"\n              variant=\"ghost\"\n            >\n              <IconPlus className=\"size-4\" stroke={1.5} />New chat\n            </Button>\n            <Button aria-label=\"Settings\" className=\"size-8\" title=\"Settings\" type=\"button\" variant=\"ghost\">\n              <IconAdjustmentsHorizontal className=\"size-4\" stroke={1.5} />\n            </Button>\n          </div>\n        </header>\n\n        <div\n          className=\"relative min-h-0 flex-1 border-t border-border/60\"\n          role=\"log\"\n        >\n          <div\n            className=\"size-full overflow-y-auto px-5 py-5\"\n            onScroll={(event) => {\n              const target = event.currentTarget\n              setAtBottom(target.scrollHeight - target.scrollTop - target.clientHeight < 24)\n            }}\n            ref={scrollerRef}\n          >\n            <div className=\"flex flex-col gap-5\">\n              {messages.map((item) => (\n                <div className={cn(\"flex max-w-[95%] flex-col gap-2\", item.role === \"user\" && \"ml-auto items-end\")} key={item.id}>\n                  <div\n                    className={cn(\n                      \"w-fit min-w-0 max-w-full overflow-hidden text-sm leading-relaxed\",\n                      item.role === \"user\" && \"rounded-2xl rounded-br-md bg-primary px-4 py-3 text-primary-foreground\",\n                      item.role === \"assistant\" && \"max-w-prose\"\n                    )}\n                  >\n                    {item.role === \"assistant\" ? (\n                      <div className=\"[&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&_li]:my-1 [&_ol]:ml-5 [&_ol]:list-decimal [&_p]:my-2 [&_ul]:ml-5 [&_ul]:list-disc\">\n                        <ReactMarkdown>{item.content}</ReactMarkdown>\n                      </div>\n                    ) : (\n                      <p className=\"whitespace-pre-wrap\">{item.content}</p>\n                    )}\n                  </div>\n                </div>\n              ))}\n              {submitting && (\n                <output aria-label=\"Assistant is typing\" className=\"flex h-7 items-center gap-1\">\n                  {[0, 1, 2].map((dot) => (\n                    <span className=\"size-1.5 animate-bounce rounded-full bg-muted-foreground/60 motion-reduce:animate-none\" key={dot} style={{ animationDelay: `${dot * 150}ms` }} />\n                  ))}\n                </output>\n              )}\n            </div>\n          </div>\n          {!atBottom && (\n            <Button aria-label=\"Scroll to latest message\" className=\"absolute bottom-4 left-1/2 size-9 -translate-x-1/2 rounded-full\" onClick={() => scrollToBottom()} type=\"button\" variant=\"outline\">\n              <IconArrowDown className=\"size-4\" />\n            </Button>\n          )}\n        </div>\n\n        <div className=\"flex flex-col gap-3 p-3\">\n          <div className=\"flex flex-wrap gap-2 px-1\">\n            {suggestions.map((suggestion) => (\n              <button\n                className=\"rounded-full border border-border/70 bg-background px-3 py-1.5 text-xs text-muted-foreground transition-[color,background-color,transform] duration-150 hover:bg-muted hover:text-foreground active:scale-[0.96] disabled:pointer-events-none disabled:opacity-50\"\n                disabled={submitting}\n                key={suggestion}\n                onClick={() => void send(suggestion)}\n                type=\"button\"\n              >\n                {suggestion}\n              </button>\n            ))}\n          </div>\n          <form\n            className=\"overflow-hidden rounded-xl border border-border bg-muted/40 transition-[border-color,box-shadow] duration-200 focus-within:border-ring focus-within:shadow-sm\"\n            onSubmit={(event) => {\n              event.preventDefault()\n              void send(message)\n            }}\n          >\n            <Textarea\n              aria-label=\"Message fieldwork assistant\"\n              className=\"max-h-32 min-h-16 resize-none border-0 bg-transparent px-3 py-2 shadow-none focus-visible:ring-0 focus-visible:outline-none\"\n              name=\"message\"\n              onChange={(event) => setMessage(event.currentTarget.value)}\n              onKeyDown={(event) => {\n                if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n                  event.preventDefault()\n                  event.currentTarget.form?.requestSubmit()\n                }\n              }}\n              placeholder=\"Message the fieldwork assistant\"\n              value={message}\n            />\n            <div className=\"flex items-center justify-between gap-1 p-2 pt-0\">\n              <div className=\"flex items-center gap-1\">\n                <Button aria-label=\"Attach file\" className=\"size-8\" type=\"button\" variant=\"ghost\"><IconPaperclip className=\"size-4\" stroke={1.5} /></Button>\n                <Button aria-label=\"Quick prompt\" className=\"size-8\" type=\"button\" variant=\"ghost\"><IconBolt className=\"size-4\" stroke={1.5} /></Button>\n              </div>\n              <Button aria-label=\"Send message\" className=\"size-8 rounded-full transition-[transform,opacity] duration-150 active:scale-[0.96]\" disabled={!message.trim() || submitting} type=\"submit\">\n                {submitting ? <IconLoader2 className=\"size-4 animate-spin motion-reduce:animate-none\" /> : <IconArrowUp className=\"size-4\" />}\n              </Button>\n            </div>\n          </form>\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport default BlocksAi05\n"
        },
        {
          "path": "components/ui/button.tsx",
          "target": "@components/ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ui/textarea.tsx",
          "target": "@components/ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60 dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/50 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:focus-visible:ring-[3px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "file-queue",
      "type": "registry:block",
      "title": "File Queue",
      "description": "file queue",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/file-queue.tsx",
          "target": "@components/blocks-so/file-queue.tsx",
          "type": "registry:component",
          "content": "\"use client\"\nexport { FileQueue } from \"@/components/blocks-so/application/file-queue\"\nexport type {\n  FileQueueProps,\n  FileQueueItem,\n  FileQueueStatus,\n} from \"@/components/blocks-so/application/file-queue\"\n"
        },
        {
          "path": "components/blocks-so/application/file-queue.tsx",
          "target": "@components/blocks-so/application/file-queue.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { FileText, RefreshCw, Trash2, Upload } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport type FileQueueStatus = \"queued\" | \"uploading\" | \"complete\" | \"error\"\nexport interface FileQueueItem {\n  id: string\n  name: string\n  size: string\n  status: FileQueueStatus\n  progress?: number\n  error?: string\n}\nexport interface FileQueueProps {\n  files: FileQueueItem[]\n  onFilesSelected: (files: File[]) => void\n  onRemove: (id: string) => void\n  onRetry?: (id: string) => void\n  onUpload?: () => void\n  accept?: string\n  multiple?: boolean\n  maxSizeLabel?: string\n  disabled?: boolean\n  className?: string\n}\nconst statusLabel: Record<FileQueueStatus, string> = {\n  queued: \"Ready to upload\",\n  uploading: \"Uploading\",\n  complete: \"Complete\",\n  error: \"Upload failed\",\n}\nexport function FileQueue({\n  files,\n  onFilesSelected,\n  onRemove,\n  onRetry,\n  onUpload,\n  accept,\n  multiple = true,\n  maxSizeLabel = \"Maximum 10 MB per file\",\n  disabled = false,\n  className,\n}: FileQueueProps) {\n  const input = React.useRef<HTMLInputElement>(null)\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full max-w-[620px] rounded-xl border p-4\",\n        className\n      )}\n    >\n      <header>\n        <h2 className=\"text-sm font-medium\">Files</h2>\n        <p className=\"text-text-secondary mt-1 text-sm\">\n          Add supporting documents to this workspace.\n        </p>\n      </header>\n      <input\n        ref={input}\n        type=\"file\"\n        accept={accept}\n        multiple={multiple}\n        disabled={disabled}\n        className=\"sr-only\"\n        onChange={(e) => {\n          onFilesSelected(Array.from(e.target.files ?? []))\n          e.currentTarget.value = \"\"\n        }}\n      />\n      <button\n        type=\"button\"\n        disabled={disabled}\n        onClick={() => input.current?.click()}\n        onDrop={(e) => {\n          e.preventDefault()\n          if (!disabled) onFilesSelected(Array.from(e.dataTransfer.files))\n        }}\n        onDragOver={(e) => e.preventDefault()}\n        className=\"border-separator-border text-text-secondary hover:bg-background-secondary-default focus-visible:ring-border-focus-ring focus-visible:ring-offset-background mt-4 flex min-h-28 w-full items-center justify-center gap-3 rounded-lg border border-dashed px-5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50\"\n      >\n        <Upload className=\"size-5\" />\n        <span>Drop files here or choose files</span>\n      </button>\n      <p className=\"text-text-secondary mt-2 text-xs\">\n        {maxSizeLabel}\n        {accept ? ` · ${accept}` : \"\"}\n      </p>\n      {files.length ? (\n        <div className=\"divide-separator-border border-separator-border mt-5 divide-y border-y\">\n          {files.map((file) => {\n            const progress = Math.max(\n              0,\n              Math.min(\n                100,\n                file.progress ?? (file.status === \"complete\" ? 100 : 0)\n              )\n            )\n            return (\n              <div\n                key={file.id}\n                className=\"grid grid-cols-[20px_1fr_auto] gap-3 py-3\"\n              >\n                <FileText className=\"text-text-secondary mt-0.5 size-4\" />\n                <div className=\"min-w-0\">\n                  <p className=\"truncate text-sm font-medium\">{file.name}</p>\n                  <div className=\"text-text-secondary mt-1 flex justify-between text-xs\">\n                    <span>{file.size}</span>\n                    <span\n                      className={\n                        file.status === \"error\"\n                          ? \"text-red-700 dark:text-red-400\"\n                          : \"\"\n                      }\n                    >\n                      {file.error ?? statusLabel[file.status]}\n                    </span>\n                  </div>\n                  {file.status === \"uploading\" && (\n                    <div className=\"bg-background-secondary-default mt-2 h-1 overflow-hidden rounded-full\">\n                      <div\n                        className=\"bg-accent-600 h-full\"\n                        style={{ width: `${progress}%` }}\n                      />\n                    </div>\n                  )}\n                </div>\n                <div className=\"flex gap-1\">\n                  {file.status === \"error\" && onRetry && (\n                    <Button\n                      variant=\"ghost\"\n                      size=\"xs\"\n                      iconOnly\n                      aria-label={`Retry ${file.name}`}\n                      onClick={() => onRetry(file.id)}\n                    >\n                      <RefreshCw />\n                    </Button>\n                  )}\n                  <Button\n                    variant=\"ghost\"\n                    size=\"xs\"\n                    iconOnly\n                    aria-label={`Remove ${file.name}`}\n                    onClick={() => onRemove(file.id)}\n                  >\n                    <Trash2 />\n                  </Button>\n                </div>\n              </div>\n            )\n          })}\n        </div>\n      ) : (\n        <p className=\"border-separator-border text-text-secondary mt-5 border-y py-4 text-sm\">\n          No files selected.\n        </p>\n      )}\n      <div className=\"mt-4 flex justify-end\">\n        <Button\n          onClick={onUpload}\n          disabled={\n            disabled ||\n            !files.length ||\n            files.some((f) => f.status === \"uploading\")\n          }\n        >\n          Upload {files.length ? files.length : \"files\"}\n        </Button>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "setup-checklist",
      "type": "registry:block",
      "title": "Setup Checklist",
      "description": "setup checklist",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/setup-checklist.tsx",
          "target": "@components/blocks-so/setup-checklist.tsx",
          "type": "registry:component",
          "content": "\"use client\"\nexport { SetupChecklist } from \"@/components/blocks-so/application/setup-checklist\"\nexport type {\n  SetupChecklistProps,\n  SetupStep,\n} from \"@/components/blocks-so/application/setup-checklist\"\n"
        },
        {
          "path": "components/blocks-so/application/setup-checklist.tsx",
          "target": "@components/blocks-so/application/setup-checklist.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Circle } from \"lucide-react\"\n\nexport interface SetupStep {\n  id: string\n  title: string\n  description: string\n  completed: boolean\n  disabled?: boolean\n}\nexport interface SetupChecklistProps {\n  title: string\n  description?: string\n  steps: SetupStep[]\n  selectedStepId?: string\n  onSelectStep?: (id: string) => void\n  onStepComplete?: (id: string, completed: boolean) => void\n  onContinue?: (id: string) => void\n  className?: string\n}\nexport function SetupChecklist({\n  title,\n  description,\n  steps,\n  selectedStepId,\n  onSelectStep,\n  onStepComplete,\n  onContinue,\n  className,\n}: SetupChecklistProps) {\n  const completed = steps.filter((step) => step.completed).length\n  const selected =\n    steps.find((step) => step.id === selectedStepId) ??\n    steps.find((step) => !step.completed)\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full max-w-[620px] rounded-xl border p-4\",\n        className\n      )}\n    >\n      <header>\n        <div className=\"flex items-start justify-between gap-4\">\n          <div>\n            <h2 className=\"text-sm font-medium\">{title}</h2>\n            {description && (\n              <p className=\"text-text-secondary mt-1 text-sm\">{description}</p>\n            )}\n          </div>\n          <span className=\"text-text-secondary text-xs\">\n            {completed} of {steps.length}\n          </span>\n        </div>\n        <div className=\"bg-background-secondary-default mt-4 h-1.5 overflow-hidden rounded-full\">\n          <div\n            className=\"bg-accent-600 h-full transition-[width] duration-150\"\n            style={{\n              width: `${steps.length ? (completed / steps.length) * 100 : 0}%`,\n            }}\n          />\n        </div>\n      </header>\n      <ol className=\"divide-separator-border border-separator-border mt-4 divide-y border-y\">\n        {steps.map((step, index) => {\n          const active = step.id === selected?.id\n          return (\n            <li\n              key={step.id}\n              className={cx(\n                \"grid grid-cols-[24px_1fr_auto] gap-3 py-3\",\n                active && \"bg-background-secondary-default\"\n              )}\n            >\n              <button\n                type=\"button\"\n                disabled={step.disabled}\n                onClick={() => onStepComplete?.(step.id, !step.completed)}\n                aria-label={`${step.completed ? \"Mark incomplete\" : \"Mark complete\"}: ${step.title}`}\n                className=\"focus-visible:ring-border-focus-ring focus-visible:ring-offset-background mt-0.5 flex size-6 items-center justify-center rounded-full outline-none focus-visible:ring-2 focus-visible:ring-offset-2\"\n              >\n                {step.completed ? (\n                  <Check className=\"size-4 text-green-600\" />\n                ) : (\n                  <Circle className=\"text-text-secondary size-4\" />\n                )}\n              </button>\n              <button\n                type=\"button\"\n                disabled={step.disabled}\n                onClick={() => onSelectStep?.(step.id)}\n                className=\"focus-visible:ring-border-focus-ring focus-visible:ring-offset-background rounded-md text-left outline-none focus-visible:ring-2 focus-visible:ring-offset-2\"\n              >\n                <span\n                  className={cx(\n                    \"text-sm font-medium\",\n                    step.completed && \"text-text-secondary line-through\"\n                  )}\n                >\n                  {index + 1}. {step.title}\n                </span>\n                <span className=\"text-text-secondary mt-1 block text-sm leading-6\">\n                  {step.description}\n                </span>\n              </button>\n              {active && !step.completed && (\n                <Button\n                  variant=\"secondary\"\n                  size=\"small\"\n                  onClick={() => onContinue?.(step.id)}\n                >\n                  Continue\n                </Button>\n              )}\n            </li>\n          )\n        })}\n      </ol>\n      {steps.length === 0 && (\n        <p className=\"text-text-secondary py-6 text-center text-sm\">\n          No setup steps.\n        </p>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "task-table",
      "type": "registry:block",
      "title": "Task Table",
      "description": "task table",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/task-table.tsx",
          "target": "@components/blocks-so/task-table.tsx",
          "type": "registry:component",
          "content": "\"use client\"\nexport { TaskTable } from \"@/components/blocks-so/application/task-table\"\nexport type {\n  TaskTableProps,\n  TaskTableItem,\n  TaskStatus,\n  TaskPriority,\n} from \"@/components/blocks-so/application/task-table\"\n"
        },
        {
          "path": "components/blocks-so/application/task-table.tsx",
          "target": "@components/blocks-so/application/task-table.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Eye, Pause, Play, Trash2 } from \"lucide-react\"\n\nexport type TaskStatus =\n  | \"pending\"\n  | \"in-progress\"\n  | \"completed\"\n  | \"blocked\"\n  | \"paused\"\nexport type TaskPriority = \"low\" | \"medium\" | \"high\" | \"urgent\"\nexport interface TaskTableItem {\n  id: string\n  title: string\n  assignee?: string\n  status: TaskStatus\n  priority?: TaskPriority\n  dueDate?: string\n  notes?: string\n}\nexport interface TaskTableProps {\n  tasks: TaskTableItem[]\n  pendingAction?: {\n    taskId: string\n    action: \"start\" | \"pause\" | \"complete\" | \"delete\" | \"view\"\n  } | null\n  onStart?: (task: TaskTableItem) => void\n  onPause?: (task: TaskTableItem) => void\n  onComplete?: (task: TaskTableItem) => void\n  onDelete?: (task: TaskTableItem) => void\n  onView?: (task: TaskTableItem) => void\n  emptyMessage?: string\n  className?: string\n}\nconst statusStyle: Record<TaskStatus, string> = {\n  pending: \"text-text-secondary\",\n  \"in-progress\": \"text-accent-600\",\n  completed: \"text-green-700 dark:text-green-400\",\n  blocked: \"text-red-700 dark:text-red-400\",\n  paused: \"text-amber-700 dark:text-amber-400\",\n}\nconst label: Record<TaskStatus, string> = {\n  pending: \"Pending\",\n  \"in-progress\": \"In progress\",\n  completed: \"Completed\",\n  blocked: \"Blocked\",\n  paused: \"Paused\",\n}\nexport function TaskTable({\n  tasks,\n  pendingAction,\n  onStart,\n  onPause,\n  onComplete,\n  onDelete,\n  onView,\n  emptyMessage = \"No tasks in this workspace.\",\n  className,\n}: TaskTableProps) {\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border border-b p-4\">\n        <h2 className=\"text-sm font-medium\">Tasks</h2>\n        <p className=\"text-text-secondary mt-1 text-xs\">{tasks.length} items</p>\n      </header>\n      <div className=\"overflow-x-auto\">\n        <table className=\"w-full min-w-[820px] text-left text-sm\">\n          <thead className=\"bg-background-secondary-default text-text-secondary text-xs\">\n            <tr>\n              <th className=\"px-4 py-3 font-medium\">Task</th>\n              <th className=\"px-4 py-3 font-medium\">Assignee</th>\n              <th className=\"px-4 py-3 font-medium\">Status</th>\n              <th className=\"px-4 py-3 font-medium\">Due</th>\n              <th className=\"px-4 py-3 font-medium\">Priority</th>\n              <th className=\"px-4 py-3 font-medium\">Actions</th>\n            </tr>\n          </thead>\n          <tbody className=\"divide-separator-border divide-y\">\n            {tasks.map((task) => {\n              const busy = pendingAction?.taskId === task.id\n              return (\n                <tr\n                  key={task.id}\n                  className=\"hover:bg-background-secondary-default\"\n                >\n                  <td className=\"max-w-72 px-4 py-3\">\n                    <p className=\"font-medium\">{task.title}</p>\n                    {task.notes && (\n                      <p className=\"text-text-secondary mt-1 truncate text-xs\">\n                        {task.notes}\n                      </p>\n                    )}\n                  </td>\n                  <td className=\"text-text-secondary px-4 py-3\">\n                    {task.assignee ?? \"Unassigned\"}\n                  </td>\n                  <td\n                    className={cx(\n                      \"px-4 py-3 text-xs font-medium\",\n                      statusStyle[task.status]\n                    )}\n                  >\n                    {busy\n                      ? `${pendingAction.action} in progress`\n                      : label[task.status]}\n                  </td>\n                  <td className=\"text-text-secondary px-4 py-3\">\n                    {task.dueDate ?? \"No due date\"}\n                  </td>\n                  <td className=\"text-text-secondary px-4 py-3\">\n                    {task.priority ?? \"Normal\"}\n                  </td>\n                  <td className=\"px-4 py-3\">\n                    <div className=\"flex items-center gap-1\">\n                      {(task.status === \"pending\" ||\n                        task.status === \"blocked\" ||\n                        task.status === \"paused\") && (\n                        <Button\n                          variant=\"secondary\"\n                          size=\"xs\"\n                          leadingIcon={Play}\n                          disabled={busy}\n                          onClick={() => onStart?.(task)}\n                        >\n                          Start\n                        </Button>\n                      )}\n                      {task.status === \"in-progress\" && (\n                        <>\n                          <Button\n                            variant=\"ghost\"\n                            size=\"xs\"\n                            leadingIcon={Pause}\n                            disabled={busy}\n                            onClick={() => onPause?.(task)}\n                          >\n                            Pause\n                          </Button>\n                          <Button\n                            variant=\"secondary\"\n                            size=\"xs\"\n                            leadingIcon={Check}\n                            disabled={busy}\n                            onClick={() => onComplete?.(task)}\n                          >\n                            Complete\n                          </Button>\n                        </>\n                      )}\n                      <Button\n                        variant=\"ghost\"\n                        size=\"xs\"\n                        iconOnly\n                        disabled={busy}\n                        aria-label={`View ${task.title}`}\n                        onClick={() => onView?.(task)}\n                      >\n                        <Eye />\n                      </Button>\n                      <Button\n                        variant=\"ghost\"\n                        size=\"xs\"\n                        iconOnly\n                        disabled={busy}\n                        aria-label={`Delete ${task.title}`}\n                        onClick={() => onDelete?.(task)}\n                      >\n                        <Trash2 />\n                      </Button>\n                    </div>\n                  </td>\n                </tr>\n              )\n            })}\n          </tbody>\n        </table>\n      </div>\n      {tasks.length === 0 && (\n        <p className=\"text-text-secondary p-8 text-center text-sm\">\n          {emptyMessage}\n        </p>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "workspace-composer",
      "type": "registry:block",
      "title": "Workspace Composer",
      "description": "workspace composer",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/blocks-so/workspace-composer.tsx",
          "target": "@components/blocks-so/workspace-composer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\nexport { WorkspaceComposer } from \"@/components/blocks-so/application/workspace-composer\"\nexport type {\n  WorkspaceComposerProps,\n  WorkspaceAttachment,\n  WorkspaceModelOption,\n} from \"@/components/blocks-so/application/workspace-composer\"\n"
        },
        {
          "path": "components/blocks-so/application/workspace-composer.tsx",
          "target": "@components/blocks-so/application/workspace-composer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { Select, SelectItem } from \"@/components/boardui/base/select/select\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { ArrowUp, Paperclip, Square, X } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport interface WorkspaceAttachment {\n  id: string\n  name: string\n  size?: string\n}\nexport interface WorkspaceModelOption {\n  id: string\n  label: string\n}\nexport interface WorkspaceComposerProps {\n  value: string\n  onValueChange: (value: string) => void\n  onSubmit: (value: string) => void\n  model: string\n  models: WorkspaceModelOption[]\n  onModelChange: (model: string) => void\n  contextLabel?: string\n  contextOptions?: string[]\n  onContextChange?: (context: string) => void\n  attachments?: WorkspaceAttachment[]\n  onFilesSelected?: (files: File[]) => void\n  onRemoveAttachment?: (id: string) => void\n  disabled?: boolean\n  isRunning?: boolean\n  onStop?: () => void\n  placeholder?: string\n  className?: string\n}\nexport function WorkspaceComposer({\n  value,\n  onValueChange,\n  onSubmit,\n  model,\n  models,\n  onModelChange,\n  contextLabel = \"Workspace context\",\n  contextOptions = [],\n  onContextChange,\n  attachments = [],\n  onFilesSelected,\n  onRemoveAttachment,\n  disabled = false,\n  isRunning = false,\n  onStop,\n  placeholder = \"Ask the agent to investigate, draft, or update work\",\n  className,\n}: WorkspaceComposerProps) {\n  const input = React.useRef<HTMLInputElement>(null)\n  const submit = () => {\n    const text = value.trim()\n    if (text && !disabled && !isRunning) onSubmit(text)\n  }\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full max-w-[760px] rounded-xl border p-3\",\n        className\n      )}\n    >\n      <div className=\"border-separator-border text-text-secondary flex flex-wrap items-center gap-2 border-b pb-2 text-xs\">\n        <span>{contextLabel}</span>\n        {contextOptions.length > 0 && (\n          <Select\n            aria-label=\"Workspace context\"\n            selectedKey={contextLabel}\n            onSelectionChange={(key) => onContextChange?.(String(key))}\n            size=\"sm\"\n            triggerClassName=\"border-0 shadow-none\"\n          >\n            <>\n              {contextOptions.map((option) => (\n                <SelectItem key={option} id={option}>\n                  {option}\n                </SelectItem>\n              ))}\n            </>\n          </Select>\n        )}\n      </div>\n      {attachments.length > 0 && (\n        <div className=\"flex flex-wrap gap-2 pt-3\">\n          {attachments.map((file) => (\n            <span\n              key={file.id}\n              className=\"border-separator-border inline-flex min-h-8 items-center gap-2 rounded-lg border px-2 text-xs\"\n            >\n              <Paperclip className=\"text-text-secondary size-3.5\" />\n              <span className=\"max-w-40 truncate\">{file.name}</span>\n              {file.size && (\n                <span className=\"text-text-secondary\">{file.size}</span>\n              )}\n              <button\n                type=\"button\"\n                aria-label={`Remove ${file.name}`}\n                onClick={() => onRemoveAttachment?.(file.id)}\n                className=\"hover:bg-background-secondary-default rounded-sm p-1\"\n              >\n                <X className=\"size-3\" />\n              </button>\n            </span>\n          ))}\n        </div>\n      )}\n      <textarea\n        aria-label={placeholder}\n        value={value}\n        onChange={(e) => onValueChange(e.target.value)}\n        onKeyDown={(e) => {\n          if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n            e.preventDefault()\n            submit()\n          }\n        }}\n        disabled={disabled}\n        placeholder={placeholder}\n        rows={4}\n        className=\"text-text-primary placeholder:text-text-tertiary mt-2 min-h-24 w-full resize-y bg-transparent p-1 text-sm leading-6 outline-none disabled:cursor-not-allowed disabled:opacity-60\"\n      />\n      <div className=\"mt-2 flex flex-wrap items-center justify-between gap-2\">\n        <div className=\"flex items-center gap-2\">\n          <input\n            ref={input}\n            type=\"file\"\n            multiple\n            className=\"sr-only\"\n            onChange={(e) => {\n              onFilesSelected?.(Array.from(e.target.files ?? []))\n              e.currentTarget.value = \"\"\n            }}\n          />\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            leadingIcon={Paperclip}\n            onClick={() => input.current?.click()}\n          >\n            Attach\n          </Button>\n          <Select\n            aria-label=\"Model\"\n            selectedKey={model}\n            onSelectionChange={(key) => onModelChange(String(key))}\n            size=\"sm\"\n          >\n            {models.map((option) => (\n              <SelectItem key={option.id} id={option.id}>\n                {option.label}\n              </SelectItem>\n            ))}\n          </Select>\n        </div>\n        {isRunning ? (\n          <Button\n            variant=\"secondary\"\n            iconOnly\n            aria-label=\"Stop generation\"\n            onClick={onStop}\n          >\n            <Square />\n          </Button>\n        ) : (\n          <Button\n            iconOnly\n            aria-label=\"Send message\"\n            disabled={disabled || !value.trim()}\n            onClick={submit}\n          >\n            <ArrowUp />\n          </Button>\n        )}\n      </div>\n      <p className=\"border-separator-border text-text-secondary mt-3 border-t pt-3 text-xs\">\n        {attachments.length} files · {contextLabel} ·{\" \"}\n        {isRunning ? \"Working\" : \"Ready\"}\n      </p>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/base/select/select.tsx",
          "target": "@components/boardui/base/select/select.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { createContext, useContext, useRef, useState } from \"react\";\nimport type { ReactNode, Ref } from \"react\";\nimport {\n  Button as AriaButton,\n  ListBox as AriaListBox,\n  ListBoxItem as AriaListBoxItem,\n  Popover as AriaPopover,\n  Select as AriaSelect,\n  SelectValue as AriaSelectValue,\n} from \"react-aria-components\";\nimport type {\n  ListBoxItemProps as AriaListBoxItemProps,\n  SelectProps as AriaSelectProps,\n  SelectValueRenderProps as AriaSelectValueRenderProps,\n} from \"react-aria-components\";\nimport {\n  MENU_ITEM,\n  MENU_ITEM_ACTIVE,\n  MENU_ITEMS_CONTAINER,\n  MENU_POPOVER_SURFACE,\n  MENU_POPOVER_WIDTH,\n} from \"@/components/boardui/base/dropdown/menu-styles\";\nimport { ChevronDownSmall } from \"@/components/boardui/foundations/icons/chevrons\";\nimport { cx } from \"@/components/boardui/utils/cx\";\nimport { useDismissOnOutsidePress, useTriggerToggle } from \"@/components/boardui/utils/use-dismiss-on-outside-press\";\n\n/**\n * Figma source: Board UI → dashboard 1 dropdown triggers (\"All prices\" filter\n * node 3731:3208, table status dropdown node 3731:3264).\n *\n * Select with a button trigger styled 1:1 with Figma:\n *   trigger  bg color/white, 1px border/button/default, shadow/xs,\n *            px 10 py 8, radius/2lg (10px), gap 6,\n *            Body 1/Medium text color/neutral/950,\n *            16px chevron (custom stroke glyph) in text/secondary\n *\n * The open popover/listbox shares the BoardUI menu recipe with Dropdown:\n * radius/2xl panel, p 10, shadow/dropdown, 150ms fade/scale/blur motion,\n * and radius/2lg rows with the same hover/selected surface.\n *\n * Item content is free-form: pass a `StatusDot` + text for status selects.\n */\n\nexport type SelectSize = \"sm\" | \"md\";\n\nconst SelectSizeContext = createContext<SelectSize>(\"md\");\n\nexport interface SelectProps<T extends object>\n  extends Omit<AriaSelectProps<T>, \"children\"> {\n  /** Trigger width. Defaults to hug content; the menu uses the shared 266px width. */\n  className?: string;\n  triggerClassName?: string;\n  /** Classes for the open popover (e.g. constrain its width). */\n  popoverClassName?: string;\n  /** `md` (default) or `sm` for compact/dense contexts (e.g. compact tables). */\n  size?: SelectSize;\n  children: ReactNode;\n  items?: Iterable<T>;\n  /** Customise the trigger's rendered value (e.g. a compact flag + dial code).\n   *  Falls back to the selected item's own content when omitted. */\n  renderValue?: ReactNode | ((values: AriaSelectValueRenderProps<T>) => ReactNode);\n  ref?: Ref<HTMLDivElement>;\n}\n\nexport function Select<T extends object>({\n  className,\n  triggerClassName,\n  popoverClassName,\n  size = \"md\",\n  children,\n  items,\n  renderValue,\n  ref,\n  ...props\n}: SelectProps<T>) {\n  // The popover is `isNonModal`: react-aria's modal scroll lock puts\n  // `overflow: hidden` on <html>, which - with this app's `h-full` root -\n  // collapses the page scroll position and visibly yanks the sticky\n  // sidebar upward every time a select opens. Non-modal skips the lock,\n  // but also disables react-aria's outside-press dismissal (`isDismissable`\n  // is hard-coupled to `!isNonModal` in usePopover), so open state is\n  // controlled here and dismissal restored manually - the same fix as the\n  // date-picker family (see utils/use-dismiss-on-outside-press.ts).\n  const triggerRef = useRef<HTMLButtonElement>(null);\n  const popoverRef = useRef<HTMLElement>(null);\n  const [isOpen, setIsOpen] = useState(false);\n  useDismissOnOutsidePress(isOpen, () => setIsOpen(false), [triggerRef, popoverRef]);\n  // Pressing the trigger while open closes the popover instead of reopening\n  const allowOpenChange = useTriggerToggle(isOpen, triggerRef);\n\n  return (\n    <AriaSelect\n      ref={ref}\n      {...props}\n      isOpen={isOpen}\n      onOpenChange={(o) => allowOpenChange(o) && setIsOpen(o)}\n      className={cx(\"group flex flex-col\", className)}\n    >\n      {({ isOpen }) => (\n        <>\n          <AriaButton\n            ref={triggerRef}\n            className={cx(\n              \"flex w-full cursor-pointer items-center justify-between rounded-2lg\",\n              \"border border-border-button-default bg-background-primary-default shadow-xs\",\n              \"text-text-primary\",\n              \"transition-[background-color,border-color,box-shadow,padding,font-size] duration-200 ease\",\n              \"hover:bg-background-primary-hover hover:border-border-button-hover\",\n              \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n              \"disabled:cursor-not-allowed disabled:bg-background-primary-disabled disabled:text-text-tertiary disabled:shadow-none\",\n              size === \"sm\"\n                ? \"gap-1 px-[7px] py-1 text-body-2-medium\"\n                : \"gap-1.5 px-2.5 py-2 text-body-medium\",\n              triggerClassName,\n            )}\n          >\n            <AriaSelectValue\n              className={cx(\n                \"flex min-w-0 items-center truncate\",\n                size === \"sm\" ? \"gap-1\" : \"gap-[5px]\",\n              )}\n            >\n              {renderValue as never /* RAC accepts node or render-prop */}\n            </AriaSelectValue>\n            <ChevronDownSmall\n              className={cx(\n                \"shrink-0 text-text-secondary transition-transform duration-200 ease\",\n                size === \"sm\" ? \"size-3.5\" : \"size-4\",\n                isOpen && \"rotate-180\",\n              )}\n            />\n          </AriaButton>\n          <AriaPopover\n            ref={popoverRef}\n            isNonModal\n            offset={4}\n            className={cx(\n              MENU_POPOVER_WIDTH,\n              MENU_POPOVER_SURFACE,\n              // Listbox rows already space themselves 4px apart, so the\n              // surface sits a touch tighter than the action-menu Dropdown.\n              \"p-2\",\n              popoverClassName,\n            )}\n          >\n            <AriaListBox\n              items={items}\n              className={cx(MENU_ITEMS_CONTAINER, \"max-h-[240px] overflow-auto\")}\n            >\n              <SelectSizeContext.Provider value={size}>{children}</SelectSizeContext.Provider>\n            </AriaListBox>\n          </AriaPopover>\n        </>\n      )}\n    </AriaSelect>\n  );\n}\n\nexport interface SelectItemProps extends Omit<AriaListBoxItemProps, \"children\"> {\n  children?: ReactNode;\n}\n\nexport function SelectItem({ className, children, ...props }: SelectItemProps) {\n  const size = useContext(SelectSizeContext);\n  return (\n    <AriaListBoxItem\n      {...props}\n      className={(state) =>\n        cx(\n          MENU_ITEM,\n          size === \"sm\" ? \"px-2 py-1.5 text-body-2-medium\" : \"text-body-medium\",\n          (state.isFocused || state.isSelected) && MENU_ITEM_ACTIVE,\n          state.isDisabled && \"cursor-not-allowed text-text-disabled\",\n          typeof className === \"function\" ? className(state) : className,\n        )\n      }\n    >\n      {children}\n    </AriaListBoxItem>\n  );\n}\n"
        },
        {
          "path": "components/boardui/base/dropdown/menu-styles.ts",
          "target": "@components/boardui/base/dropdown/menu-styles.ts",
          "type": "registry:component",
          "content": "/**\n * Shared visual recipe for BoardUI menu surfaces.\n *\n * Select and Dropdown intentionally keep their distinct React Aria semantics\n * (single-value listbox vs. action menu), while consuming the same panel,\n * motion, and row treatments from here.\n */\nexport const MENU_POPOVER_SURFACE = [\n  \"max-w-[calc(100vw-32px)] overflow-y-auto\",\n  \"rounded-2xl border border-border-button-default bg-background-primary-default p-2.5 shadow-dropdown\",\n  \"transition duration-150 ease-out\",\n  \"data-[entering]:opacity-0 data-[entering]:scale-95 data-[entering]:blur-[2px]\",\n  \"data-[exiting]:opacity-0 data-[exiting]:scale-95 data-[exiting]:blur-[2px]\",\n  \"data-[placement=bottom]:origin-top-left data-[placement=top]:origin-bottom-left\",\n  \"data-[placement=left]:origin-right data-[placement=right]:origin-left\",\n].join(\" \");\n\nexport const MENU_POPOVER_WIDTH = \"w-[266px]\";\n\nexport const MENU_ITEMS_CONTAINER = \"flex w-full flex-col gap-1 outline-none\";\n\nexport const MENU_ITEM = [\n  \"flex w-full cursor-pointer items-center gap-2 rounded-2lg p-2 text-left\",\n  \"text-text-primary outline-none transition-colors\",\n].join(\" \");\n\nexport const MENU_ITEM_ACTIVE = \"bg-dropdown-item-hover-background\";\n\nexport const MENU_ITEM_INTERACTIVE =\n  \"hover:bg-dropdown-item-hover-background focus-visible:bg-dropdown-item-hover-background\";\n"
        },
        {
          "path": "components/boardui/foundations/icons/chevrons.tsx",
          "target": "@components/boardui/foundations/icons/chevrons.tsx",
          "type": "registry:component",
          "content": "import type { SVGProps } from \"react\";\n\n/**\n * Custom chevron glyphs drawn as vectors in the Board UI Figma file (they are\n * not Remix icons). Paths are copied 1:1 from the Figma export.\n *\n * All icons render `currentColor` and size via Tailwind `size-*` utilities,\n * exactly like the Remix icon components.\n */\n\ntype IconProps = SVGProps<SVGSVGElement>;\n\n/** 16×16 rounded 2px-stroke chevron. Select triggers, disclosure affordances. */\nexport function ChevronDownSmall(props: IconProps) {\n  return (\n    <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden {...props}>\n      <path\n        d=\"M4 7L7.29289 10.2929C7.68342 10.6834 8.31658 10.6834 8.70711 10.2929L12 7\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n      />\n    </svg>\n  );\n}\n\n/** 12×12 rounded 1.5px-stroke chevron. Breadcrumb separator. */\nexport function ChevronRightSmall(props: IconProps) {\n  return (\n    <svg viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden {...props}>\n      <path\n        d=\"M4.5 3L7.14645 5.64645C7.34171 5.84171 7.34171 6.15829 7.14645 6.35355L4.5 9\"\n        stroke=\"currentColor\"\n        strokeWidth=\"1.5\"\n        strokeLinecap=\"round\"\n      />\n    </svg>\n  );\n}\n\n/** 16×16 stacked up/down chevrons. Workspace / account switchers. */\nexport function ChevronUpDownSmall(props: IconProps) {\n  return (\n    <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden {...props}>\n      <g transform=\"translate(4.25 2.56)\">\n        <path\n          d=\"M0.75 7.43934L3.21967 9.90901C3.51256 10.2019 3.98744 10.2019 4.28033 9.90901L6.75 7.43934\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.5\"\n          strokeLinecap=\"round\"\n        />\n        <path\n          d=\"M0.75 3.43934L3.21967 0.96967C3.51256 0.676777 3.98744 0.676777 4.28033 0.96967L6.75 3.43934\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.5\"\n          strokeLinecap=\"round\"\n        />\n      </g>\n    </svg>\n  );\n}\n\n/** 24×24 filled rounded triangle chevron. Table column sort indicator. */\nexport function ChevronSortDown(props: IconProps) {\n  return (\n    <svg viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden {...props}>\n      <path\n        d=\"M12.7071 15.2929C12.3166 15.6834 11.6834 15.6834 11.2929 15.2929L7.70711 11.7071C7.07714 11.0771 7.52331 10 8.41421 10H15.5858C16.4767 10 16.9229 11.0771 16.2929 11.7071L12.7071 15.2929Z\"\n        fill=\"currentColor\"\n      />\n    </svg>\n  );\n}\n"
        },
        {
          "path": "components/boardui/utils/use-dismiss-on-outside-press.ts",
          "target": "@components/boardui/utils/use-dismiss-on-outside-press.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport type { RefObject } from \"react\";\n\n/**\n * React Aria's `Popover` couples \"non-modal\" with \"not dismissable on\n * outside interaction\" — `isNonModal` (which we set to avoid the scroll\n * lock / focus trap that comes with a modal popover) also silently disables\n * its built-in outside-click-to-close behavior. This restores just that\n * piece manually: closes when a pointerdown lands outside every given ref\n * (typically the trigger + the popover's own content).\n */\nexport function useDismissOnOutsidePress(\n  isOpen: boolean,\n  onDismiss: () => void,\n  refs: RefObject<HTMLElement | null>[],\n) {\n  useEffect(() => {\n    if (!isOpen) return;\n\n    const handlePointerDown = (event: PointerEvent) => {\n      const target = event.target as Node;\n      if (refs.some((ref) => ref.current?.contains(target))) return;\n      onDismiss();\n    };\n\n    document.addEventListener(\"pointerdown\", handlePointerDown, true);\n    return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n  }, [isOpen, onDismiss, refs]);\n}\n\n/**\n * Companion fix for the same `isNonModal` popovers: pressing the trigger\n * while the popover is open should close it (toggle), but React Aria fires\n * `onOpenChange(false)` immediately followed by `onOpenChange(true)` within\n * the same press, so the popover never actually closes.\n *\n * This watches for a pointerdown on the trigger while open and swallows the\n * spurious reopen that follows. Wire the returned guard into the component's\n * `onOpenChange`:\n *\n *   const allowOpenChange = useTriggerToggle(isOpen, triggerRef);\n *   <AriaSelect onOpenChange={(o) => allowOpenChange(o) && setIsOpen(o)} …\n */\nexport function useTriggerToggle(\n  isOpen: boolean,\n  triggerRef: RefObject<HTMLElement | null>,\n) {\n  const suppressReopenRef = useRef(false);\n\n  useEffect(() => {\n    if (!isOpen) return;\n\n    const handlePointerDown = (event: PointerEvent) => {\n      if (!triggerRef.current?.contains(event.target as Node)) return;\n      suppressReopenRef.current = true;\n      // Safety valve: only the very next open within this click may be\n      // swallowed; never leave a stale suppression behind.\n      setTimeout(() => {\n        suppressReopenRef.current = false;\n      }, 400);\n    };\n\n    document.addEventListener(\"pointerdown\", handlePointerDown, true);\n    return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n  }, [isOpen, triggerRef]);\n\n  return (next: boolean) => {\n    if (next && suppressReopenRef.current) {\n      suppressReopenRef.current = false;\n      return false;\n    }\n    return true;\n  };\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/blocks-so/SOURCE.json",
          "target": "@components/blocks-so/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Blocks.so adapted compositions\",\n  \"upstream\": \"https://github.com/ephraimduncan/blocks\",\n  \"revision\": \"e4fdf6c4b31bb95ddbccf2c919478672bc61226b\",\n  \"license\": \"MIT\",\n  \"sourceFiles\": [\n    \"content/components/ai/ai-01.tsx\",\n    \"content/components/ai/ai-02.tsx\",\n    \"content/components/ai/ai-03.tsx\",\n    \"content/components/ai/ai-04.tsx\",\n    \"content/components/ai/ai-05.tsx\",\n    \"components/ai-elements/conversation.tsx\",\n    \"components/ai-elements/message.tsx\",\n    \"components/ai-elements/prompt-input.tsx\",\n    \"content/components/file-upload/file-upload-05.tsx\",\n    \"content/components/onboarding/onboarding-03.tsx\",\n    \"content/components/tables/table-02.tsx\"\n  ],\n  \"adaptation\": \"Public AI blocks retain upstream layouts, controls, interaction states, transitions, attachment handling, and response animation. Import paths, host theme tokens, reusable callbacks, and demo fixture copy were adapted for Agents Kit. Existing application compositions remain controlled adaptations. Card insets and AI starter headings follow the shared compact Agents Kit design system.\"\n}\n"
        },
        {
          "path": "components/blocks-so/LICENSE.md",
          "target": "@components/blocks-so/LICENSE.md",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Blocks.so"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-agent-screen",
      "type": "registry:block",
      "title": "Beautiful Agent Screen",
      "description": "agent screen",
      "dependencies": [
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/agent-screen.tsx",
          "target": "@components/beautiful-ui/agent-screen.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  Check,\n  Circle,\n  LoaderCircle,\n  Maximize2,\n  Minimize2,\n  Pause,\n  Play,\n  Radio,\n  Square,\n} from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport * as React from \"react\"\n\nexport type AgentScreenVariant = \"working\" | \"loading\"\nexport interface AgentScreenStep {\n  id: string\n  label: string\n  status: \"pending\" | \"running\" | \"complete\"\n}\nexport interface AgentScreenProps {\n  title: string\n  description?: string\n  steps?: AgentScreenStep[]\n  variant?: AgentScreenVariant\n  mediaSrc?: string\n  mediaType?: \"image\" | \"video\"\n  expanded?: boolean\n  recording?: boolean\n  recordingElapsed?: string\n  paused?: boolean\n  onExpandedChange?: (expanded: boolean) => void\n  onStartRecording?: () => void\n  onEndRecording?: () => void\n  onPause?: () => void\n  onResume?: () => void\n  className?: string\n}\nfunction ScreenMedia({\n  src,\n  type,\n  loading,\n  expanded,\n  reduce,\n}: {\n  src?: string\n  type?: \"image\" | \"video\"\n  loading: boolean\n  expanded: boolean\n  reduce: boolean\n}) {\n  const video =\n    type === \"video\" || /\\.(mp4|webm|mov|m4v)(\\?|$)/i.test(src ?? \"\")\n  const key = loading ? \"loading\" : src ? `${type ?? \"media\"}-${src}` : \"empty\"\n  return (\n    <div\n      className={cx(\n        \"aspect-video w-full overflow-hidden\",\n        expanded && \"max-h-[calc(100vh-12rem)]\"\n      )}\n    >\n      <AnimatePresence initial={false} mode=\"wait\">\n        <motion.div\n          key={key}\n          initial={reduce ? false : { opacity: 0, y: 4 }}\n          animate={{ opacity: 1, y: 0 }}\n          exit={reduce ? undefined : { opacity: 0, y: -4 }}\n          transition={{ duration: reduce ? 0 : 0.18 }}\n          className=\"h-full w-full\"\n        >\n          {loading ? (\n            <div className=\"bg-background-secondary-default text-text-secondary flex h-full items-center justify-center gap-2 text-sm\">\n              <LoaderCircle\n                className={cx(\"size-5\", !reduce && \"animate-spin\")}\n              />\n              Connecting to agent screen\n            </div>\n          ) : !src ? (\n            <div className=\"bg-background-secondary-default text-text-secondary flex h-full items-center justify-center text-sm\">\n              No screen media supplied\n            </div>\n          ) : video ? (\n            <video\n              src={src}\n              autoPlay\n              muted\n              loop\n              playsInline\n              className=\"h-full w-full bg-black object-contain\"\n            />\n          ) : (\n            // Caller-provided screen captures may be remote or data URLs and cannot use a fixed Next image loader.\n            // eslint-disable-next-line @next/next/no-img-element\n            <img\n              src={src}\n              alt=\"Agent screen\"\n              className=\"bg-background-secondary-default h-full w-full object-contain\"\n            />\n          )}\n        </motion.div>\n      </AnimatePresence>\n    </div>\n  )\n}\nexport function AgentScreen({\n  title,\n  description,\n  steps = [],\n  variant = \"working\",\n  mediaSrc,\n  mediaType,\n  expanded,\n  recording = false,\n  recordingElapsed,\n  paused = false,\n  onExpandedChange,\n  onStartRecording,\n  onEndRecording,\n  onPause,\n  onResume,\n  className,\n}: AgentScreenProps) {\n  const reduce = useReducedMotion() ?? false\n  const [localExpanded, setLocalExpanded] = React.useState(false)\n  const open = expanded ?? localExpanded\n  const changeOpen = (next: boolean) => {\n    if (expanded === undefined) setLocalExpanded(next)\n    onExpandedChange?.(next)\n  }\n  return (\n    <motion.section\n      layout={!reduce}\n      transition={\n        reduce\n          ? { duration: 0 }\n          : { type: \"spring\", stiffness: 390, damping: 38 }\n      }\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        open ? \"w-full max-w-none\" : \"mx-auto w-full max-w-sm\",\n        className\n      )}\n    >\n      <div className=\"group relative\">\n        <ScreenMedia\n          src={mediaSrc}\n          type={mediaType}\n          loading={variant === \"loading\"}\n          expanded={open}\n          reduce={reduce}\n        />\n        {variant !== \"loading\" && (\n          <motion.div\n            initial={reduce ? false : { opacity: 0 }}\n            animate={{ opacity: 1 }}\n            transition={{ duration: reduce ? 0 : 0.16 }}\n            className=\"absolute inset-0 flex items-center justify-center bg-black/0 transition-colors group-hover:bg-black/20\"\n          >\n            <Button\n              variant=\"secondary\"\n              size=\"small\"\n              leadingIcon={open ? Minimize2 : Maximize2}\n              onClick={() => changeOpen(!open)}\n            >\n              {open ? \"Collapse\" : \"Open screen\"}\n            </Button>\n          </motion.div>\n        )}\n        <AnimatePresence initial={false}>\n          {recording && variant !== \"loading\" && (\n            <motion.span\n              initial={reduce ? false : { opacity: 0, y: -4 }}\n              animate={{ opacity: 1, y: 0 }}\n              exit={reduce ? undefined : { opacity: 0, y: -4 }}\n              transition={{ duration: reduce ? 0 : 0.15 }}\n              className=\"absolute top-3 left-3 inline-flex items-center gap-1.5 rounded-full bg-red-600 px-2 py-1 text-xs text-white\"\n            >\n              <Radio className=\"size-3\" />\n              Recording{recordingElapsed ? ` · ${recordingElapsed}` : \"\"}\n            </motion.span>\n          )}\n        </AnimatePresence>\n      </div>\n      <header className=\"border-separator-border flex flex-wrap items-start justify-between gap-3 border-t p-4\">\n        <div>\n          <p className=\"text-text-secondary text-xs capitalize\">{variant}</p>\n          <h2 className=\"mt-1 text-base font-semibold\">{title}</h2>\n          {description && (\n            <p className=\"text-text-secondary mt-1 text-sm\">{description}</p>\n          )}\n        </div>\n        {variant !== \"loading\" && (\n          <AnimatePresence initial={false} mode=\"wait\">\n            <motion.div\n              key={recording ? (paused ? \"paused\" : \"recording\") : \"idle\"}\n              initial={reduce ? false : { opacity: 0, y: 4 }}\n              animate={{ opacity: 1, y: 0 }}\n              exit={reduce ? undefined : { opacity: 0, y: -4 }}\n              transition={{ duration: reduce ? 0 : 0.15 }}\n              className=\"flex gap-2\"\n            >\n              {recording ? (\n                <Button\n                  variant=\"danger\"\n                  size=\"small\"\n                  leadingIcon={Square}\n                  onClick={onEndRecording}\n                >\n                  End recording\n                </Button>\n              ) : (\n                <Button\n                  variant=\"secondary\"\n                  size=\"small\"\n                  leadingIcon={Radio}\n                  onClick={onStartRecording}\n                >\n                  Teach a task\n                </Button>\n              )}\n              {recording &&\n                (paused ? (\n                  <Button\n                    variant=\"ghost\"\n                    size=\"small\"\n                    leadingIcon={Play}\n                    onClick={onResume}\n                  >\n                    Resume\n                  </Button>\n                ) : (\n                  <Button\n                    variant=\"ghost\"\n                    size=\"small\"\n                    leadingIcon={Pause}\n                    onClick={onPause}\n                  >\n                    Pause\n                  </Button>\n                ))}\n            </motion.div>\n          </AnimatePresence>\n        )}\n      </header>\n      {steps.length > 0 && (\n        <motion.div\n          layout\n          className=\"divide-separator-border border-separator-border divide-y border-t\"\n        >\n          <AnimatePresence initial={false}>\n            {steps.map((step) => {\n              const Icon =\n                step.status === \"complete\"\n                  ? Check\n                  : step.status === \"running\"\n                    ? LoaderCircle\n                    : Circle\n              return (\n                <motion.div\n                  key={step.id}\n                  layout=\"position\"\n                  initial={reduce ? false : { opacity: 0, y: 4 }}\n                  animate={{ opacity: 1, y: 0 }}\n                  exit={reduce ? undefined : { opacity: 0, y: -4 }}\n                  transition={{ duration: reduce ? 0 : 0.14 }}\n                  className=\"flex min-h-11 items-center gap-3 px-4\"\n                >\n                  <Icon\n                    className={cx(\n                      \"text-text-secondary size-4\",\n                      step.status === \"running\" && \"animate-spin\"\n                    )}\n                  />\n                  <span className=\"text-sm\">{step.label}</span>\n                  <span className=\"text-text-secondary ml-auto text-xs capitalize\">\n                    {step.status}\n                  </span>\n                </motion.div>\n              )\n            })}\n          </AnimatePresence>\n        </motion.div>\n      )}\n    </motion.section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-approval-card",
      "type": "registry:block",
      "title": "Beautiful Approval Card",
      "description": "approval card",
      "dependencies": [
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/approval-card.tsx",
          "target": "@components/beautiful-ui/approval-card.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check } from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport * as React from \"react\"\n\nexport type ApprovalAnswer = string | string[]\nexport interface ApprovalQuestion {\n  id: string\n  label: string\n  type?: \"text\" | \"radio\" | \"check\"\n  options?: string[]\n  required?: boolean\n  value?: ApprovalAnswer\n  placeholder?: string\n}\nexport interface ApprovalCardProps {\n  title: string\n  description?: string\n  questions?: ApprovalQuestion[]\n  currentStep?: number\n  answers?: Record<string, ApprovalAnswer>\n  submitted?: boolean\n  allowSkip?: boolean\n  onStepChange?: (step: number) => void\n  onAnswerChange?: (id: string, value: ApprovalAnswer) => void\n  onSubmit?: (answers: Record<string, ApprovalAnswer>) => void\n  onSkip?: (id: string) => void\n  onBack?: (step: number) => void\n  onApprove?: () => void\n  onDecline?: () => void\n  onChange?: (id: string, value: string) => void\n  className?: string\n}\nexport function isApprovalAnswerValid(\n  question: ApprovalQuestion,\n  answer: ApprovalAnswer | undefined\n) {\n  if (!question.required) return true\n  return Array.isArray(answer) ? answer.length > 0 : Boolean(answer?.trim())\n}\nexport function ApprovalCard({\n  title,\n  description,\n  questions = [],\n  currentStep,\n  answers,\n  submitted,\n  allowSkip = true,\n  onStepChange,\n  onAnswerChange,\n  onSubmit,\n  onSkip,\n  onBack,\n  onApprove,\n  onDecline,\n  onChange,\n  className,\n}: ApprovalCardProps) {\n  const reduce = useReducedMotion() ?? false\n  const [localStep, setLocalStep] = React.useState(0)\n  const [localAnswers, setLocalAnswers] = React.useState<\n    Record<string, ApprovalAnswer>\n  >(() =>\n    Object.fromEntries(\n      questions\n        .filter((question) => question.value !== undefined)\n        .map((question) => [question.id, question.value!])\n    )\n  )\n  const [localSubmitted, setLocalSubmitted] = React.useState(false)\n  const step = Math.min(\n    Math.max(currentStep ?? localStep, 0),\n    Math.max(questions.length - 1, 0)\n  )\n  const values = answers ?? localAnswers\n  const done = submitted ?? localSubmitted\n  const question = questions[step]\n  const answer = question ? values[question.id] : undefined\n  const valid = question ? isApprovalAnswerValid(question, answer) : true\n  const changeStep = (next: number) => {\n    if (currentStep === undefined) setLocalStep(next)\n    onStepChange?.(next)\n  }\n  const changeAnswer = (id: string, value: ApprovalAnswer) => {\n    if (answers === undefined)\n      setLocalAnswers((current) => ({ ...current, [id]: value }))\n    onAnswerChange?.(id, value)\n    if (typeof value === \"string\") onChange?.(id, value)\n  }\n  const finish = () => {\n    if (!valid) return\n    if (submitted === undefined) setLocalSubmitted(true)\n    onSubmit?.(values)\n    onApprove?.()\n  }\n  const next = () => {\n    if (!valid) return\n    if (step >= questions.length - 1) finish()\n    else changeStep(step + 1)\n  }\n  if (done)\n    return (\n      <section\n        className={cx(\n          \"border-separator-border bg-background-primary-default max-w-sm rounded-xl border p-4\",\n          className\n        )}\n      >\n        <p className=\"flex items-center gap-2 text-sm font-medium\">\n          <Check className=\"size-4 text-green-600\" />\n          Answers submitted\n        </p>\n      </section>\n    )\n  if (!question)\n    return (\n      <section\n        className={cx(\n          \"border-separator-border bg-background-primary-default max-w-sm rounded-xl border p-4\",\n          className\n        )}\n      >\n        <h3 className=\"text-sm font-semibold\">{title}</h3>\n        <p className=\"text-text-secondary mt-2 text-[13px]\">\n          No questions provided.\n        </p>\n        {onApprove && (\n          <div className=\"mt-4 flex justify-end\">\n            <Button size=\"small\" onClick={finish}>\n              Approve\n            </Button>\n          </div>\n        )}\n      </section>\n    )\n  const type = question.type ?? \"text\"\n  const selected = Array.isArray(answer) ? answer : []\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full max-w-sm rounded-xl border p-4\",\n        className\n      )}\n    >\n      <header>\n        <div className=\"flex items-center justify-between gap-3\">\n          <h3 className=\"text-sm font-semibold\">{title}</h3>\n          <span className=\"text-text-secondary text-xs tabular-nums\">\n            {step + 1} / {questions.length}\n          </span>\n        </div>\n        {description && (\n          <p className=\"text-text-secondary mt-1 text-[13px] leading-5\">\n            {description}\n          </p>\n        )}\n      </header>\n      <div className=\"mt-4 min-h-[104px]\">\n        <AnimatePresence initial={false} mode=\"wait\">\n          <motion.div\n            key={question.id}\n            initial={reduce ? false : { opacity: 0, y: 4 }}\n            animate={{ opacity: 1, y: 0 }}\n            exit={reduce ? undefined : { opacity: 0, y: -4 }}\n            transition={{ duration: reduce ? 0 : 0.16 }}\n          >\n            <p className=\"text-sm font-medium\">\n              {question.label}\n              {question.required && (\n                <span className=\"ml-1 text-red-600\">*</span>\n              )}\n            </p>\n            {type === \"text\" ? (\n              <input\n                value={typeof answer === \"string\" ? answer : \"\"}\n                placeholder={question.placeholder}\n                onChange={(event) =>\n                  changeAnswer(question.id, event.target.value)\n                }\n                className=\"bg-background-tertiary-default focus:ring-border-focus-ring mt-2 h-9 w-full rounded-lg px-3 text-[13px] outline-none focus:ring-2\"\n              />\n            ) : (\n              <div\n                role={type === \"radio\" ? \"radiogroup\" : \"group\"}\n                aria-label={question.label}\n                className=\"mt-2 flex flex-wrap gap-2\"\n              >\n                {question.options?.map((option) => {\n                  const on = selected.includes(option) || answer === option\n                  return (\n                    <button\n                      key={option}\n                      type=\"button\"\n                      role={type === \"radio\" ? \"radio\" : \"checkbox\"}\n                      aria-checked={on}\n                      onClick={() =>\n                        changeAnswer(\n                          question.id,\n                          type === \"radio\"\n                            ? option\n                            : on\n                              ? selected.filter((item) => item !== option)\n                              : [...selected, option]\n                        )\n                      }\n                      className={cx(\n                        \"min-h-8 rounded-full border px-3 text-xs\",\n                        on\n                          ? \"border-text-primary bg-button-primary text-text-white\"\n                          : \"border-separator-border hover:bg-background-secondary-default\"\n                      )}\n                    >\n                      {option}\n                    </button>\n                  )\n                })}\n              </div>\n            )}\n            {!valid && (\n              <p className=\"mt-2 text-xs text-red-700 dark:text-red-400\">\n                Choose or enter an answer to continue.\n              </p>\n            )}\n          </motion.div>\n        </AnimatePresence>\n      </div>\n      <footer className=\"border-separator-border mt-5 flex items-center justify-between border-t pt-3\">\n        <div className=\"flex gap-1\">\n          {onDecline && (\n            <Button variant=\"ghost\" size=\"xs\" onClick={onDecline}>\n              Decline\n            </Button>\n          )}\n          {step > 0 && (\n            <Button\n              variant=\"ghost\"\n              size=\"xs\"\n              onClick={() => {\n                onBack?.(step - 1)\n                changeStep(step - 1)\n              }}\n            >\n              Back\n            </Button>\n          )}\n        </div>\n        <div className=\"flex gap-1\">\n          {allowSkip && (\n            <Button\n              variant=\"ghost\"\n              size=\"xs\"\n              onClick={() => {\n                onSkip?.(question.id)\n                if (step >= questions.length - 1) {\n                  if (submitted === undefined) setLocalSubmitted(true)\n                  onSubmit?.(values)\n                  onApprove?.()\n                } else changeStep(step + 1)\n              }}\n            >\n              Skip\n            </Button>\n          )}\n          <Button size=\"xs\" disabled={!valid} onClick={next}>\n            {step >= questions.length - 1 ? \"Submit\" : \"Continue\"}\n          </Button>\n        </div>\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-chat-composer",
      "type": "registry:block",
      "title": "Beautiful Chat Composer",
      "description": "chat composer",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/chat-composer.tsx",
          "target": "@components/beautiful-ui/chat-composer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Send } from \"lucide-react\"\n\nexport interface ChatMessage {\n  id: string\n  role: \"user\" | \"assistant\"\n  content: string\n  label?: string\n  meta?: string\n}\nexport interface ChatComposerProps {\n  messages: ChatMessage[]\n  value: string\n  onValueChange: (value: string) => void\n  onSubmit: (value: string) => void\n  disabled?: boolean\n  tabs?: string[]\n  activeTab?: string\n  onTabChange?: (tab: string) => void\n  className?: string\n}\nexport function ChatComposer({\n  messages,\n  value,\n  onValueChange,\n  onSubmit,\n  disabled = false,\n  tabs = [],\n  activeTab,\n  onTabChange,\n  className,\n}: ChatComposerProps) {\n  const submit = () => {\n    if (value.trim() && !disabled) onSubmit(value.trim())\n  }\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      {tabs.length > 0 && (\n        <div className=\"border-separator-border flex gap-1 border-b p-1.5\">\n          {tabs.map((tab) => (\n            <button\n              key={tab}\n              type=\"button\"\n              aria-pressed={activeTab === tab}\n              onClick={() => onTabChange?.(tab)}\n              className={cx(\n                \"min-h-8 rounded-lg px-3 text-xs\",\n                activeTab === tab\n                  ? \"bg-background-secondary-default font-medium\"\n                  : \"text-text-secondary\"\n              )}\n            >\n              {tab}\n            </button>\n          ))}\n        </div>\n      )}\n      <div className=\"max-h-72 space-y-3 overflow-auto p-4\">\n        {messages.map((message) => (\n          <div\n            key={message.id}\n            className={cx(\n              \"max-w-[85%] rounded-lg p-3 text-[13px]\",\n              message.role === \"user\"\n                ? \"bg-button-primary text-text-white ml-auto\"\n                : \"bg-background-secondary-default\"\n            )}\n          >\n            {message.label && (\n              <p className=\"mb-1 text-xs font-medium\">\n                {message.label}\n                {message.meta && (\n                  <span className=\"text-text-secondary ml-2 font-normal\">\n                    {message.meta}\n                  </span>\n                )}\n              </p>\n            )}\n            {message.content}\n          </div>\n        ))}\n      </div>\n      <div className=\"border-separator-border flex gap-2 border-t p-3\">\n        <textarea\n          value={value}\n          onChange={(e) => onValueChange(e.target.value)}\n          onKeyDown={(e) => {\n            if (\n              e.key === \"Enter\" &&\n              !e.shiftKey &&\n              !e.nativeEvent.isComposing\n            ) {\n              e.preventDefault()\n              submit()\n            }\n          }}\n          rows={2}\n          className=\"min-h-10 flex-1 resize-none bg-transparent text-[13px] outline-none\"\n        />\n        <Button\n          iconOnly\n          aria-label=\"Send message\"\n          leadingIcon={Send}\n          disabled={disabled || !value.trim()}\n          onClick={submit}\n        />\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-code-block",
      "type": "registry:block",
      "title": "Beautiful Code Block",
      "description": "code block",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/code-block.tsx",
          "target": "@components/beautiful-ui/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Copy } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport type CodeBlockVariant = \"code\" | \"diff\"\nexport interface CodePiece {\n  text: string\n  change?: \"add\" | \"del\"\n}\nexport interface CodeDiffRow {\n  oldLine: number | null\n  newLine: number | null\n  type: \"context\" | \"add\" | \"remove\"\n  pieces: CodePiece[]\n}\nexport interface CodeBlockLabels {\n  copy: string\n  copied: string\n}\nexport interface CodeBlockProps {\n  code: string\n  language?: string\n  variant?: CodeBlockVariant\n  filename?: string\n  diff?: CodeDiffRow[]\n  labels?: Partial<CodeBlockLabels>\n  onCopy?: (code: string) => void\n  className?: string\n}\n\nfunction inferredDiff(code: string): CodeDiffRow[] {\n  let oldLine = 1\n  let newLine = 1\n  return code.split(\"\\n\").map((line) => {\n    if (line.startsWith(\"+\") && !line.startsWith(\"+++\"))\n      return {\n        oldLine: null,\n        newLine: newLine++,\n        type: \"add\" as const,\n        pieces: [{ text: line.slice(1), change: \"add\" as const }],\n      }\n    if (line.startsWith(\"-\") && !line.startsWith(\"---\"))\n      return {\n        oldLine: oldLine++,\n        newLine: null,\n        type: \"remove\" as const,\n        pieces: [{ text: line.slice(1), change: \"del\" as const }],\n      }\n    const text = line.startsWith(\" \") ? line.slice(1) : line\n    return {\n      oldLine: oldLine++,\n      newLine: newLine++,\n      type: \"context\" as const,\n      pieces: [{ text }],\n    }\n  })\n}\n\nfunction Pieces({ pieces }: { pieces: CodePiece[] }) {\n  return (\n    <>\n      {pieces.map((piece, index) => (\n        <span\n          key={index}\n          className={cx(\n            piece.change === \"add\" && \"rounded-sm bg-green-500/15\",\n            piece.change === \"del\" && \"rounded-sm bg-red-500/15\"\n          )}\n        >\n          {piece.text}\n        </span>\n      ))}\n    </>\n  )\n}\n\nexport function CodeBlock({\n  code,\n  language = \"text\",\n  variant = \"code\",\n  filename,\n  diff,\n  labels,\n  onCopy,\n  className,\n}: CodeBlockProps) {\n  const [copied, setCopied] = React.useState(false)\n  const text = { copy: \"Copy\", copied: \"Copied\", ...labels }\n  const rows = React.useMemo(() => diff ?? inferredDiff(code), [code, diff])\n  const additions = rows.filter((row) => row.type === \"add\").length\n  const removals = rows.filter((row) => row.type === \"remove\").length\n  const copy = async () => {\n    await navigator.clipboard.writeText(code)\n    setCopied(true)\n    onCopy?.(code)\n    window.setTimeout(() => setCopied(false), 1500)\n  }\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border text-text-secondary flex h-11 items-center gap-3 border-b px-4 text-xs\">\n        <span className=\"text-text-primary min-w-0 truncate font-mono\">\n          {filename ?? language}\n        </span>\n        {variant === \"diff\" ? (\n          <span className=\"ml-auto flex gap-2 font-mono tabular-nums\">\n            <span className=\"text-green-700 dark:text-green-400\">\n              +{additions}\n            </span>\n            <span className=\"text-red-700 dark:text-red-400\">-{removals}</span>\n          </span>\n        ) : (\n          <Button\n            className=\"ml-auto\"\n            variant=\"ghost\"\n            size=\"xs\"\n            leadingIcon={copied ? Check : Copy}\n            onClick={copy}\n          >\n            {copied ? text.copied : text.copy}\n          </Button>\n        )}\n      </header>\n      <div className=\"max-h-96 overflow-auto py-3 font-mono text-[13px] leading-5\">\n        {variant === \"diff\"\n          ? rows.map((row, index) => (\n              <div\n                key={index}\n                data-change={row.type}\n                data-old-line={row.oldLine ?? undefined}\n                data-new-line={row.newLine ?? undefined}\n                className={cx(\n                  \"grid grid-cols-[2rem_2rem_1.25rem_minmax(0,1fr)] px-2\",\n                  row.type === \"add\" && \"bg-green-500/10\",\n                  row.type === \"remove\" && \"bg-red-500/10\"\n                )}\n              >\n                <span className=\"text-text-tertiary text-right text-xs tabular-nums select-none\">\n                  {row.oldLine ?? \"\"}\n                </span>\n                <span className=\"text-text-tertiary text-right text-xs tabular-nums select-none\">\n                  {row.newLine ?? \"\"}\n                </span>\n                <span\n                  className={cx(\n                    \"text-center select-none\",\n                    row.type === \"add\" && \"text-green-700 dark:text-green-400\",\n                    row.type === \"remove\" && \"text-red-700 dark:text-red-400\"\n                  )}\n                >\n                  {row.type === \"add\" ? \"+\" : row.type === \"remove\" ? \"-\" : \"\"}\n                </span>\n                <code className=\"min-w-0 pl-1 break-words whitespace-pre-wrap\">\n                  <Pieces pieces={row.pieces} />\n                </code>\n              </div>\n            ))\n          : code.split(\"\\n\").map((line, index) => (\n              <div\n                key={index}\n                className=\"grid grid-cols-[2.5rem_minmax(0,1fr)] px-2\"\n              >\n                <span className=\"border-separator-border text-text-tertiary border-r pr-2 text-right text-xs tabular-nums select-none\">\n                  {index + 1}\n                </span>\n                <code className=\"min-w-0 pl-3 break-words whitespace-pre-wrap\">\n                  {line || \" \"}\n                </code>\n              </div>\n            ))}\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-context-cards",
      "type": "registry:block",
      "title": "Beautiful Context Cards",
      "description": "context cards",
      "dependencies": [
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/context-cards.tsx",
          "target": "@components/beautiful-ui/context-cards.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { FileText } from \"lucide-react\"\n\nexport interface ContextChunk {\n  id: string\n  title: string\n  source: string\n  content: string\n  score?: number\n}\nexport interface ContextCardsProps {\n  chunks: ContextChunk[]\n  selectedId?: string\n  onSelect?: (id: string) => void\n  className?: string\n}\nexport function ContextCards({\n  chunks,\n  selectedId,\n  onSelect,\n  className,\n}: ContextCardsProps) {\n  return (\n    <div\n      className={cx(\n        \"divide-separator-border border-separator-border bg-background-primary-default divide-y rounded-xl border\",\n        className\n      )}\n    >\n      {chunks.map((chunk) => (\n        <button\n          key={chunk.id}\n          onClick={() => onSelect?.(chunk.id)}\n          className={cx(\n            \"grid w-full grid-cols-[20px_1fr_auto] gap-3 p-4 text-left\",\n            selectedId === chunk.id && \"bg-background-secondary-default\"\n          )}\n        >\n          <FileText className=\"text-text-secondary size-4\" />\n          <span>\n            <strong className=\"block text-[13px] font-medium\">\n              {chunk.title}\n            </strong>\n            <span className=\"text-text-secondary mt-1 line-clamp-2 text-xs leading-5\">\n              {chunk.content}\n            </span>\n            <span className=\"text-text-secondary mt-1 block text-xs\">\n              {chunk.source}\n            </span>\n          </span>\n          {chunk.score !== undefined && (\n            <span className=\"text-text-secondary text-xs\">\n              {Math.round(chunk.score * 100)}%\n            </span>\n          )}\n        </button>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-diff-table",
      "type": "registry:block",
      "title": "Beautiful Diff Table",
      "description": "diff table",
      "dependencies": [
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/diff-table.tsx",
          "target": "@components/beautiful-ui/diff-table.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, X } from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\n\nexport interface DiffTableRow {\n  id: string\n  field: string\n  before: string\n  after: string\n  status?: \"pending\" | \"accepted\" | \"rejected\"\n}\nexport interface DiffTableProps {\n  rows: DiffTableRow[]\n  onAccept?: (id: string) => void\n  onReject?: (id: string) => void\n  onApplyAll?: () => void\n  className?: string\n}\n\nexport function DiffTable({\n  rows,\n  onAccept,\n  onReject,\n  onApplyAll,\n  className,\n}: DiffTableProps) {\n  const reduce = useReducedMotion() ?? false\n  const accepted = rows.filter((row) => row.status === \"accepted\").length\n  const rejected = rows.filter((row) => row.status === \"rejected\").length\n  const pending = rows.length - accepted - rejected\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <header className=\"border-separator-border flex min-h-12 flex-wrap items-center justify-between gap-3 border-b px-4\">\n        <div>\n          <h2 className=\"text-text-primary text-sm font-semibold\">\n            Review changes\n          </h2>\n          <p className=\"text-text-secondary text-xs\">\n            {rows.length} changed fields\n          </p>\n        </div>\n        <div className=\"flex gap-3 text-xs tabular-nums\" aria-live=\"polite\">\n          {[\n            [accepted, \"accepted\", \"text-green-700 dark:text-green-400\"],\n            [rejected, \"rejected\", \"text-red-700 dark:text-red-400\"],\n            [pending, \"pending\", \"text-text-secondary\"],\n          ].map(([count, label, color]) => (\n            <span key={String(label)} className={String(color)}>\n              <AnimatePresence initial={false} mode=\"popLayout\">\n                <motion.span\n                  key={String(count)}\n                  initial={reduce ? false : { opacity: 0, y: 3 }}\n                  animate={{ opacity: 1, y: 0 }}\n                  exit={reduce ? undefined : { opacity: 0, y: -3 }}\n                  transition={{ duration: reduce ? 0 : 0.14 }}\n                  className=\"inline-block\"\n                >\n                  {count} {label}\n                </motion.span>\n              </AnimatePresence>\n            </span>\n          ))}\n        </div>\n      </header>\n      <div className=\"overflow-auto\">\n        <table className=\"w-full min-w-[720px] text-left text-[13px]\">\n          <thead className=\"bg-background-secondary-default text-text-secondary text-xs\">\n            <tr>\n              <th className=\"px-4 py-2.5 font-medium\">Field</th>\n              <th className=\"px-4 py-2.5 font-medium\">Change</th>\n              <th className=\"px-4 py-2.5 font-medium\">Decision</th>\n            </tr>\n          </thead>\n          <motion.tbody layout>\n            <AnimatePresence initial={false}>\n              {rows.map((row) => (\n                <motion.tr\n                  key={row.id}\n                  layout=\"position\"\n                  initial={reduce ? false : { opacity: 0, y: 4 }}\n                  animate={{ opacity: 1, y: 0 }}\n                  exit={reduce ? undefined : { opacity: 0, y: -4 }}\n                  transition={\n                    reduce\n                      ? { duration: 0 }\n                      : { type: \"spring\", stiffness: 430, damping: 38 }\n                  }\n                  className=\"border-separator-border border-t align-top\"\n                >\n                  <th className=\"text-text-primary w-44 px-4 py-3 font-medium\">\n                    {row.field}\n                  </th>\n                  <td className=\"px-4 py-3\">\n                    <div className=\"grid gap-1\">\n                      <motion.div\n                        animate={{\n                          opacity: row.status === \"accepted\" ? 0.42 : 1,\n                        }}\n                        transition={{ duration: reduce ? 0 : 0.15 }}\n                        className={cx(\n                          \"grid grid-cols-[1rem_1fr] rounded-sm bg-red-500/10 px-2 py-1.5 text-red-800 dark:text-red-300\",\n                          row.status === \"accepted\" && \"line-through\"\n                        )}\n                      >\n                        <span aria-hidden>-</span>\n                        <span className=\"break-words\">{row.before}</span>\n                      </motion.div>\n                      <motion.div\n                        animate={{\n                          opacity: row.status === \"rejected\" ? 0.42 : 1,\n                        }}\n                        transition={{ duration: reduce ? 0 : 0.15 }}\n                        className={cx(\n                          \"grid grid-cols-[1rem_1fr] rounded-sm bg-green-500/10 px-2 py-1.5 text-green-800 dark:text-green-300\",\n                          row.status === \"rejected\" && \"line-through\"\n                        )}\n                      >\n                        <span aria-hidden>+</span>\n                        <span className=\"break-words\">{row.after}</span>\n                      </motion.div>\n                    </div>\n                  </td>\n                  <td className=\"w-44 px-4 py-3\">\n                    <div className=\"flex gap-1\">\n                      <Button\n                        variant={\n                          row.status === \"rejected\" ? \"secondary\" : \"ghost\"\n                        }\n                        size=\"xs\"\n                        leadingIcon={X}\n                        aria-pressed={row.status === \"rejected\"}\n                        onClick={() => onReject?.(row.id)}\n                      >\n                        Reject\n                      </Button>\n                      <Button\n                        variant={\n                          row.status === \"accepted\" ? \"secondary\" : \"ghost\"\n                        }\n                        size=\"xs\"\n                        leadingIcon={Check}\n                        aria-pressed={row.status === \"accepted\"}\n                        onClick={() => onAccept?.(row.id)}\n                      >\n                        Accept\n                      </Button>\n                    </div>\n                  </td>\n                </motion.tr>\n              ))}\n            </AnimatePresence>\n          </motion.tbody>\n        </table>\n      </div>\n      <footer className=\"border-separator-border flex min-h-12 items-center justify-between gap-3 border-t px-4\">\n        <span className=\"text-text-secondary text-xs\">\n          Decisions apply only after confirmation.\n        </span>\n        {onApplyAll && (\n          <Button size=\"small\" onClick={onApplyAll}>\n            Apply all {rows.length} changes\n          </Button>\n        )}\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-filter-table",
      "type": "registry:block",
      "title": "Beautiful Filter Table",
      "description": "filter table",
      "dependencies": [
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/filter-table.tsx",
          "target": "@components/beautiful-ui/filter-table.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\n\nexport type FilterStatus = \"todo\" | \"progress\" | \"done\"\nexport interface FilterTableRow {\n  id: string\n  task: string\n  date: string\n  status: FilterStatus\n  owner: string\n}\nexport interface FilterTableProps {\n  rows: FilterTableRow[]\n  filter?: FilterStatus | \"all\"\n  onFilterChange?: (value: FilterStatus | \"all\") => void\n  className?: string\n}\nexport function FilterTable({\n  rows,\n  filter = \"all\",\n  onFilterChange,\n  className,\n}: FilterTableProps) {\n  const visible =\n    filter === \"all\" ? rows : rows.filter((row) => row.status === filter)\n  return (\n    <section\n      className={cx(\"border-separator-border rounded-xl border\", className)}\n    >\n      <div className=\"border-separator-border flex gap-1 border-b p-2\">\n        {([\"all\", \"todo\", \"progress\", \"done\"] as const).map((value) => (\n          <button\n            key={value}\n            onClick={() => onFilterChange?.(value)}\n            className={cx(\n              \"min-h-8 rounded-lg px-3 text-xs capitalize\",\n              filter === value && \"bg-background-secondary-default font-medium\"\n            )}\n          >\n            {value}\n          </button>\n        ))}\n      </div>\n      <div className=\"divide-separator-border divide-y\">\n        {visible.map((row) => (\n          <div\n            key={row.id}\n            className=\"grid grid-cols-[1fr_auto_auto] gap-4 p-3 text-[13px]\"\n          >\n            <span>\n              {row.task}\n              <span className=\"text-text-secondary block text-xs\">\n                {row.owner}\n              </span>\n            </span>\n            <span className=\"text-text-secondary text-xs\">{row.date}</span>\n            <span className=\"text-xs capitalize\">{row.status}</span>\n          </div>\n        ))}\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-fine-tune-card",
      "type": "registry:block",
      "title": "Beautiful Fine Tune Card",
      "description": "fine tune card",
      "dependencies": [
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/fine-tune-card.tsx",
          "target": "@components/beautiful-ui/fine-tune-card.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\n\nexport interface FineTuneField {\n  id: string\n  label: string\n  value: string | number\n  options?: string[]\n  min?: number\n  max?: number\n  step?: number\n  suffix?: string\n}\nexport interface FineTuneCardProps {\n  title: string\n  fields: FineTuneField[]\n  onChange?: (id: string, value: string | number) => void\n  onApply?: () => void\n  onReset?: () => void\n  className?: string\n}\nexport function FineTuneCard({\n  title,\n  fields,\n  onChange,\n  onApply,\n  onReset,\n  className,\n}: FineTuneCardProps) {\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default max-w-md rounded-xl border p-4\",\n        className\n      )}\n    >\n      <h3 className=\"text-sm font-semibold\">{title}</h3>\n      <div className=\"mt-4 space-y-4\">\n        {fields.map((field) => (\n          <label key={field.id} className=\"text-text-secondary block text-xs\">\n            {field.label}\n            {field.options ? (\n              <select\n                value={String(field.value)}\n                onChange={(e) => onChange?.(field.id, e.target.value)}\n                className=\"border-separator-border bg-background-primary-default text-text-primary mt-1 h-9 w-full rounded-lg border px-3 text-[13px]\"\n              >\n                {field.options.map((option) => (\n                  <option key={option}>{option}</option>\n                ))}\n              </select>\n            ) : (\n              <input\n                type={typeof field.value === \"number\" ? \"number\" : \"text\"}\n                value={field.value}\n                min={field.min}\n                max={field.max}\n                step={field.step}\n                onChange={(e) =>\n                  onChange?.(\n                    field.id,\n                    typeof field.value === \"number\"\n                      ? Number(e.target.value)\n                      : e.target.value\n                  )\n                }\n                className=\"bg-background-tertiary-default text-text-primary mt-1 h-9 w-full rounded-lg px-3 text-[13px] outline-none\"\n              />\n            )}\n            {field.suffix && (\n              <span className=\"text-text-secondary mt-1 block text-right text-xs\">\n                {field.suffix}\n              </span>\n            )}\n          </label>\n        ))}\n      </div>\n      <div className=\"mt-5 flex justify-end gap-2\">\n        <Button variant=\"ghost\" onClick={onReset}>\n          Reset\n        </Button>\n        <Button onClick={onApply}>Apply</Button>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-flowchart",
      "type": "registry:block",
      "title": "Beautiful Flowchart",
      "description": "flowchart",
      "dependencies": [
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/flowchart.tsx",
          "target": "@components/beautiful-ui/flowchart.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Circle, GripVertical, LoaderCircle } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport interface FlowchartNode {\n  id: string\n  label: string\n  detail?: string\n  status: \"pending\" | \"running\" | \"complete\"\n  x?: number\n  y?: number\n  kind?: string\n  condition?: { field: string; operator: string; value: string }\n}\nexport interface FlowchartEdge {\n  from: string\n  to: string\n}\nexport interface FlowchartProps {\n  nodes: FlowchartNode[]\n  edges?: FlowchartEdge[]\n  onSelect?: (id: string) => void\n  onNodeMove?: (id: string, position: { x: number; y: number }) => void\n  onConditionChange?: (\n    id: string,\n    condition: FlowchartNode[\"condition\"]\n  ) => void\n  className?: string\n}\nexport function Flowchart({\n  nodes,\n  edges,\n  onSelect,\n  onNodeMove,\n  onConditionChange,\n  className,\n}: FlowchartProps) {\n  const initial = React.useMemo(\n    () =>\n      Object.fromEntries(\n        nodes.map((node, index) => [\n          node.id,\n          { x: node.x ?? 50, y: node.y ?? 38 + index * 116 },\n        ])\n      ),\n    [nodes]\n  )\n  const [positions, setPositions] = React.useState(initial)\n  const links =\n    edges ??\n    nodes\n      .slice(0, -1)\n      .map((node, index) => ({ from: node.id, to: nodes[index + 1].id }))\n  const drag = React.useRef<{ id: string; dx: number; dy: number } | null>(null)\n  const move = (event: React.PointerEvent<HTMLDivElement>) => {\n    if (!drag.current) return\n    const rect = event.currentTarget.getBoundingClientRect()\n    const next = {\n      x: Math.max(\n        8,\n        Math.min(rect.width - 208, event.clientX - rect.left - drag.current.dx)\n      ),\n      y: Math.max(\n        8,\n        Math.min(rect.height - 84, event.clientY - rect.top - drag.current.dy)\n      ),\n    }\n    setPositions((current) => ({ ...current, [drag.current!.id]: next }))\n    onNodeMove?.(drag.current.id, next)\n  }\n  return (\n    <div\n      onPointerMove={move}\n      onPointerUp={() => {\n        drag.current = null\n      }}\n      onPointerCancel={() => {\n        drag.current = null\n      }}\n      className={cx(\n        \"border-separator-border bg-background-primary-default relative h-[360px] min-w-[640px] overflow-hidden rounded-xl border\",\n        className\n      )}\n      style={{\n        backgroundImage:\n          \"radial-gradient(circle, color-mix(in srgb, currentColor 12%, transparent) 1px, transparent 1px)\",\n        backgroundSize: \"18px 18px\",\n      }}\n    >\n      <svg\n        className=\"pointer-events-none absolute inset-0 h-full w-full\"\n        aria-hidden\n      >\n        {links.map((edge) => {\n          const from = positions[edge.from],\n            to = positions[edge.to]\n          if (!from || !to) return null\n          const x1 = from.x + 100,\n            y1 = from.y + 72,\n            x2 = to.x + 100,\n            y2 = to.y\n          return (\n            <path\n              key={`${edge.from}-${edge.to}`}\n              d={`M${x1},${y1} C${x1},${(y1 + y2) / 2} ${x2},${(y1 + y2) / 2} ${x2},${y2}`}\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeOpacity=\".25\"\n              strokeWidth=\"1.5\"\n            />\n          )\n        })}\n      </svg>\n      {nodes.map((node) => {\n        const position = positions[node.id] ?? { x: 0, y: 0 }\n        const Icon =\n          node.status === \"complete\"\n            ? Check\n            : node.status === \"running\"\n              ? LoaderCircle\n              : Circle\n        return (\n          <article\n            key={node.id}\n            className=\"border-separator-border bg-background-primary-default absolute w-[200px] touch-none rounded-lg border shadow-sm\"\n            style={{ transform: `translate(${position.x}px, ${position.y}px)` }}\n          >\n            <button\n              type=\"button\"\n              onPointerDown={(event) => {\n                const rect =\n                  event.currentTarget.parentElement!.getBoundingClientRect()\n                drag.current = {\n                  id: node.id,\n                  dx: event.clientX - rect.left,\n                  dy: event.clientY - rect.top,\n                }\n                event.currentTarget.setPointerCapture(event.pointerId)\n              }}\n              onClick={() => onSelect?.(node.id)}\n              className=\"border-separator-border flex min-h-9 w-full cursor-grab items-center gap-2 border-b px-3 text-left active:cursor-grabbing\"\n            >\n              <GripVertical className=\"text-text-secondary size-4\" />\n              <span className=\"flex-1 text-xs font-medium\">\n                {node.kind ?? \"Step\"}\n              </span>\n              <Icon\n                className={cx(\n                  \"text-text-secondary size-4\",\n                  node.status === \"running\" && \"animate-spin\"\n                )}\n              />\n            </button>\n            <div className=\"p-3\">\n              <h3 className=\"text-[13px] font-medium\">{node.label}</h3>\n              {node.detail && (\n                <p className=\"text-text-secondary mt-1 text-xs\">\n                  {node.detail}\n                </p>\n              )}\n              {node.condition && (\n                <div className=\"mt-2 flex flex-wrap gap-1 text-xs\">\n                  <input\n                    aria-label=\"Condition field\"\n                    value={node.condition.field}\n                    onChange={(event) =>\n                      onConditionChange?.(node.id, {\n                        ...node.condition!,\n                        field: event.target.value,\n                      })\n                    }\n                    className=\"bg-background-secondary-default w-16 rounded-sm px-1.5 py-1\"\n                  />\n                  <input\n                    aria-label=\"Condition operator\"\n                    value={node.condition.operator}\n                    onChange={(event) =>\n                      onConditionChange?.(node.id, {\n                        ...node.condition!,\n                        operator: event.target.value,\n                      })\n                    }\n                    className=\"bg-background-secondary-default w-12 rounded-sm px-1.5 py-1\"\n                  />\n                  <input\n                    aria-label=\"Condition value\"\n                    value={node.condition.value}\n                    onChange={(event) =>\n                      onConditionChange?.(node.id, {\n                        ...node.condition!,\n                        value: event.target.value,\n                      })\n                    }\n                    className=\"bg-background-secondary-default min-w-0 flex-1 rounded-sm px-1.5 py-1\"\n                  />\n                </div>\n              )}\n            </div>\n          </article>\n        )\n      })}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-insight-cards",
      "type": "registry:block",
      "title": "Beautiful Insight Cards",
      "description": "insight cards",
      "dependencies": [
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/insight-cards.tsx",
          "target": "@components/beautiful-ui/insight-cards.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\n\nexport type InsightKind = \"compare\" | \"anomaly\" | \"allocation\"\nexport interface InsightCard {\n  id: string\n  title: string\n  description: string\n  value?: string\n  kind: InsightKind\n  series?: number[]\n}\nexport interface InsightCardsProps {\n  insights: InsightCard[]\n  onSelect?: (id: string) => void\n  className?: string\n}\nfunction Line({ data = [] }: { data?: number[] }) {\n  if (data.length < 2) return null\n  const max = Math.max(...data),\n    min = Math.min(...data),\n    range = max - min || 1\n  const points = data\n    .map(\n      (value, index) =>\n        `${(index / (data.length - 1)) * 100},${30 - ((value - min) / range) * 28}`\n    )\n    .join(\" \")\n  return (\n    <svg\n      viewBox=\"0 0 100 32\"\n      className=\"mt-3 h-8 w-full\"\n      preserveAspectRatio=\"none\"\n    >\n      <polyline\n        points={points}\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        vectorEffect=\"non-scaling-stroke\"\n      />\n    </svg>\n  )\n}\nfunction Graphic({ kind, data = [] }: { kind: InsightKind; data?: number[] }) {\n  if (kind === \"allocation\") {\n    const total = data.reduce((sum, value) => sum + Math.max(0, value), 0) || 1\n    return (\n      <div className=\"bg-background-secondary-default mt-4 flex h-2 overflow-hidden rounded-full\">\n        {data.map((value, index) => (\n          <span\n            key={index}\n            className={cx(\n              \"h-full\",\n              index === 0\n                ? \"bg-accent-600\"\n                : index === 1\n                  ? \"bg-text-secondary\"\n                  : \"bg-border-button-default\"\n            )}\n            style={{ width: `${(Math.max(0, value) / total) * 100}%` }}\n          />\n        ))}\n      </div>\n    )\n  }\n  if (kind === \"anomaly\") {\n    const max = Math.max(...data),\n      index = data.indexOf(max)\n    return (\n      <div className=\"relative\">\n        <Line data={data} />\n        {data.length > 1 && (\n          <span\n            className=\"absolute size-2 rounded-full bg-red-600\"\n            style={{\n              left: `calc(${(index / (data.length - 1)) * 100}% - 4px)`,\n              top: 10,\n            }}\n          />\n        )}\n      </div>\n    )\n  }\n  return <Line data={data} />\n}\nexport function InsightCards({\n  insights,\n  onSelect,\n  className,\n}: InsightCardsProps) {\n  return (\n    <div className={cx(\"grid gap-3 md:grid-cols-3\", className)}>\n      {insights.map((item) => (\n        <button\n          key={item.id}\n          onClick={() => onSelect?.(item.id)}\n          className=\"border-separator-border bg-background-primary-default rounded-xl border p-4 text-left\"\n        >\n          <p className=\"text-text-secondary text-xs capitalize\">{item.kind}</p>\n          <h3 className=\"mt-1 text-[13px] font-semibold\">{item.title}</h3>\n          {item.value && (\n            <p className=\"mt-3 text-2xl font-semibold tabular-nums\">\n              {item.value}\n            </p>\n          )}\n          <p className=\"text-text-secondary mt-2 text-xs leading-5\">\n            {item.description}\n          </p>\n          <Graphic kind={item.kind} data={item.series} />\n        </button>\n      ))}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-loading-state",
      "type": "registry:block",
      "title": "Beautiful Loading State",
      "description": "loading state",
      "dependencies": [
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/loading-state.tsx",
          "target": "@components/beautiful-ui/loading-state.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport * as React from \"react\"\n\nexport type LoadingVariant = \"drive\" | \"dots\" | \"orbit\" | \"surfer\"\nexport interface LoadingStateProps {\n  variant?: LoadingVariant\n  label?: string\n  elapsed?: string\n  elapsedSeconds?: number\n  startTime?: number | Date\n  running?: boolean\n  mediaUrl?: string\n  className?: string\n}\n\nconst chevron = Array.from(\n  { length: 9 },\n  (_, index) => ((index % 3) + Math.abs(Math.floor(index / 3) - 1)) * 90\n)\nconst orbitOrder = [0, 1, 2, 5, 8, 7, 6, 3]\n\nfunction PixelGrid({\n  variant,\n}: {\n  variant: Exclude<LoadingVariant, \"surfer\">\n}) {\n  const delays =\n    variant === \"orbit\"\n      ? Array.from({ length: 9 }, (_, index) => {\n          const order = orbitOrder.indexOf(index)\n          return order < 0 ? null : order * 110\n        })\n      : chevron\n  const duration = variant === \"orbit\" ? 950 : 650\n  return (\n    <span\n      aria-hidden\n      className=\"grid shrink-0 grid-cols-[repeat(3,4px)] gap-[1.5px]\"\n    >\n      {delays.map((delay, index) => (\n        <span\n          key={index}\n          className={cx(\n            \"bg-text-primary size-1\",\n            variant === \"dots\" ? \"rounded-full\" : \"rounded-[1px]\"\n          )}\n          style={{\n            opacity: delay === null ? 0.07 : 0.15,\n            animation:\n              delay === null\n                ? \"none\"\n                : `beautiful-pixel ${duration}ms ease-in-out ${delay}ms infinite`,\n          }}\n        />\n      ))}\n    </span>\n  )\n}\n\nfunction secondsSince(value: number | Date) {\n  const milliseconds = value instanceof Date ? value.getTime() : value\n  return Math.max(0, (Date.now() - milliseconds) / 1000)\n}\n\nfunction formatElapsed(seconds: number) {\n  if (seconds < 60) return `${seconds.toFixed(seconds < 10 ? 1 : 0)}s`\n  return `${Math.floor(seconds / 60)}m ${Math.floor(seconds % 60)}s`\n}\n\nexport function LoadingState({\n  variant = \"drive\",\n  label = \"Working\",\n  elapsed,\n  elapsedSeconds,\n  startTime,\n  running = true,\n  mediaUrl,\n  className,\n}: LoadingStateProps) {\n  const [liveSeconds, setLiveSeconds] = React.useState(() =>\n    startTime === undefined ? 0 : secondsSince(startTime)\n  )\n  React.useEffect(() => {\n    if (\n      elapsed !== undefined ||\n      elapsedSeconds !== undefined ||\n      startTime === undefined ||\n      !running\n    )\n      return\n    const update = () => setLiveSeconds(secondsSince(startTime))\n    update()\n    const timer = window.setInterval(update, 250)\n    return () => window.clearInterval(timer)\n  }, [elapsed, elapsedSeconds, running, startTime])\n  const displayElapsed =\n    elapsed ??\n    (elapsedSeconds !== undefined\n      ? formatElapsed(Math.max(0, elapsedSeconds))\n      : startTime !== undefined\n        ? formatElapsed(liveSeconds)\n        : undefined)\n  const pattern = variant === \"surfer\" ? \"drive\" : variant\n  return (\n    <div role=\"status\" className={cx(\"w-fit\", className)}>\n      <style>{`@keyframes beautiful-pixel{0%,55%,100%{opacity:.15;transform:scale(.86)}25%{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){[style*=\"beautiful-pixel\"]{animation:none!important;transform:none!important}}`}</style>\n      <div className=\"flex min-h-7 items-center gap-2.5\">\n        <PixelGrid variant={pattern} />\n        <span className=\"text-text-primary text-sm font-medium\">{label}</span>\n        {displayElapsed && (\n          <span\n            suppressHydrationWarning\n            className=\"text-text-secondary font-mono text-xs tabular-nums\"\n          >\n            {displayElapsed}\n          </span>\n        )}\n      </div>\n      {variant === \"surfer\" && (\n        <div className=\"border-separator-border bg-background-secondary-default mt-3 aspect-video w-56 overflow-hidden rounded-lg border\">\n          {mediaUrl ? (\n            <video\n              src={mediaUrl}\n              autoPlay\n              muted\n              loop\n              playsInline\n              className=\"h-full w-full object-cover\"\n            />\n          ) : (\n            <div className=\"flex h-full flex-col items-center justify-center gap-2\">\n              <PixelGrid variant=\"drive\" />\n              <span className=\"text-text-secondary text-xs\">\n                No media supplied\n              </span>\n            </div>\n          )}\n        </div>\n      )}\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-prompt-bar",
      "type": "registry:block",
      "title": "Beautiful Prompt Bar",
      "description": "prompt bar",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/prompt-bar.tsx",
          "target": "@components/beautiful-ui/prompt-bar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { ArrowUp, AtSign, Command, Mic, Paperclip, Square } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport type PromptBarVariant = \"rounded\" | \"pill\"\nexport interface PromptSource {\n  id: string\n  label: string\n  description?: string\n}\nexport interface PromptCommand {\n  id: string\n  label: string\n  description?: string\n}\nexport interface PromptModel {\n  id: string\n  label: string\n  description?: string\n}\nexport interface PromptBarProps {\n  value: string\n  onValueChange: (value: string) => void\n  onSubmit: (value: string) => void\n  onAttach?: () => void\n  variant?: PromptBarVariant\n  placeholder?: string\n  disabled?: boolean\n  sources?: PromptSource[]\n  commands?: PromptCommand[]\n  models?: PromptModel[]\n  selectedModel?: string\n  onModelChange?: (id: string) => void\n  onSourceSelect?: (source: PromptSource) => void\n  onCommandSelect?: (command: PromptCommand) => void\n  isListening?: boolean\n  onDictationToggle?: () => void\n  isRunning?: boolean\n  onStop?: () => void\n  className?: string\n}\nfunction token(value: string) {\n  const match = /(^|\\s)([@/])([\\w-]*)$/.exec(value)\n  return match\n    ? {\n        kind: match[2] === \"@\" ? (\"source\" as const) : (\"command\" as const),\n        query: match[3].toLowerCase(),\n        start: match.index + match[1].length,\n      }\n    : null\n}\nexport function PromptBar({\n  value,\n  onValueChange,\n  onSubmit,\n  onAttach,\n  variant = \"rounded\",\n  placeholder = \"Ask anything\",\n  disabled = false,\n  sources = [],\n  commands = [],\n  models = [],\n  selectedModel,\n  onModelChange,\n  onSourceSelect,\n  onCommandSelect,\n  isListening = false,\n  onDictationToggle,\n  isRunning = false,\n  onStop,\n  className,\n}: PromptBarProps) {\n  const current = token(value)\n  const [menu, setMenu] = React.useState<\"source\" | \"command\" | null>(null)\n  const [active, setActive] = React.useState(0)\n  const [dismissedValue, setDismissedValue] = React.useState<string>()\n  const kind = menu ?? (dismissedValue === value ? null : current?.kind) ?? null\n  const query = menu ? \"\" : (current?.query ?? \"\")\n  const options =\n    kind === \"source\"\n      ? sources.filter((item) =>\n          `${item.label} ${item.description ?? \"\"}`\n            .toLowerCase()\n            .includes(query)\n        )\n      : kind === \"command\"\n        ? commands.filter((item) =>\n            `${item.label} ${item.description ?? \"\"}`\n              .toLowerCase()\n              .includes(query)\n          )\n        : []\n  const close = () => {\n    setDismissedValue(value)\n    setMenu(null)\n    setActive(0)\n  }\n  const select = (index: number) => {\n    const option = options[index]\n    if (!option || !kind) return\n    const inserted = kind === \"source\" ? `@${option.label}` : `/${option.label}`\n    onValueChange(\n      current\n        ? `${value.slice(0, current.start)}${inserted} `\n        : `${value}${value ? \" \" : \"\"}${inserted} `\n    )\n    if (kind === \"source\") onSourceSelect?.(option as PromptSource)\n    else onCommandSelect?.(option as PromptCommand)\n    close()\n  }\n  const submit = () => {\n    const text = value.trim()\n    if (text && !disabled && !isRunning) onSubmit(text)\n  }\n  return (\n    <div className={cx(\"relative\", className)}>\n      {kind && options.length > 0 && !disabled && !isRunning && (\n        <div\n          role=\"listbox\"\n          aria-label={kind === \"source\" ? \"Data sources\" : \"Commands\"}\n          className=\"border-separator-border bg-background-primary-default absolute bottom-full z-20 mb-2 w-full max-w-sm rounded-xl border p-1.5 shadow-lg\"\n        >\n          {options.map((option, index) => (\n            <button\n              key={option.id}\n              type=\"button\"\n              role=\"option\"\n              aria-selected={active === index}\n              onMouseEnter={() => setActive(index)}\n              onClick={() => select(index)}\n              className={cx(\n                \"flex min-h-9 w-full items-center gap-2 rounded-lg px-2 text-left\",\n                active === index && \"bg-background-secondary-default\"\n              )}\n            >\n              <span className=\"text-xs font-medium\">\n                {kind === \"source\" ? \"@\" : \"/\"}\n                {option.label}\n              </span>\n              {option.description && (\n                <span className=\"text-text-secondary ml-auto text-xs\">\n                  {option.description}\n                </span>\n              )}\n            </button>\n          ))}\n        </div>\n      )}\n      <div\n        className={cx(\n          \"border-separator-border bg-background-primary-default flex min-h-11 items-center gap-1.5 border p-1.5\",\n          variant === \"pill\" ? \"rounded-full\" : \"rounded-xl\"\n        )}\n      >\n        <Button\n          variant=\"ghost\"\n          size=\"small\"\n          iconOnly\n          aria-label=\"Attach file\"\n          leadingIcon={Paperclip}\n          disabled={disabled || isRunning}\n          onClick={onAttach}\n        />\n        {sources.length > 0 && (\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            iconOnly\n            aria-label=\"Mention a data source\"\n            leadingIcon={AtSign}\n            disabled={disabled || isRunning}\n            onClick={() => {\n              setMenu(menu === \"source\" ? null : \"source\")\n              setActive(0)\n            }}\n          />\n        )}{\" \"}\n        {commands.length > 0 && (\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            iconOnly\n            aria-label=\"Choose a command\"\n            leadingIcon={Command}\n            disabled={disabled || isRunning}\n            onClick={() => {\n              setMenu(menu === \"command\" ? null : \"command\")\n              setActive(0)\n            }}\n          />\n        )}\n        <input\n          value={value}\n          disabled={disabled || isRunning}\n          onChange={(event) => {\n            onValueChange(event.target.value)\n            setMenu(null)\n            setActive(0)\n          }}\n          onKeyDown={(event) => {\n            if (\n              kind &&\n              options.length &&\n              (event.key === \"ArrowDown\" || event.key === \"ArrowUp\")\n            ) {\n              event.preventDefault()\n              setActive((index) =>\n                event.key === \"ArrowDown\"\n                  ? Math.min(options.length - 1, index + 1)\n                  : Math.max(0, index - 1)\n              )\n              return\n            }\n            if (\n              kind &&\n              options.length > 0 &&\n              event.key === \"Enter\" &&\n              !event.nativeEvent.isComposing\n            ) {\n              event.preventDefault()\n              select(active)\n              return\n            }\n            if (event.key === \"Escape\" && kind) {\n              event.preventDefault()\n              close()\n              return\n            }\n            if (\n              event.key === \"Enter\" &&\n              !event.nativeEvent.isComposing &&\n              !disabled &&\n              !isRunning\n            ) {\n              event.preventDefault()\n              submit()\n            }\n          }}\n          placeholder={placeholder}\n          className=\"placeholder:text-text-tertiary min-w-0 flex-1 bg-transparent px-1 text-[13px] outline-none disabled:cursor-not-allowed\"\n        />\n        {models.length > 0 && (\n          <select\n            aria-label=\"Model\"\n            value={selectedModel}\n            disabled={disabled || isRunning}\n            onChange={(event) => onModelChange?.(event.target.value)}\n            className=\"bg-background-secondary-default h-8 max-w-28 rounded-lg px-2 text-xs outline-none\"\n          >\n            <option value=\"\" disabled>\n              Model\n            </option>\n            {models.map((model) => (\n              <option key={model.id} value={model.id}>\n                {model.label}\n              </option>\n            ))}\n          </select>\n        )}\n        {onDictationToggle && (\n          <Button\n            variant=\"ghost\"\n            size=\"small\"\n            iconOnly\n            aria-label={isListening ? \"Stop dictation\" : \"Start dictation\"}\n            aria-pressed={isListening}\n            leadingIcon={Mic}\n            disabled={disabled || isRunning}\n            onClick={onDictationToggle}\n          />\n        )}{\" \"}\n        {isRunning ? (\n          <Button\n            variant=\"secondary\"\n            size=\"small\"\n            iconOnly\n            aria-label=\"Stop generation\"\n            leadingIcon={Square}\n            disabled={disabled}\n            onClick={onStop}\n          />\n        ) : (\n          <Button\n            size=\"small\"\n            iconOnly\n            aria-label=\"Send prompt\"\n            leadingIcon={ArrowUp}\n            disabled={disabled || !value.trim()}\n            onClick={submit}\n          />\n        )}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-recommendation-card",
      "type": "registry:block",
      "title": "Beautiful Recommendation Card",
      "description": "recommendation card",
      "dependencies": [
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/recommendation-card.tsx",
          "target": "@components/beautiful-ui/recommendation-card.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\n\nexport interface RecommendationOption {\n  id: string\n  label: string\n  description?: string\n}\nexport interface RecommendationCardProps {\n  title: string\n  description: string\n  confidence?: number\n  alternatives?: RecommendationOption[]\n  onAccept?: () => void\n  onSelectAlternative?: (id: string) => void\n  className?: string\n}\nexport function RecommendationCard({\n  title,\n  description,\n  confidence,\n  alternatives = [],\n  onAccept,\n  onSelectAlternative,\n  className,\n}: RecommendationCardProps) {\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default rounded-xl border p-4\",\n        className\n      )}\n    >\n      <div className=\"flex justify-between gap-4\">\n        <h3 className=\"text-sm font-semibold\">{title}</h3>\n        {confidence !== undefined && (\n          <span className=\"text-text-secondary text-xs\">\n            {Math.round(confidence * 100)}% confidence\n          </span>\n        )}\n      </div>\n      <p className=\"text-text-secondary mt-2 text-[13px] leading-5\">\n        {description}\n      </p>\n      {alternatives.length > 0 && (\n        <div className=\"divide-separator-border border-separator-border mt-4 divide-y border-y\">\n          {alternatives.map((option) => (\n            <button\n              key={option.id}\n              onClick={() => onSelectAlternative?.(option.id)}\n              className=\"min-h-10 w-full py-2 text-left\"\n            >\n              <span className=\"text-[13px] font-medium\">{option.label}</span>\n              {option.description && (\n                <span className=\"text-text-secondary block text-xs\">\n                  {option.description}\n                </span>\n              )}\n            </button>\n          ))}\n        </div>\n      )}\n      <div className=\"mt-4 flex justify-end\">\n        <Button onClick={onAccept}>Accept recommendation</Button>\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-records-table",
      "type": "registry:block",
      "title": "Beautiful Records Table",
      "description": "records table",
      "dependencies": [
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/records-table.tsx",
          "target": "@components/beautiful-ui/records-table.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { ChevronDown, ChevronUp } from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\n\nexport interface RecordRow {\n  id: string\n  name: string\n  categories?: string[]\n  updated?: string\n  strength?: string\n  links?: number\n}\nexport interface RecordsTableProps {\n  records: RecordRow[]\n  sortKey?: keyof RecordRow\n  sortDirection?: \"asc\" | \"desc\"\n  onSort?: (key: keyof RecordRow) => void\n  onSelect?: (id: string) => void\n  className?: string\n}\n\nconst columns = [\"name\", \"categories\", \"updated\", \"strength\", \"links\"] as const\nconst labels: Record<(typeof columns)[number], string> = {\n  name: \"Record\",\n  categories: \"Categories\",\n  updated: \"Updated\",\n  strength: \"Strength\",\n  links: \"Links\",\n}\n\nexport function RecordsTable({\n  records,\n  sortKey,\n  sortDirection = \"asc\",\n  onSort,\n  onSelect,\n  className,\n}: RecordsTableProps) {\n  const reduce = useReducedMotion() ?? false\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default overflow-hidden rounded-xl border\",\n        className\n      )}\n    >\n      <div className=\"overflow-auto\">\n        <table className=\"w-full min-w-[680px] text-left text-[13px]\">\n          <thead className=\"bg-background-secondary-default text-text-secondary text-xs\">\n            <tr>\n              {columns.map((key) => (\n                <th key={key} className=\"h-9 px-3 font-medium\">\n                  <button\n                    type=\"button\"\n                    onClick={() => onSort?.(key)}\n                    className=\"focus-visible:ring-border-focus-ring flex items-center gap-1 rounded-sm outline-none focus-visible:ring-2\"\n                  >\n                    {labels[key]}\n                    <AnimatePresence initial={false} mode=\"wait\">\n                      {sortKey === key && (\n                        <motion.span\n                          key={sortDirection}\n                          initial={reduce ? false : { opacity: 0, y: 2 }}\n                          animate={{ opacity: 1, y: 0 }}\n                          exit={reduce ? undefined : { opacity: 0, y: -2 }}\n                          transition={{ duration: reduce ? 0 : 0.12 }}\n                        >\n                          {sortDirection === \"asc\" ? (\n                            <ChevronUp className=\"size-3\" />\n                          ) : (\n                            <ChevronDown className=\"size-3\" />\n                          )}\n                        </motion.span>\n                      )}\n                    </AnimatePresence>\n                  </button>\n                </th>\n              ))}\n            </tr>\n          </thead>\n          <motion.tbody layout className=\"divide-separator-border divide-y\">\n            <AnimatePresence initial={false}>\n              {records.map((record) => (\n                <motion.tr\n                  key={record.id}\n                  layout=\"position\"\n                  initial={reduce ? false : { opacity: 0, y: 4 }}\n                  animate={{ opacity: 1, y: 0 }}\n                  exit={reduce ? undefined : { opacity: 0, y: -4 }}\n                  transition={\n                    reduce\n                      ? { duration: 0 }\n                      : { type: \"spring\", stiffness: 460, damping: 40 }\n                  }\n                  className=\"hover:bg-background-secondary-default\"\n                >\n                  <td className=\"h-11 px-3\">\n                    <button\n                      type=\"button\"\n                      className=\"text-text-primary focus-visible:ring-border-focus-ring font-medium underline-offset-2 hover:underline focus-visible:ring-2\"\n                      onClick={() => onSelect?.(record.id)}\n                    >\n                      {record.name}\n                    </button>\n                  </td>\n                  <td className=\"h-11 px-3\">\n                    <div className=\"flex max-w-64 flex-wrap gap-1\">\n                      {record.categories?.map((category) => (\n                        <span\n                          key={category}\n                          className=\"bg-background-secondary-default text-text-secondary rounded-sm px-1.5 py-0.5 text-xs\"\n                        >\n                          {category}\n                        </span>\n                      ))}\n                    </div>\n                  </td>\n                  <td className=\"text-text-secondary h-11 px-3\">\n                    {record.updated ?? \"Not updated\"}\n                  </td>\n                  <td className=\"text-text-secondary h-11 px-3\">\n                    {record.strength ?? \"Not scored\"}\n                  </td>\n                  <td className=\"text-text-primary h-11 px-3 tabular-nums\">\n                    {record.links ?? 0}\n                  </td>\n                </motion.tr>\n              ))}\n            </AnimatePresence>\n          </motion.tbody>\n        </table>\n      </div>\n      <footer className=\"border-separator-border text-text-secondary flex min-h-10 items-center justify-between border-t px-3 text-xs\">\n        <span>{records.length} records</span>\n        <span>\n          {records.reduce((sum, record) => sum + (record.links ?? 0), 0)} links\n        </span>\n      </footer>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-search-list",
      "type": "registry:block",
      "title": "Beautiful Search List",
      "description": "search list",
      "dependencies": [
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/search-list.tsx",
          "target": "@components/beautiful-ui/search-list.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Search } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport interface SearchListItem {\n  id: string\n  label: string\n  description?: string\n}\nexport interface SearchListProps {\n  value: string\n  items: SearchListItem[]\n  onValueChange: (value: string) => void\n  onSelect?: (id: string) => void\n  placeholder?: string\n  className?: string\n}\nexport function SearchList({\n  value,\n  items,\n  onValueChange,\n  onSelect,\n  placeholder = \"Search\",\n  className,\n}: SearchListProps) {\n  const [activeIndex, setActiveIndex] = React.useState(0)\n  const visible = items.filter((item) =>\n    `${item.label} ${item.description ?? \"\"}`\n      .toLowerCase()\n      .includes(value.toLowerCase())\n  )\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default max-w-xl rounded-xl border p-3\",\n        className\n      )}\n    >\n      <label className=\"border-separator-border flex h-10 items-center gap-2 border-b px-2\">\n        <Search className=\"text-text-secondary size-4\" />\n        <input\n          value={value}\n          onChange={(e) => onValueChange(e.target.value)}\n          onKeyDown={(event) => {\n            if (event.key === \"ArrowDown\") {\n              event.preventDefault()\n              setActiveIndex((index) => Math.min(visible.length - 1, index + 1))\n            } else if (event.key === \"ArrowUp\") {\n              event.preventDefault()\n              setActiveIndex((index) => Math.max(0, index - 1))\n            } else if (event.key === \"Enter\" && visible[activeIndex]) {\n              event.preventDefault()\n              onSelect?.(visible[activeIndex].id)\n            }\n          }}\n          placeholder={placeholder}\n          className=\"flex-1 bg-transparent text-[13px] outline-none\"\n        />\n      </label>\n      <div className=\"divide-separator-border mt-2 divide-y\">\n        {visible.map((item, index) => (\n          <button\n            key={item.id}\n            onClick={() => onSelect?.(item.id)}\n            className={cx(\n              \"min-h-10 w-full px-2 text-left\",\n              index === activeIndex && \"bg-background-secondary-default\"\n            )}\n          >\n            <span className=\"block text-[13px] font-medium\">{item.label}</span>\n            {item.description && (\n              <span className=\"text-text-secondary block text-xs\">\n                {item.description}\n              </span>\n            )}\n          </button>\n        ))}\n        {visible.length === 0 && (\n          <p className=\"text-text-secondary p-6 text-center text-[13px]\">\n            No results\n          </p>\n        )}\n      </div>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-selection-actions",
      "type": "registry:block",
      "title": "Beautiful Selection Actions",
      "description": "selection actions",
      "dependencies": [
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/selection-actions.tsx",
          "target": "@components/beautiful-ui/selection-actions.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\n\nexport interface SelectionAction {\n  id: string\n  label: string\n}\nexport interface SelectionActionsProps {\n  selectedText: string\n  actions: SelectionAction[]\n  result?: string\n  isWorking?: boolean\n  onAction?: (id: string) => void\n  onReplace?: (value: string) => void\n  className?: string\n}\nexport function SelectionActions({\n  selectedText,\n  actions,\n  result,\n  isWorking = false,\n  onAction,\n  onReplace,\n  className,\n}: SelectionActionsProps) {\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default max-w-2xl rounded-xl border p-4\",\n        className\n      )}\n    >\n      <p className=\"text-text-secondary text-xs\">Selected text</p>\n      <blockquote className=\"border-separator-border mt-2 border-l-2 pl-3 text-[13px]\">\n        {selectedText}\n      </blockquote>\n      <div className=\"mt-3 flex flex-wrap gap-2\">\n        {actions.map((action) => (\n          <Button\n            key={action.id}\n            variant=\"secondary\"\n            size=\"small\"\n            disabled={isWorking}\n            onClick={() => onAction?.(action.id)}\n          >\n            {action.label}\n          </Button>\n        ))}\n      </div>\n      {isWorking && (\n        <p className=\"text-text-secondary mt-4 text-[13px]\">\n          Rewriting selection\n        </p>\n      )}\n      {result && (\n        <div className=\"bg-background-secondary-default mt-4 rounded-lg p-3\">\n          <p className=\"text-[13px] leading-5\">{result}</p>\n          <div className=\"mt-3 flex justify-end\">\n            <Button size=\"small\" onClick={() => onReplace?.(result)}>\n              Replace selection\n            </Button>\n          </div>\n        </div>\n      )}\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-sidebar-nav",
      "type": "registry:block",
      "title": "Beautiful Sidebar Nav",
      "description": "sidebar nav",
      "dependencies": [
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/sidebar-nav.tsx",
          "target": "@components/beautiful-ui/sidebar-nav.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { FileText, Search, Settings } from \"lucide-react\"\n\nexport interface SidebarNavItem {\n  id: string\n  label: string\n  count?: number\n}\nexport interface SidebarNavProps {\n  title: string\n  items: SidebarNavItem[]\n  activeId?: string\n  onSelect?: (id: string) => void\n  onSearch?: (value: string) => void\n  onSettings?: () => void\n  className?: string\n}\nexport function SidebarNav({\n  title,\n  items,\n  activeId,\n  onSelect,\n  onSearch,\n  onSettings,\n  className,\n}: SidebarNavProps) {\n  return (\n    <aside\n      className={cx(\n        \"border-separator-border bg-background-primary-default w-full max-w-64 rounded-xl border p-3\",\n        className\n      )}\n    >\n      <h3 className=\"px-2 py-2 text-[13px] font-semibold\">{title}</h3>\n      <label className=\"bg-background-secondary-default flex h-9 items-center gap-2 rounded-lg px-3\">\n        <Search className=\"text-text-secondary size-4\" />\n        <input\n          onChange={(e) => onSearch?.(e.target.value)}\n          placeholder=\"Search\"\n          className=\"min-w-0 flex-1 bg-transparent text-[13px] outline-none\"\n        />\n      </label>\n      <nav className=\"mt-3 space-y-1\">\n        {items.map((item) => (\n          <button\n            key={item.id}\n            onClick={() => onSelect?.(item.id)}\n            className={cx(\n              \"flex min-h-9 w-full items-center gap-2 rounded-lg px-2 text-[13px]\",\n              activeId === item.id &&\n                \"bg-background-secondary-default font-medium\"\n            )}\n          >\n            <FileText className=\"text-text-secondary size-4\" />\n            <span className=\"flex-1 text-left\">{item.label}</span>\n            {item.count !== undefined && (\n              <span className=\"text-text-secondary text-xs\">{item.count}</span>\n            )}\n          </button>\n        ))}\n      </nav>\n      {onSettings && (\n        <button\n          onClick={onSettings}\n          className=\"border-separator-border mt-3 flex min-h-9 w-full items-center gap-2 border-t px-2 pt-3 text-[13px]\"\n        >\n          <Settings className=\"size-4\" />\n          Settings\n        </button>\n      )}\n    </aside>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-streaming-text",
      "type": "registry:block",
      "title": "Beautiful Streaming Text",
      "description": "streaming text",
      "dependencies": [
        "lucide-react@0.577.0",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/streaming-text.tsx",
          "target": "@components/beautiful-ui/streaming-text.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/boardui/base/buttons/button\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, Copy, RotateCcw, ThumbsDown, ThumbsUp } from \"lucide-react\"\nimport * as React from \"react\"\n\nexport interface StreamingSource {\n  name: string\n  domain: string\n  href: string\n}\nexport interface StreamingToken {\n  text: string\n  citation?: number\n}\nexport interface StreamingTextProps {\n  children: string\n  tokens?: StreamingToken[]\n  visibleTokenCount?: number\n  sources?: StreamingSource[]\n  isStreaming?: boolean\n  followUps?: string[]\n  onCopy?: (text: string) => void\n  onRetry?: () => void\n  onFeedback?: (value: \"up\" | \"down\") => void\n  onFollowUp?: (value: string) => void\n  onComplete?: () => void\n  className?: string\n}\n\nexport function StreamingText({\n  children,\n  tokens,\n  visibleTokenCount,\n  sources = [],\n  isStreaming = false,\n  followUps = [],\n  onCopy,\n  onRetry,\n  onFeedback,\n  onFollowUp,\n  onComplete,\n  className,\n}: StreamingTextProps) {\n  const [copied, setCopied] = React.useState(false)\n  const wasStreaming = React.useRef(isStreaming)\n  const visible = tokens\n    ? tokens.slice(\n        0,\n        visibleTokenCount === undefined\n          ? tokens.length\n          : Math.max(0, visibleTokenCount)\n      )\n    : undefined\n  const renderedText = visible\n    ? visible.map((token) => token.text).join(\"\")\n    : children\n  React.useEffect(() => {\n    if (wasStreaming.current && !isStreaming) onComplete?.()\n    wasStreaming.current = isStreaming\n  }, [isStreaming, onComplete])\n  const copy = async () => {\n    await navigator.clipboard.writeText(renderedText)\n    setCopied(true)\n    onCopy?.(renderedText)\n    window.setTimeout(() => setCopied(false), 1500)\n  }\n  return (\n    <article\n      className={cx(\n        \"border-separator-border bg-background-primary-default rounded-xl border p-5\",\n        className\n      )}\n    >\n      <p className=\"text-text-primary text-[13px] leading-6 whitespace-pre-wrap\">\n        {visible\n          ? visible.map((token, index) => {\n              const source = token.citation\n                ? sources[token.citation - 1]\n                : undefined\n              return (\n                <span key={index}>\n                  {token.text}\n                  {token.citation !== undefined &&\n                    (source ? (\n                      <a\n                        href={source.href}\n                        className=\"bg-background-secondary-default text-accent-600 ml-1 inline-flex rounded-sm px-1.5 font-mono text-[11px]\"\n                      >\n                        {source.domain}\n                      </a>\n                    ) : (\n                      <span className=\"text-text-secondary ml-1 text-xs\">\n                        [{token.citation}]\n                      </span>\n                    ))}\n                </span>\n              )\n            })\n          : children}\n        {isStreaming && (\n          <span\n            className=\"bg-text-primary ml-1 inline-block h-3.5 w-0.5 translate-y-0.5 motion-safe:animate-pulse\"\n            aria-label=\"Streaming\"\n          />\n        )}\n      </p>\n      {!isStreaming && sources.length > 0 && (\n        <details className=\"group mt-3\">\n          <summary className=\"text-text-secondary cursor-pointer list-none text-xs\">\n            {sources.length} sources\n          </summary>\n          <div className=\"divide-separator-border bg-background-secondary-default mt-2 divide-y rounded-lg px-3\">\n            {sources.map((source) => (\n              <a\n                key={source.href}\n                href={source.href}\n                className=\"flex items-center justify-between gap-3 py-2 text-xs\"\n              >\n                <span className=\"text-text-primary\">{source.name}</span>\n                <span className=\"text-text-secondary font-mono\">\n                  {source.domain}\n                </span>\n              </a>\n            ))}\n          </div>\n        </details>\n      )}\n      {!isStreaming && (\n        <div className=\"border-separator-border mt-3 flex gap-1 border-t pt-3\">\n          <Button\n            variant=\"ghost\"\n            size=\"xs\"\n            leadingIcon={copied ? Check : Copy}\n            onClick={copy}\n          >\n            {copied ? \"Copied\" : \"Copy\"}\n          </Button>\n          {onRetry && (\n            <Button\n              variant=\"ghost\"\n              size=\"xs\"\n              iconOnly\n              leadingIcon={RotateCcw}\n              aria-label=\"Retry response\"\n              onClick={onRetry}\n            />\n          )}\n          {onFeedback && (\n            <>\n              <Button\n                variant=\"ghost\"\n                size=\"xs\"\n                iconOnly\n                leadingIcon={ThumbsUp}\n                aria-label=\"Helpful\"\n                onClick={() => onFeedback(\"up\")}\n              />\n              <Button\n                variant=\"ghost\"\n                size=\"xs\"\n                iconOnly\n                leadingIcon={ThumbsDown}\n                aria-label=\"Not helpful\"\n                onClick={() => onFeedback(\"down\")}\n              />\n            </>\n          )}\n        </div>\n      )}\n      {!isStreaming && followUps.length > 0 && (\n        <div className=\"mt-4\">\n          <p className=\"text-text-secondary text-xs font-medium\">Follow-ups</p>\n          <div className=\"divide-separator-border mt-1 divide-y\">\n            {followUps.map((item) => (\n              <button\n                key={item}\n                onClick={() => onFollowUp?.(item)}\n                className=\"text-text-primary hover:bg-background-secondary-default block min-h-9 w-full text-left text-[13px]\"\n              >\n                {item}\n              </button>\n            ))}\n          </div>\n        </div>\n      )}\n    </article>\n  )\n}\n"
        },
        {
          "path": "components/boardui/base/buttons/button.tsx",
          "target": "@components/boardui/base/buttons/button.tsx",
          "type": "registry:component",
          "content": "import { cx, sortCx } from \"@/components/boardui/utils/cx\"\nimport type {\n  AnchorHTMLAttributes,\n  ButtonHTMLAttributes,\n  ComponentType,\n  ReactNode,\n  Ref,\n} from \"react\"\nimport { Focusable } from \"react-aria-components\"\n\n/**\n * Figma source: Board UI → Buttons (node 3656:13819).\n *\n * Variant matrix from Figma:\n *   Type     = Primary | Secondary | Ghost | Danger\n *   Size     = Medium  | Small | Xs\n *   State    = Default | Hover | Active | Disabled        (CSS pseudo)\n *   OnlyIcon = false   | true\n *\n * Sizing (1:1 with Figma):\n *\n *                       Medium                    Small                     Xs\n *   container          h=36, p=8,   r=10         h=32, px=8 py=6, r=8      h=24, px=8, r=4\n *   gap                 2px                       2px                      1.33px→1\n *   icon                20×20                     18×18                    14×14\n *   label wrapper       px=4                      px=2                     px=2\n *   text style          Body 1/Medium             Body 1/Medium            Caption 1/Semibold\n *   icon-only square    36×36 (content-derived)   32×32 (forced size)      24×24 (forced size)\n *\n * `xs` is the smallest tier - first needed for the calendar template's\n * event-details modal (\"Join\" / edit-icon buttons, node 3920:10954), which\n * scales every dimension down by the same ~0.667 factor from Figma; the\n * table above rounds those to clean pixel values rather than reproducing\n * the fractional source numbers.\n *\n * Icons are rendered by the component itself via the `leadingIcon` /\n * `trailingIcon` props so the consumer can't pass the wrong size. Pass\n * a Remix Icon component reference (`RiAddLine`, not `<RiAddLine />`).\n *\n * For icon-only buttons:\n *   <Button iconOnly leadingIcon={RiAddLine} aria-label=\"Add\" />\n *\n * The HTML `type` prop is preserved; Figma's \"Type\" enum is renamed to\n * `variant` to avoid the clash.\n */\n\ntype ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\"\ntype ButtonSize = \"medium\" | \"small\" | \"xs\"\n\ntype IconComponent = ComponentType<{\n  className?: string\n  \"aria-hidden\"?: boolean | \"true\" | \"false\"\n}>\n\nexport interface ButtonProps\n  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLButtonElement>\n}\n\nexport interface ButtonLinkProps\n  extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"children\"> {\n  variant?: ButtonVariant\n  size?: ButtonSize\n  iconOnly?: boolean\n  leadingIcon?: IconComponent\n  trailingIcon?: IconComponent\n  children?: ReactNode\n  ref?: Ref<HTMLAnchorElement>\n}\n\nconst styles = sortCx({\n  base: [\n    \"inline-flex items-center justify-center gap-0.5 whitespace-nowrap overflow-hidden\",\n    \"font-sans select-none cursor-pointer\",\n    \"button-press-motion\",\n    \"outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-border-focus-ring\",\n    \"disabled:cursor-not-allowed aria-disabled:cursor-not-allowed\",\n  ].join(\" \"),\n\n  // Base shape per size (used when label is present OR medium icon-only).\n  size: {\n    medium: \"h-9 rounded-2lg p-2 text-body-medium\",\n    small: \"h-8 rounded-lg px-2 py-1.5 text-body-medium\",\n    xs: \"h-6 rounded-sm px-2 text-caption-1-semibold\",\n  },\n\n  // Icon-only override:\n  //   Medium → keep p-2; w expands from content (8+20+8 = 36) → square.\n  //   Small  → Figma forces 32×32 even though 8+18+8=34, so we hard-set size-8\n  //            and zero the padding; the inner flex centers the 18px icon.\n  //   Xs     → forces 24×24, content-centered - used for the calendar\n  //            template's edit-icon buttons (timezone/participants/reminder).\n  iconOnlySize: {\n    medium: \"\", // base size already produces 36×36 with a 20px icon\n    small: \"size-8 p-0\", // hard 32×32, content-centered\n    xs: \"size-6 p-0\", // hard 24×24, content-centered\n  },\n\n  icon: {\n    medium: \"size-5 shrink-0\", // 20px\n    small: \"size-[18px] shrink-0\", // 18px\n    xs: \"size-3.5 shrink-0\", // 14px\n  },\n\n  label: {\n    medium: \"inline-flex items-center justify-center px-1 shrink-0\", // px=4\n    small: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n    xs: \"inline-flex items-center justify-center px-0.5 shrink-0\", // px=2\n  },\n\n  variant: {\n    primary: [\n      \"bg-button-primary\",\n      \"disabled:text-button-primary-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:text-button-primary-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n    danger: [\n      \"bg-button-danger text-text-white shadow-xs\",\n      \"disabled:text-foreground-disabled-danger disabled:shadow-none\",\n      \"aria-disabled:text-foreground-disabled-danger aria-disabled:shadow-none\",\n    ].join(\" \"),\n    secondary: [\n      \"bg-background-primary-default text-text-primary\",\n      \"border border-border-button-default shadow-xs\",\n      \"hover:bg-background-primary-hover  hover:border-border-button-hover\",\n      \"active:bg-background-primary-active active:border-border-button-active\",\n      \"disabled:bg-background-primary-disabled disabled:border-border-button-default disabled:text-text-tertiary disabled:shadow-none\",\n      \"aria-disabled:bg-background-primary-disabled aria-disabled:border-border-button-default aria-disabled:text-text-tertiary aria-disabled:shadow-none\",\n    ].join(\" \"),\n    ghost: [\n      \"bg-button-ghost-background text-button-ghost-foreground\",\n      \"hover:bg-button-ghost-hover active:bg-button-ghost-active\",\n      \"disabled:bg-button-ghost-disabled disabled:text-button-ghost-disabled-foreground disabled:shadow-none\",\n      \"aria-disabled:bg-button-ghost-disabled aria-disabled:text-button-ghost-disabled-foreground aria-disabled:shadow-none\",\n    ].join(\" \"),\n  },\n})\n\nexport function Button({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  type = \"button\",\n  ref,\n  ...props\n}: ButtonProps) {\n  return (\n    <Focusable isDisabled={props.disabled}>\n      <button\n        ref={ref}\n        type={type}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </button>\n    </Focusable>\n  )\n}\n\n/** Anchor counterpart to Button for navigational actions. */\nexport function ButtonLink({\n  variant = \"primary\",\n  size = \"medium\",\n  iconOnly = false,\n  leadingIcon: Leading,\n  trailingIcon: Trailing,\n  children,\n  className,\n  ref,\n  ...props\n}: ButtonLinkProps) {\n  return (\n    <Focusable>\n      <a\n        ref={ref}\n        className={cx(\n          styles.base,\n          styles.size[size],\n          styles.variant[variant],\n          iconOnly && styles.iconOnlySize[size],\n          className\n        )}\n        {...props}\n      >\n        {Leading ? <Leading className={styles.icon[size]} aria-hidden /> : null}\n        {iconOnly && !Leading && children != null ? (\n          <span\n            aria-hidden\n            className={cx(\n              styles.icon[size],\n              \"inline-flex items-center justify-center [&>svg]:size-full\"\n            )}\n          >\n            {children}\n          </span>\n        ) : null}\n        {!iconOnly && children !== undefined && children !== null && (\n          <span className={styles.label[size]}>{children}</span>\n        )}\n        {!iconOnly && Trailing ? (\n          <Trailing className={styles.icon[size]} aria-hidden />\n        ) : null}\n      </a>\n    </Focusable>\n  )\n}\n\n/** Style maps, exported for advanced composition and the dev Design Tuner. */\nexport const buttonStyles = styles\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-task-rows",
      "type": "registry:block",
      "title": "Beautiful Task Rows",
      "description": "task rows",
      "dependencies": [
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/task-rows.tsx",
          "target": "@components/beautiful-ui/task-rows.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, ChevronDown } from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport * as React from \"react\"\n\nexport type TaskRowsVariant = \"capsules\" | \"list\"\nexport interface TaskRow {\n  id: string\n  title: string\n  meta?: string\n  status: \"pending\" | \"running\" | \"complete\"\n  progress?: number\n  details?: { label: string; meta?: string }[]\n}\nexport interface TaskRowsProps {\n  tasks: TaskRow[]\n  variant?: TaskRowsVariant\n  onSelect?: (id: string) => void\n  expandedId?: string\n  onToggle?: (id: string, open: boolean) => void\n  className?: string\n}\n\nfunction Marker({\n  status,\n  index,\n}: {\n  status: TaskRow[\"status\"]\n  index: number\n}) {\n  const reduceMotion = useReducedMotion()\n  if (status === \"complete\")\n    return (\n      <span className=\"flex size-5 items-center justify-center rounded-full bg-green-600 text-white\">\n        <Check className=\"size-3\" />\n      </span>\n    )\n  if (status === \"running\")\n    return (\n      <span className=\"text-accent-600 relative flex size-5 items-center justify-center text-[11px] tabular-nums\">\n        <motion.span\n          aria-hidden\n          className=\"border-accent-200 border-t-accent-600 absolute inset-0 rounded-full border\"\n          animate={reduceMotion ? undefined : { rotate: 360 }}\n          transition={{ duration: 0.9, repeat: Infinity, ease: \"linear\" }}\n        />\n        {index + 1}\n      </span>\n    )\n  return (\n    <span\n      className={cx(\n        \"flex size-5 items-center justify-center rounded-full border text-[11px] tabular-nums\",\n        \"border-separator-border text-text-secondary\"\n      )}\n    >\n      {index + 1}\n    </span>\n  )\n}\n\nexport function TaskRows({\n  tasks,\n  variant = \"list\",\n  onSelect,\n  expandedId,\n  onToggle,\n  className,\n}: TaskRowsProps) {\n  const [localExpanded, setLocalExpanded] = React.useState<string>()\n  const reduceMotion = useReducedMotion()\n  const selected = expandedId ?? localExpanded\n  return (\n    <motion.div\n      layout={!reduceMotion}\n      className={cx(\n        variant === \"capsules\"\n          ? \"flex w-full flex-col gap-2\"\n          : \"divide-separator-border border-separator-border divide-y border-y\",\n        className\n      )}\n    >\n      {tasks.map((task, index) => {\n        const open = selected === task.id\n        return (\n          <motion.div\n            layout={!reduceMotion}\n            key={task.id}\n            initial={reduceMotion ? false : { opacity: 0, y: 4 }}\n            animate={{ opacity: 1, y: 0 }}\n            transition={{\n              duration: reduceMotion ? 0 : 0.18,\n              delay: reduceMotion ? 0 : index * 0.04,\n            }}\n            className=\"block w-full\"\n          >\n            <button\n              type=\"button\"\n              aria-expanded={Boolean(task.details?.length) ? open : undefined}\n              onClick={() => {\n                const next = !open\n                if (expandedId === undefined)\n                  setLocalExpanded(next ? task.id : undefined)\n                onSelect?.(task.id)\n                onToggle?.(task.id, next)\n              }}\n              className={cx(\n                \"group focus-visible:ring-border-focus-ring flex items-center gap-2.5 text-left outline-none focus-visible:ring-2\",\n                variant === \"capsules\"\n                  ? \"border-separator-border bg-background-primary-default min-h-10 w-full rounded-full border px-3\"\n                  : \"min-h-10 w-full px-2\"\n              )}\n            >\n              <AnimatePresence mode=\"wait\" initial={false}>\n                <motion.span\n                  key={task.status}\n                  initial={reduceMotion ? false : { opacity: 0, y: 2 }}\n                  animate={{ opacity: 1, y: 0 }}\n                  exit={reduceMotion ? { opacity: 0 } : { opacity: 0, y: -2 }}\n                  className=\"inline-flex\"\n                >\n                  <Marker status={task.status} index={index} />\n                </motion.span>\n              </AnimatePresence>\n              <span className=\"text-text-primary min-w-0 flex-1 truncate text-[13px] font-medium\">\n                {task.title}\n              </span>\n              <span className=\"text-text-secondary ml-auto flex shrink-0 items-center gap-2 text-xs tabular-nums\">\n                {task.meta && <span>{task.meta}</span>}\n                {task.progress !== undefined && <span>{task.progress}%</span>}\n                {task.status === \"complete\" && (\n                  <span className=\"rounded-full bg-green-500/10 px-2 py-0.5 text-[11px] text-green-600 dark:text-green-400\">\n                    Completed\n                  </span>\n                )}\n                {task.details?.length ? (\n                  <ChevronDown\n                    className={cx(\n                      \"size-3.5 transition-transform\",\n                      open && \"rotate-180\"\n                    )}\n                  />\n                ) : null}\n              </span>\n            </button>\n            <AnimatePresence initial={false}>\n              {open && task.details?.length ? (\n                <motion.div\n                  initial={reduceMotion ? false : { height: 0, opacity: 0 }}\n                  animate={{ height: \"auto\", opacity: 1 }}\n                  exit={\n                    reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }\n                  }\n                  transition={{\n                    duration: reduceMotion ? 0 : 0.2,\n                    ease: [0.22, 1, 0.36, 1],\n                  }}\n                  className={cx(\n                    \"bg-background-secondary-default overflow-hidden p-3\",\n                    variant === \"capsules\"\n                      ? \"w-full rounded-lg\"\n                      : \"border-separator-border border-t\"\n                  )}\n                >\n                  <div className=\"divide-separator-border divide-y\">\n                    {task.details.map((detail) => (\n                      <div\n                        key={detail.label}\n                        className=\"flex min-h-8 items-center justify-between gap-3 text-xs\"\n                      >\n                        <span className=\"text-text-primary\">\n                          {detail.label}\n                        </span>\n                        <span className=\"text-text-secondary text-right\">\n                          {detail.meta}\n                        </span>\n                      </div>\n                    ))}\n                  </div>\n                </motion.div>\n              ) : null}\n            </AnimatePresence>\n          </motion.div>\n        )\n      })}\n    </motion.div>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-thinking-state",
      "type": "registry:block",
      "title": "Beautiful Thinking State",
      "description": "thinking state",
      "dependencies": [
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/thinking-state.tsx",
          "target": "@components/beautiful-ui/thinking-state.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport {\n  Check,\n  ChevronDown,\n  Circle,\n  ExternalLink,\n  FileEdit,\n  FileText,\n  LoaderCircle,\n  Play,\n  Search,\n} from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport * as React from \"react\"\n\nexport type ThinkingVariant = \"steps\" | \"reasoning\" | \"search\" | \"coding\"\nexport interface ThinkingRow {\n  id: string\n  label: string\n  detail?: string\n  status: \"pending\" | \"running\" | \"complete\"\n}\nexport interface ThinkingSource {\n  id: string\n  title: string\n  domain: string\n  href: string\n}\nexport interface ThinkingCodeTool {\n  id: string\n  action: \"read\" | \"edit\" | \"run\"\n  target: string\n  additions?: number\n  deletions?: number\n  detail?: string\n}\nexport interface ThinkingStateProps {\n  variant?: ThinkingVariant\n  title?: string\n  rows?: ThinkingRow[]\n  reasoning?: string[]\n  query?: string\n  sources?: ThinkingSource[]\n  codeTools?: ThinkingCodeTool[]\n  expanded?: boolean\n  status?: \"running\" | \"complete\"\n  visibleCount?: number\n  selectedToolId?: string\n  onExpandedChange?: (expanded: boolean) => void\n  onToolSelect?: (id: string | undefined) => void\n  className?: string\n}\nexport function ThinkingState({\n  variant = \"steps\",\n  title,\n  rows = [],\n  reasoning = [],\n  query = \"\",\n  sources = [],\n  codeTools = [],\n  expanded,\n  status = \"running\",\n  visibleCount,\n  selectedToolId,\n  onExpandedChange,\n  onToolSelect,\n  className,\n}: ThinkingStateProps) {\n  const [localExpanded, setLocalExpanded] = React.useState(true)\n  const [localTool, setLocalTool] = React.useState<string>()\n  const reduceMotion = useReducedMotion()\n  const open = expanded ?? localExpanded\n  const selected = selectedToolId ?? localTool\n  const toggle = () => {\n    if (expanded === undefined) setLocalExpanded(!open)\n    onExpandedChange?.(!open)\n  }\n  const heading =\n    title ??\n    (variant === \"search\"\n      ? \"Searched the workspace\"\n      : variant === \"coding\"\n        ? \"Ran tools\"\n        : \"Thinking\")\n  return (\n    <section\n      className={cx(\n        \"border-separator-border bg-background-primary-default max-w-xl rounded-xl border\",\n        className\n      )}\n    >\n      <button\n        type=\"button\"\n        aria-expanded={open}\n        onClick={toggle}\n        className=\"flex min-h-9 w-full items-center gap-2 px-4 text-left\"\n      >\n        {status === \"running\" ? (\n          <LoaderCircle className=\"text-text-secondary size-4 animate-spin\" />\n        ) : (\n          <Check className=\"text-text-secondary size-4\" />\n        )}\n        <span className=\"flex-1 text-[13px] font-medium\">{heading}</span>\n        <span className=\"text-text-secondary text-xs capitalize\">\n          {variant}\n        </span>\n        <ChevronDown\n          className={cx(\n            \"text-text-secondary size-4 transition-transform\",\n            open && \"rotate-180\"\n          )}\n        />\n      </button>\n      <AnimatePresence initial={false}>\n        {open && (\n          <motion.div\n            key=\"trace\"\n            initial={reduceMotion ? false : { height: 0, opacity: 0 }}\n            animate={{ height: \"auto\", opacity: 1 }}\n            exit={reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}\n            transition={{\n              duration: reduceMotion ? 0 : 0.2,\n              ease: [0.22, 1, 0.36, 1],\n            }}\n            className=\"border-separator-border overflow-hidden border-t\"\n          >\n            <motion.div\n              key={variant}\n              initial={reduceMotion ? false : { opacity: 0, y: 4 }}\n              animate={{ opacity: 1, y: 0 }}\n              transition={{ duration: reduceMotion ? 0 : 0.18 }}\n              className=\"p-4\"\n            >\n              {variant === \"steps\" && (\n                <div className=\"divide-separator-border divide-y\">\n                  {rows.slice(0, visibleCount).map((row) => {\n                    const Icon =\n                      row.status === \"complete\"\n                        ? Check\n                        : row.status === \"running\"\n                          ? LoaderCircle\n                          : Circle\n                    return (\n                      <div\n                        key={row.id}\n                        className=\"flex min-h-10 items-center gap-3\"\n                      >\n                        <Icon\n                          className={cx(\n                            \"text-text-secondary size-4\",\n                            row.status === \"running\" && \"animate-spin\"\n                          )}\n                        />\n                        <span className=\"flex-1 text-[13px]\">{row.label}</span>\n                        {row.detail && (\n                          <span className=\"text-text-secondary text-xs\">\n                            {row.detail}\n                          </span>\n                        )}\n                      </div>\n                    )\n                  })}\n                </div>\n              )}\n              {variant === \"reasoning\" && (\n                <div className=\"border-separator-border space-y-3 border-l pl-4\">\n                  {reasoning.slice(0, visibleCount).map((paragraph, index) => (\n                    <p\n                      key={index}\n                      className=\"text-text-secondary text-[13px] leading-5\"\n                    >\n                      {paragraph}\n                    </p>\n                  ))}\n                </div>\n              )}\n              {variant === \"search\" && (\n                <div>\n                  <div className=\"bg-background-secondary-default flex items-center gap-2 rounded-lg px-3 py-2\">\n                    <Search className=\"text-text-secondary size-4\" />\n                    <span className=\"text-[13px]\">{query}</span>\n                  </div>\n                  <div className=\"divide-separator-border mt-3 divide-y\">\n                    {sources.slice(0, visibleCount).map((source) => (\n                      <a\n                        key={source.id}\n                        href={source.href}\n                        className=\"flex min-h-9 items-center gap-3\"\n                      >\n                        <ExternalLink className=\"text-text-secondary size-4\" />\n                        <span className=\"flex-1 text-[13px] font-medium\">\n                          {source.title}\n                        </span>\n                        <span className=\"text-text-secondary text-xs\">\n                          {source.domain}\n                        </span>\n                      </a>\n                    ))}\n                  </div>\n                </div>\n              )}\n              {variant === \"coding\" && (\n                <div className=\"divide-separator-border divide-y\">\n                  {codeTools.slice(0, visibleCount).map((tool) => {\n                    const Icon =\n                      tool.action === \"read\"\n                        ? FileText\n                        : tool.action === \"edit\"\n                          ? FileEdit\n                          : Play\n                    return (\n                      <div key={tool.id}>\n                        <button\n                          type=\"button\"\n                          aria-pressed={selected === tool.id}\n                          onClick={() => {\n                            const next =\n                              selected === tool.id ? undefined : tool.id\n                            if (selectedToolId === undefined) setLocalTool(next)\n                            onToolSelect?.(next)\n                          }}\n                          className={cx(\n                            \"flex min-h-9 w-full items-center gap-3 px-2 text-left\",\n                            selected === tool.id &&\n                              \"bg-background-secondary-default\"\n                          )}\n                        >\n                          <Icon className=\"text-text-secondary size-4\" />\n                          <span className=\"text-text-secondary w-10 text-xs capitalize\">\n                            {tool.action}\n                          </span>\n                          <code className=\"flex-1 truncate text-xs\">\n                            {tool.target}\n                          </code>\n                          {tool.additions !== undefined && (\n                            <span className=\"font-mono text-xs\">\n                              <span className=\"text-green-700 dark:text-green-400\">\n                                +{tool.additions}\n                              </span>{\" \"}\n                              <span className=\"text-red-700 dark:text-red-400\">\n                                -{tool.deletions ?? 0}\n                              </span>\n                            </span>\n                          )}\n                        </button>\n                        {selected === tool.id && tool.detail && (\n                          <pre className=\"bg-background-secondary-default overflow-auto p-3 text-xs\">\n                            {tool.detail}\n                          </pre>\n                        )}\n                      </div>\n                    )\n                  })}\n                </div>\n              )}\n            </motion.div>\n          </motion.div>\n        )}\n      </AnimatePresence>\n    </section>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-tool-chips",
      "type": "registry:block",
      "title": "Beautiful Tool Chips",
      "description": "tool chips",
      "dependencies": [
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/tool-chips.tsx",
          "target": "@components/beautiful-ui/tool-chips.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { Check, ChevronDown, LoaderCircle, Wrench } from \"lucide-react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport * as React from \"react\"\n\nexport interface ToolStep {\n  id: string\n  label: string\n  detail?: string\n  chip?: string\n  additions?: number\n  deletions?: number\n  status: \"running\" | \"complete\" | \"error\"\n}\nexport interface ToolDiff {\n  file: string\n  additions: number\n  deletions: number\n  lines?: string[]\n}\nexport interface ToolChipsProps {\n  steps: ToolStep[]\n  diffs?: ToolDiff[]\n  expandedId?: string\n  onToggle?: (id: string) => void\n  visibleStepCount?: number\n  onDiffToggle?: (file: string, open: boolean) => void\n  className?: string\n}\nexport function ToolChips({\n  steps,\n  diffs = [],\n  expandedId,\n  onToggle,\n  visibleStepCount,\n  onDiffToggle,\n  className,\n}: ToolChipsProps) {\n  const [localExpanded, setLocalExpanded] = React.useState<string>()\n  const [openDiff, setOpenDiff] = React.useState<string>()\n  const reduceMotion = useReducedMotion()\n  const selected = expandedId ?? localExpanded\n  return (\n    <motion.div\n      layout={!reduceMotion}\n      className={cx(\n        \"divide-separator-border border-separator-border bg-background-primary-default divide-y rounded-xl border\",\n        className\n      )}\n    >\n      {steps.slice(0, visibleStepCount).map((step) => {\n        const open = step.id === selected\n        const Icon =\n          step.status === \"running\"\n            ? LoaderCircle\n            : step.status === \"complete\"\n              ? Check\n              : Wrench\n        return (\n          <motion.div\n            layout={!reduceMotion}\n            key={step.id}\n            initial={reduceMotion ? false : { opacity: 0, y: 4 }}\n            animate={{ opacity: 1, y: 0 }}\n            transition={{ duration: reduceMotion ? 0 : 0.18 }}\n          >\n            <button\n              onClick={() => {\n                const next = open ? undefined : step.id\n                if (expandedId === undefined) setLocalExpanded(next)\n                onToggle?.(next ?? \"\")\n              }}\n              className=\"flex min-h-9 w-full items-center gap-2 px-3 text-left\"\n            >\n              <AnimatePresence mode=\"wait\" initial={false}>\n                <motion.span\n                  key={step.status}\n                  initial={reduceMotion ? false : { opacity: 0, y: 2 }}\n                  animate={{ opacity: 1, y: 0 }}\n                  exit={reduceMotion ? { opacity: 0 } : { opacity: 0, y: -2 }}\n                  className=\"inline-flex\"\n                >\n                  <Icon\n                    className={cx(\n                      \"text-text-secondary size-4\",\n                      step.status === \"running\" && \"animate-spin\"\n                    )}\n                  />\n                </motion.span>\n              </AnimatePresence>\n              <span className=\"text-[13px] font-medium\">{step.label}</span>\n              {step.chip && (\n                <code className=\"bg-background-secondary-default min-w-0 flex-1 truncate rounded-sm px-1.5 py-0.5 text-xs\">\n                  {step.chip}\n                </code>\n              )}\n              {!step.chip && <span className=\"flex-1\" />}\n              {step.additions !== undefined && (\n                <span className=\"font-mono text-xs\">\n                  <span className=\"text-green-700 dark:text-green-400\">\n                    +{step.additions}\n                  </span>{\" \"}\n                  <span className=\"text-red-700 dark:text-red-400\">\n                    -{step.deletions ?? 0}\n                  </span>\n                </span>\n              )}\n              <ChevronDown className={cx(\"size-4\", open && \"rotate-180\")} />\n            </button>\n            <AnimatePresence initial={false}>\n              {open && step.detail && (\n                <motion.div\n                  initial={reduceMotion ? false : { height: 0, opacity: 0 }}\n                  animate={{ height: \"auto\", opacity: 1 }}\n                  exit={\n                    reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }\n                  }\n                  className=\"overflow-hidden\"\n                >\n                  <pre className=\"bg-background-secondary-default overflow-auto p-3 text-xs\">\n                    {step.detail}\n                  </pre>\n                </motion.div>\n              )}\n            </AnimatePresence>\n          </motion.div>\n        )\n      })}\n      {diffs.length > 0 && (\n        <div className=\"flex flex-wrap gap-2 p-3\">\n          {diffs.map((diff) => (\n            <motion.div\n              layout={!reduceMotion}\n              key={diff.file}\n              className=\"border-separator-border rounded-lg border px-2 py-1 text-xs\"\n            >\n              <button\n                type=\"button\"\n                aria-expanded={openDiff === diff.file}\n                onClick={() => {\n                  const next = openDiff === diff.file ? undefined : diff.file\n                  setOpenDiff(next)\n                  onDiffToggle?.(diff.file, next === diff.file)\n                }}\n                className=\"font-mono\"\n              >\n                {diff.file}{\" \"}\n                <span className=\"text-green-700 dark:text-green-400\">\n                  +{diff.additions}\n                </span>{\" \"}\n                <span className=\"text-red-700 dark:text-red-400\">\n                  -{diff.deletions}\n                </span>\n              </button>\n              <AnimatePresence initial={false}>\n                {openDiff === diff.file && diff.lines?.length ? (\n                  <motion.pre\n                    initial={reduceMotion ? false : { height: 0, opacity: 0 }}\n                    animate={{ height: \"auto\", opacity: 1 }}\n                    exit={\n                      reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }\n                    }\n                    className=\"border-separator-border mt-2 max-w-sm overflow-auto border-t pt-2 leading-5\"\n                  >\n                    {diff.lines.join(\"\\n\")}\n                  </motion.pre>\n                ) : null}\n              </AnimatePresence>\n            </motion.div>\n          ))}\n        </div>\n      )}\n    </motion.div>\n  )\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "border-beam",
      "type": "registry:block",
      "title": "Border Beam",
      "description": "border beam",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/effects/border-beam.tsx",
          "target": "@components/effects/border-beam.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { forwardRef } from \"react\"\n\nimport { BorderBeam as UpstreamBorderBeam } from \"./border-beam/upstream/BorderBeam\"\nimport type { BorderBeamProps } from \"./border-beam/upstream/types\"\n\nexport const BorderBeam = forwardRef<HTMLDivElement, BorderBeamProps>(\n  function BorderBeam(\n    {\n      colorVariant = \"mono\",\n      theme = \"auto\",\n      strength = 0.6,\n      ...props\n    },\n    ref,\n  ) {\n    return (\n      <UpstreamBorderBeam\n        ref={ref}\n        colorVariant={colorVariant}\n        theme={theme}\n        strength={strength}\n        {...props}\n      />\n    )\n  },\n)\n\nexport default BorderBeam\n\nexport {\n  sizePresets,\n  sizeThemePresets,\n  themeColors,\n} from \"./border-beam/upstream/styles\"\nexport type {\n  BorderBeamColorVariant,\n  BorderBeamProps,\n  BorderBeamSize,\n  BorderBeamTheme,\n  SizeConfig,\n  ThemeColors,\n} from \"./border-beam/upstream/types\"\n"
        },
        {
          "path": "components/effects/border-beam/upstream/BorderBeam.tsx",
          "target": "@components/effects/border-beam/upstream/BorderBeam.tsx",
          "type": "registry:component",
          "content": "import {\n  forwardRef,\n  useId,\n  useEffect,\n  useState,\n  useCallback,\n  useMemo,\n  useRef,\n  type CSSProperties,\n  type ForwardedRef,\n  type AnimationEvent,\n  type MutableRefObject,\n} from 'react';\nimport type { BorderBeamProps, BorderBeamTheme } from './types';\nimport { sizePresets, sizeThemePresets, generateBeamCSS, getPulseDriverConfig } from './styles';\nimport { registerPulseInstance } from './pulseDriver';\n\nfunction useSystemTheme(): 'dark' | 'light' {\n  const [theme, setTheme] = useState<'dark' | 'light'>(() => {\n    if (typeof window === 'undefined') return 'dark';\n    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n  });\n\n  useEffect(() => {\n    if (typeof window === 'undefined') return;\n\n    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n    const handler = (e: MediaQueryListEvent) => {\n      setTheme(e.matches ? 'dark' : 'light');\n    };\n\n    mediaQuery.addEventListener('change', handler);\n    return () => mediaQuery.removeEventListener('change', handler);\n  }, []);\n\n  return theme;\n}\n\nfunction resolveTheme(theme: BorderBeamTheme, systemTheme: 'dark' | 'light'): 'dark' | 'light' {\n  return theme === 'auto' ? systemTheme : theme;\n}\n\n/**\n * BorderBeam component - Animated border beam effect for React\n *\n * @example\n * ```tsx\n * <BorderBeam>\n *   <Card>Content</Card>\n * </BorderBeam>\n * ```\n */\nexport const BorderBeam = forwardRef<HTMLDivElement, BorderBeamProps>(\n  function BorderBeam(\n    {\n      children,\n      size = 'md',\n      colorVariant = 'colorful',\n      theme = 'dark',\n      staticColors = false,\n      duration,\n      active = true,\n      borderRadius: customBorderRadius,\n      brightness: brightnessProp,\n      saturation,\n      hueRange = 30,\n      glowSize = 1,\n      strength = 1,\n      className,\n      style,\n      css: extraCss,\n      onActivate,\n      onDeactivate,\n      onAnimationEnd: consumerOnAnimationEnd,\n      ...props\n    }: BorderBeamProps,\n    ref: ForwardedRef<HTMLDivElement>\n  ) {\n    const baseId = useId();\n    const id = baseId.replace(/:/g, '-');\n    const systemTheme = useSystemTheme();\n    const internalRef = useRef<HTMLDivElement>(null);\n\n    const [isActive, setIsActive] = useState(active);\n    const [isFading, setIsFading] = useState(false);\n    const [isVisible, setIsVisible] = useState(true);\n    const [detectedRadius, setDetectedRadius] = useState<number | null>(null);\n    const [pulseGlowScale, setPulseGlowScale] = useState<{ x: number; y: number }>({ x: 1, y: 1 });\n\n    // Auto-detect child border radius when no explicit value is provided\n    useEffect(() => {\n      if (customBorderRadius != null) return;\n      const el = internalRef.current;\n      if (!el) return;\n\n      const detect = () => {\n        const child = el.firstElementChild as HTMLElement | null;\n        if (!child) return;\n        const computed = getComputedStyle(child);\n        const raw = parseFloat(computed.borderTopLeftRadius);\n        if (!isNaN(raw) && raw > 0) {\n          setDetectedRadius(raw);\n        }\n      };\n\n      detect();\n\n      // Re-detect if child layout changes (e.g. CSS loaded late)\n      const observer = new MutationObserver(detect);\n      observer.observe(el, { childList: true, subtree: false });\n      return () => observer.disconnect();\n    }, [customBorderRadius, children]);\n\n    useEffect(() => {\n      if (active && !isActive && !isFading) {\n        setIsActive(true);\n      } else if (!active && isActive && !isFading) {\n        setIsFading(true);\n      }\n    }, [active, isActive, isFading]);\n\n    // Pause the (paint-heavy) animations while the element is scrolled offscreen.\n    // This stops per-frame painting entirely for hidden instances without changing\n    // their logical active/fading state, so it never fires onActivate/onDeactivate.\n    useEffect(() => {\n      const el = internalRef.current;\n      if (!el || typeof IntersectionObserver === 'undefined') return;\n\n      const observer = new IntersectionObserver(\n        entries => {\n          for (const entry of entries) setIsVisible(entry.isIntersecting);\n        },\n        // Start animating slightly before the element scrolls into view.\n        { rootMargin: '256px' }\n      );\n\n      observer.observe(el);\n      return () => observer.disconnect();\n    }, []);\n\n    // Pulse Outside glow geometry is authored in fixed pixels for a reference\n    // element (~350x140). Measure the actual wrapped element and scale the glow\n    // per-axis so the halo grows/shrinks to fit any component it's applied to.\n    useEffect(() => {\n      if (size !== 'pulse-outside') {\n        setPulseGlowScale({ x: 1, y: 1 });\n        return;\n      }\n\n      const el = internalRef.current;\n      if (!el) return;\n\n      const REF_WIDTH = 350;\n      const REF_HEIGHT = 140;\n      // Allow the glow to both shrink (small buttons) and grow (large cards),\n      // with generous bounds to avoid degenerate geometry at the extremes.\n      const MIN_SCALE = 0.35;\n      const MAX_SCALE = 4;\n      const clamp = (value: number) => Math.max(MIN_SCALE, Math.min(MAX_SCALE, value));\n\n      const measure = () => {\n        const child = el.firstElementChild as HTMLElement | null;\n        if (!child) return;\n        const rect = child.getBoundingClientRect();\n        if (!rect.width || !rect.height) return;\n        const x = +clamp(rect.width / REF_WIDTH).toFixed(3);\n        const y = +clamp(rect.height / REF_HEIGHT).toFixed(3);\n        setPulseGlowScale(prev => (prev.x === x && prev.y === y ? prev : { x, y }));\n      };\n\n      measure();\n      if (typeof ResizeObserver === 'undefined') return;\n\n      const child = el.firstElementChild as HTMLElement | null;\n      if (!child) return;\n\n      const resizeObserver = new ResizeObserver(measure);\n      resizeObserver.observe(child);\n      return () => resizeObserver.disconnect();\n    }, [size, children]);\n\n    const handleAnimationEnd = useCallback(\n      (e: AnimationEvent<HTMLDivElement>) => {\n        const animationName = e.animationName;\n\n        if (animationName.includes('fade-out')) {\n          setIsActive(false);\n          setIsFading(false);\n          onDeactivate?.();\n        } else if (animationName.includes('fade-in')) {\n          onActivate?.();\n        }\n\n        consumerOnAnimationEnd?.(e);\n      },\n      [onActivate, onDeactivate, consumerOnAnimationEnd]\n    );\n\n    const resolvedTheme = resolveTheme(theme, systemTheme);\n    const themeConfig = sizeThemePresets[size][resolvedTheme];\n    const sizeConfig = sizePresets[size];\n\n    const isPulse = size === 'pulse-inner' || size === 'pulse-outside';\n\n    const finalBorderRadius = customBorderRadius ?? detectedRadius ?? sizeConfig.borderRadius;\n    const finalDuration = duration ?? (size === 'line' ? 3.1 : isPulse ? 2.3 : 1.96);\n    const finalSaturation = saturation ?? themeConfig.saturation;\n    const finalBrightness = brightnessProp ?? themeConfig.brightness ?? 1.3;\n    const finalHueRange = size === 'line' ? Math.min(hueRange, 13) : hueRange;\n    const finalStaticColors = colorVariant === 'mono' ? true : staticColors;\n\n    const cssStyles = useMemo(\n      () =>\n        generateBeamCSS({\n          id,\n          borderRadius: finalBorderRadius,\n          borderWidth: sizeConfig.borderWidth,\n          duration: finalDuration,\n          strokeOpacity: themeConfig.strokeOpacity,\n          innerOpacity: themeConfig.innerOpacity,\n          bloomOpacity: themeConfig.bloomOpacity,\n          innerShadow: themeConfig.innerShadow,\n          size,\n          colorVariant,\n          staticColors: finalStaticColors,\n          brightness: finalBrightness,\n          saturation: finalSaturation,\n          hueRange: finalHueRange,\n          theme: resolvedTheme,\n          hairlineOpacity: themeConfig.hairlineOpacity,\n          glowSize,\n        }),\n      [\n        id,\n        finalBorderRadius,\n        sizeConfig.borderWidth,\n        finalDuration,\n        themeConfig.strokeOpacity,\n        themeConfig.innerOpacity,\n        themeConfig.bloomOpacity,\n        themeConfig.innerShadow,\n        themeConfig.hairlineOpacity,\n        size,\n        colorVariant,\n        finalStaticColors,\n        finalBrightness,\n        finalSaturation,\n        finalHueRange,\n        glowSize,\n        resolvedTheme,\n      ]\n    );\n\n    // Runtime config for the JS breathing driver (null for non-pulse sizes).\n    const driverConfig = useMemo(\n      () =>\n        isPulse\n          ? getPulseDriverConfig(size, resolvedTheme, finalDuration, finalHueRange, finalStaticColors, id)\n          : null,\n      [isPulse, size, resolvedTheme, finalDuration, finalHueRange, finalStaticColors, id]\n    );\n\n    // Drive the Pulse breathing from the shared, fps-capped rAF loop while the\n    // instance is on, onscreen, and the user hasn't requested reduced motion.\n    useEffect(() => {\n      if (!driverConfig) return;\n      if (!(isActive || isFading) || !isVisible) return;\n\n      const el = internalRef.current;\n      if (!el) return;\n\n      if (\n        typeof window !== 'undefined' &&\n        window.matchMedia?.('(prefers-reduced-motion: reduce)').matches\n      ) {\n        return;\n      }\n\n      return registerPulseInstance(el, driverConfig);\n    }, [driverConfig, isActive, isFading, isVisible]);\n\n    const setRefs = useCallback(\n      (node: HTMLDivElement | null) => {\n        (internalRef as MutableRefObject<HTMLDivElement | null>).current = node;\n        if (typeof ref === 'function') {\n          ref(node);\n        } else if (ref) {\n          (ref as MutableRefObject<HTMLDivElement | null>).current = node;\n        }\n      },\n      [ref]\n    );\n\n    const mergedStyle = {\n      ...(style ?? {}),\n      '--beam-strength': Math.max(0, Math.min(1, strength)),\n      ...(size === 'pulse-outside'\n        ? { '--pulse-glow-sx': pulseGlowScale.x, '--pulse-glow-sy': pulseGlowScale.y }\n        : {}),\n    } as CSSProperties;\n\n    return (\n      <>\n        <style>{extraCss ? `${cssStyles}\\n${extraCss.split('{id}').join(id)}` : cssStyles}</style>\n        <div\n          {...props}\n          ref={setRefs}\n          data-beam={id}\n          data-active={isActive && !isFading ? '' : undefined}\n          data-fading={isFading ? '' : undefined}\n          data-paused={isActive && !isFading && !isVisible ? '' : undefined}\n          className={className}\n          style={mergedStyle}\n          onAnimationEnd={handleAnimationEnd}\n        >\n          {children}\n          <div data-beam-bloom />\n        </div>\n      </>\n    );\n  }\n);\n\nexport default BorderBeam;\n"
        },
        {
          "path": "components/effects/border-beam/upstream/types.ts",
          "target": "@components/effects/border-beam/upstream/types.ts",
          "type": "registry:component",
          "content": "import type { CSSProperties, ReactNode, HTMLAttributes } from 'react';\n\n/**\n * Size/type preset for the border beam effect\n *\n * Rotate family (traveling/spinning beam):\n * - 'sm': Small button-sized with compact glow\n * - 'md': Medium card-sized with full border glow\n * - 'line': Bottom-only traveling glow with breathe and spike animations\n *\n * Pulse family (breathing glow, no rotation):\n * - 'pulse-outside': Glow blooms OUTWARD beyond the element (uncropped halo)\n * - 'pulse-inner': Glow breathes contained within the element's border\n */\nexport type BorderBeamSize = 'sm' | 'md' | 'line' | 'pulse-outside' | 'pulse-inner';\n\n/**\n * Theme mode for adapting beam colors to background\n */\nexport type BorderBeamTheme = 'dark' | 'light' | 'auto';\n\n/**\n * Color variant for the beam effect\n * - 'colorful': Full rainbow spectrum (default)\n * - 'mono': Monochromatic grayscale\n * - 'ocean': Blue and purple tones\n * - 'sunset': Warm orange, yellow, and red tones\n * - 'forest': Green and teal tones\n * - 'candy': Pink and magenta tones\n * - 'ice': Cyan and pale blue tones\n * - 'gold': Amber and yellow tones\n */\nexport type BorderBeamColorVariant =\n  | 'colorful'\n  | 'mono'\n  | 'ocean'\n  | 'sunset'\n  | 'forest'\n  | 'candy'\n  | 'ice'\n  | 'gold';\n\n/**\n * Configuration for a size preset\n */\nexport interface SizeConfig {\n  borderRadius: number;\n  borderWidth: number;\n  width?: number;\n  height?: number;\n}\n\n/**\n * Theme color configuration\n */\nexport interface ThemeColors {\n  strokeOpacity: number;\n  innerOpacity: number;\n  bloomOpacity: number;\n  innerShadow: string;\n  saturation: number;\n  /** Optional per-type default brightness (used by pulse types). Falls back to 1.3. */\n  brightness?: number;\n  /**\n   * Optional opacity of the 1px hairline border that frames the element.\n   * Used by 'pulse-outside' so the colored stroke rides a subtle outline,\n   * matching the v5 prototype. Falls back to 0 (no hairline).\n   */\n  hairlineOpacity?: number;\n}\n\n/**\n * Props for the BorderBeam component\n */\nexport interface BorderBeamProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n  /** Content to wrap with the border beam effect */\n  children: ReactNode;\n\n  /**\n   * Size/type preset\n   * Rotate family: 'sm' (compact), 'md' (full border, default), 'line' (bottom traveling).\n   * Pulse family: 'pulse-outside' (outward bloom), 'pulse-inner' (contained breathe).\n   * @default 'md'\n   */\n  size?: BorderBeamSize;\n\n  /**\n   * Color variant for the beam effect\n   * - 'colorful': Full rainbow spectrum (default)\n   * - 'mono': Monochromatic grayscale\n   * - 'ocean': Blue and purple tones\n   * - 'sunset': Warm orange, yellow, and red tones\n   * @default 'colorful'\n   */\n  colorVariant?: BorderBeamColorVariant;\n\n  /**\n   * Theme mode - adapts beam/glow colors for dark or light backgrounds\n   * 'auto' detects system preference via prefers-color-scheme\n   * @default 'dark'\n   */\n  theme?: BorderBeamTheme;\n\n  /**\n   * Disable the hue-shift animation for static colors (e.g., monochrome)\n   * @default false\n   */\n  staticColors?: boolean;\n\n  /**\n   * Rotation/travel duration in seconds\n   * @default 1.96 for border, 2.4 for line\n   */\n  duration?: number;\n\n  /**\n   * Whether the animation is active\n   * @default true\n   */\n  active?: boolean;\n\n  /**\n   * Custom border radius in pixels. When omitted, the component\n   * auto-detects the border-radius of the first child element.\n   * Falls back to the size preset default if detection fails.\n   */\n  borderRadius?: number;\n\n  /**\n   * Brightness multiplier for the glow effect.\n   * Falls back to the type's preset default (1.3 for most types).\n   * @default 1.3\n   */\n  brightness?: number;\n\n  /**\n   * Saturation multiplier for the glow effect\n   * @default 1.2 for dark, varies for light\n   */\n  saturation?: number;\n\n  /**\n   * Multiplies the blur radius of every glow layer, so the halo reads\n   * tighter (< 1) or wider and softer (> 1). Each layer keeps its own\n   * tuned proportion — the core stays tighter than the bloom — because\n   * this scales the presets rather than replacing them.\n   * @default 1\n   */\n  glowSize?: number;\n\n  /**\n   * Hue rotation range in degrees for the hue-shift animation\n   * @default 30\n   */\n  hueRange?: number;\n\n  /**\n   * Overall strength/opacity of the effect (0-1).\n   * Only affects the beam, glow, and bloom layers -- not the children.\n   * @default 1\n   */\n  strength?: number;\n\n  /**\n   * Additional class name for the container\n   */\n  className?: string;\n\n  /**\n   * Additional inline styles for the container\n   */\n  style?: CSSProperties;\n\n  /**\n   * Extra CSS appended after the beam's own generated stylesheet, so it can\n   * override or add layers and keyframes. Write `{id}` wherever the\n   * instance id belongs — the root is `[data-beam=\"{id}\"]`, its layers are\n   * the `::before` / `::after` pseudo-elements and `[data-beam-bloom]`, and\n   * keyframes are named `*-{id}` — and it is substituted per instance.\n   */\n  css?: string;\n\n  /**\n   * Callback when fade-in animation completes\n   */\n  onActivate?: () => void;\n\n  /**\n   * Callback when fade-out animation completes\n   */\n  onDeactivate?: () => void;\n}\n"
        },
        {
          "path": "components/effects/border-beam/upstream/styles.ts",
          "target": "@components/effects/border-beam/upstream/styles.ts",
          "type": "registry:component",
          "content": "import type { SizeConfig, ThemeColors, BorderBeamColorVariant, BorderBeamSize } from './types';\n\n/**\n * Size presets for border radius and dimensions\n */\nexport const sizePresets: Record<BorderBeamSize, SizeConfig> = {\n  sm: {\n    borderRadius: 32,\n    borderWidth: 1,\n    width: 70,\n    height: 36,\n  },\n  md: {\n    borderRadius: 16,\n    borderWidth: 1,\n  },\n  line: {\n    borderRadius: 16,\n    borderWidth: 1,\n  },\n  'pulse-outside': {\n    borderRadius: 16,\n    borderWidth: 1,\n  },\n  'pulse-inner': {\n    borderRadius: 16,\n    borderWidth: 1,\n  },\n};\n\n/**\n * Per-size theme presets matching the tuned v5 control panel defaults\n */\nexport const sizeThemePresets: Record<BorderBeamSize, Record<'dark' | 'light', ThemeColors>> = {\n  sm: {\n    dark: {\n      strokeOpacity: 0.46,\n      innerOpacity: 0.24,\n      bloomOpacity: 0.38,\n      innerShadow: 'rgba(255, 255, 255, 0.3)',\n      saturation: 1.2,\n    },\n    light: {\n      strokeOpacity: 0.12,\n      innerOpacity: 0.3,\n      bloomOpacity: 0.16,\n      innerShadow: 'rgba(0, 0, 0, 0.14)',\n      saturation: 1.8,\n    },\n  },\n  md: {\n    dark: {\n      strokeOpacity: 0.26,\n      innerOpacity: 0.42,\n      bloomOpacity: 0.24,\n      innerShadow: 'rgba(255, 255, 255, 0.27)',\n      saturation: 1.2,\n    },\n    light: {\n      strokeOpacity: 0.12,\n      innerOpacity: 0.26,\n      bloomOpacity: 0.34,\n      innerShadow: 'rgba(0, 0, 0, 0.14)',\n      saturation: 1.5,\n    },\n  },\n  line: {\n    dark: {\n      strokeOpacity: 1.14,\n      innerOpacity: 0.7,\n      bloomOpacity: 0.8,\n      innerShadow: 'rgba(255, 255, 255, 0.1)',\n      saturation: 1.2,\n    },\n    light: {\n      strokeOpacity: 0.16,\n      innerOpacity: 0.32,\n      bloomOpacity: 0.3,\n      innerShadow: 'rgba(0, 0, 0, 0.14)',\n      saturation: 1.95,\n    },\n  },\n  // Pulse Outside — outward-blooming breathe (ported from v5 \"Breathe Outside Uncropped\" / c6)\n  'pulse-outside': {\n    dark: {\n      strokeOpacity: 0.94,\n      innerOpacity: 0.34,\n      bloomOpacity: 0.3,\n      innerShadow: 'transparent',\n      saturation: 1.2,\n      brightness: 1.9,\n      // v5 Card 5 frames the card with a single 1px hairline (its box-shadow at\n      // 0.3). Wrapped components here already supply their own ~equivalent 1px\n      // border, so the beam must NOT add a second hairline on top or the edge\n      // reads brighter than v5. Kept at 0 to match v5's single-hairline look.\n      hairlineOpacity: 0,\n    },\n    light: {\n      strokeOpacity: 1.96,\n      innerOpacity: 1.04,\n      bloomOpacity: 0.42,\n      innerShadow: 'transparent',\n      saturation: 0.6,\n      brightness: 1.7,\n      hairlineOpacity: 0,\n    },\n  },\n  // Pulse Inner — contained breathe (ported from v5 \"Breathe\" / c4)\n  'pulse-inner': {\n    dark: {\n      strokeOpacity: 1.54,\n      innerOpacity: 0.44,\n      bloomOpacity: 0.66,\n      innerShadow: 'transparent',\n      saturation: 1.2,\n      brightness: 0.75,\n    },\n    light: {\n      strokeOpacity: 0.32,\n      innerOpacity: 0.4,\n      bloomOpacity: 0.8,\n      innerShadow: 'transparent',\n      saturation: 0.75,\n      brightness: 1.3,\n    },\n  },\n};\n\n/**\n * @deprecated Use `sizeThemePresets` for per-size theme values.\n * Retained for backward compatibility — maps to `md` size presets.\n */\nexport const themeColors: Record<'dark' | 'light', ThemeColors> = {\n  dark: { ...sizeThemePresets.md.dark },\n  light: { ...sizeThemePresets.md.light },\n};\n\n/**\n * Color palettes for each color variant\n */\nexport const colorPalettes = {\n  colorful: {\n    border: [\n      { color: 'rgb(255, 50, 100)', pos: '33% -7.4%', size: '70px 40px' },\n      { color: 'rgb(40, 140, 255)', pos: '12% -5%', size: '60px 35px' },\n      { color: 'rgb(50, 200, 80)', pos: '2.1% 68.3%', size: '40px 70px' },\n      { color: 'rgb(30, 185, 170)', pos: '2.1% 68.3%', size: '20px 35px' },\n      { color: 'rgb(100, 70, 255)', pos: '74.4% 100%', size: '180px 32px' },\n      { color: 'rgb(40, 140, 255)', pos: '55% 100%', size: '85px 26px' },\n      { color: 'rgb(255, 120, 40)', pos: '93.9% 0%', size: '74px 32px' },\n      { color: 'rgb(240, 50, 180)', pos: '100% 27.1%', size: '26px 42px' },\n      { color: 'rgb(180, 40, 240)', pos: '100% 27.1%', size: '52px 48px' },\n    ],\n    spike: { primary: 'rgb(255, 60, 80)', secondary: 'rgba(40, 190, 180, 0.98)' },\n    spikeLt: { primary: 'rgb(200, 30, 60)', secondary: 'rgb(20, 150, 140)' },\n  },\n  mono: {\n    border: [\n      { color: 'rgb(180, 180, 180)', pos: '33% -7.4%', size: '70px 40px' },\n      { color: 'rgb(140, 140, 140)', pos: '12% -5%', size: '60px 35px' },\n      { color: 'rgb(160, 160, 160)', pos: '2.1% 68.3%', size: '40px 70px' },\n      { color: 'rgb(130, 130, 130)', pos: '2.1% 68.3%', size: '20px 35px' },\n      { color: 'rgb(170, 170, 170)', pos: '74.4% 100%', size: '180px 32px' },\n      { color: 'rgb(150, 150, 150)', pos: '55% 100%', size: '85px 26px' },\n      { color: 'rgb(190, 190, 190)', pos: '93.9% 0%', size: '74px 32px' },\n      { color: 'rgb(145, 145, 145)', pos: '100% 27.1%', size: '26px 42px' },\n      { color: 'rgb(165, 165, 165)', pos: '100% 27.1%', size: '52px 48px' },\n    ],\n    spike: { primary: 'rgb(200, 200, 200)', secondary: 'rgb(170, 170, 170)' },\n    spikeLt: { primary: 'rgb(80, 80, 80)', secondary: 'rgb(120, 120, 120)' },\n  },\n  ocean: {\n    border: [\n      { color: 'rgb(100, 80, 220)', pos: '33% -7.4%', size: '70px 40px' },\n      { color: 'rgb(60, 120, 255)', pos: '12% -5%', size: '60px 35px' },\n      { color: 'rgb(80, 100, 200)', pos: '2.1% 68.3%', size: '40px 70px' },\n      { color: 'rgb(50, 140, 220)', pos: '2.1% 68.3%', size: '20px 35px' },\n      { color: 'rgb(120, 80, 255)', pos: '74.4% 100%', size: '180px 32px' },\n      { color: 'rgb(70, 130, 255)', pos: '55% 100%', size: '85px 26px' },\n      { color: 'rgb(140, 100, 240)', pos: '93.9% 0%', size: '74px 32px' },\n      { color: 'rgb(90, 110, 230)', pos: '100% 27.1%', size: '26px 42px' },\n      { color: 'rgb(130, 70, 255)', pos: '100% 27.1%', size: '52px 48px' },\n    ],\n    spike: { primary: 'rgb(100, 120, 255)', secondary: 'rgba(130, 100, 220, 0.98)' },\n    spikeLt: { primary: 'rgb(60, 60, 180)', secondary: 'rgb(80, 100, 200)' },\n  },\n  sunset: {\n    border: [\n      { color: 'rgb(255, 80, 50)', pos: '33% -7.4%', size: '70px 40px' },\n      { color: 'rgb(255, 160, 40)', pos: '12% -5%', size: '60px 35px' },\n      { color: 'rgb(255, 120, 60)', pos: '2.1% 68.3%', size: '40px 70px' },\n      { color: 'rgb(255, 200, 50)', pos: '2.1% 68.3%', size: '20px 35px' },\n      { color: 'rgb(255, 100, 80)', pos: '74.4% 100%', size: '180px 32px' },\n      { color: 'rgb(255, 180, 60)', pos: '55% 100%', size: '85px 26px' },\n      { color: 'rgb(255, 60, 60)', pos: '93.9% 0%', size: '74px 32px' },\n      { color: 'rgb(255, 140, 50)', pos: '100% 27.1%', size: '26px 42px' },\n      { color: 'rgb(255, 90, 70)', pos: '100% 27.1%', size: '52px 48px' },\n    ],\n    spike: { primary: 'rgb(255, 140, 80)', secondary: 'rgba(255, 100, 60, 0.98)' },\n    spikeLt: { primary: 'rgb(200, 80, 40)', secondary: 'rgb(220, 120, 30)' },\n  },\n  forest: {\n    border: [\n      { color: 'rgb(46, 160, 90)', pos: '33% -7.4%', size: '70px 40px' },\n      { color: 'rgb(30, 190, 120)', pos: '12% -5%', size: '60px 35px' },\n      { color: 'rgb(70, 180, 70)', pos: '2.1% 68.3%', size: '40px 70px' },\n      { color: 'rgb(20, 150, 130)', pos: '2.1% 68.3%', size: '20px 35px' },\n      { color: 'rgb(90, 200, 80)', pos: '74.4% 100%', size: '180px 32px' },\n      { color: 'rgb(40, 170, 110)', pos: '55% 100%', size: '85px 26px' },\n      { color: 'rgb(120, 210, 70)', pos: '93.9% 0%', size: '74px 32px' },\n      { color: 'rgb(35, 145, 100)', pos: '100% 27.1%', size: '26px 42px' },\n      { color: 'rgb(60, 195, 140)', pos: '100% 27.1%', size: '52px 48px' },\n    ],\n    spike: { primary: 'rgb(46, 160, 90)', secondary: 'rgba(30, 190, 120,, 0.98)' },\n    spikeLt: { primary: 'rgb(33, 115, 65)', secondary: 'rgb(22, 137, 86)' },\n  },\n  candy: {\n    border: [\n      { color: 'rgb(240, 70, 170)', pos: '33% -7.4%', size: '70px 40px' },\n      { color: 'rgb(255, 90, 140)', pos: '12% -5%', size: '60px 35px' },\n      { color: 'rgb(215, 60, 200)', pos: '2.1% 68.3%', size: '40px 70px' },\n      { color: 'rgb(255, 110, 180)', pos: '2.1% 68.3%', size: '20px 35px' },\n      { color: 'rgb(200, 80, 240)', pos: '74.4% 100%', size: '180px 32px' },\n      { color: 'rgb(250, 60, 150)', pos: '55% 100%', size: '85px 26px' },\n      { color: 'rgb(230, 120, 220)', pos: '93.9% 0%', size: '74px 32px' },\n      { color: 'rgb(245, 85, 165)', pos: '100% 27.1%', size: '26px 42px' },\n      { color: 'rgb(210, 70, 230)', pos: '100% 27.1%', size: '52px 48px' },\n    ],\n    spike: { primary: 'rgb(240, 70, 170)', secondary: 'rgba(255, 90, 140,, 0.98)' },\n    spikeLt: { primary: 'rgb(173, 50, 122)', secondary: 'rgb(184, 65, 101)' },\n  },\n  ice: {\n    border: [\n      { color: 'rgb(90, 200, 240)', pos: '33% -7.4%', size: '70px 40px' },\n      { color: 'rgb(60, 175, 230)', pos: '12% -5%', size: '60px 35px' },\n      { color: 'rgb(130, 220, 250)', pos: '2.1% 68.3%', size: '40px 70px' },\n      { color: 'rgb(70, 190, 215)', pos: '2.1% 68.3%', size: '20px 35px' },\n      { color: 'rgb(110, 210, 255)', pos: '74.4% 100%', size: '180px 32px' },\n      { color: 'rgb(50, 165, 220)', pos: '55% 100%', size: '85px 26px' },\n      { color: 'rgb(150, 230, 250)', pos: '93.9% 0%', size: '74px 32px' },\n      { color: 'rgb(85, 195, 235)', pos: '100% 27.1%', size: '26px 42px' },\n      { color: 'rgb(65, 180, 245)', pos: '100% 27.1%', size: '52px 48px' },\n    ],\n    spike: { primary: 'rgb(90, 200, 240)', secondary: 'rgba(60, 175, 230,, 0.98)' },\n    spikeLt: { primary: 'rgb(65, 144, 173)', secondary: 'rgb(43, 126, 166)' },\n  },\n  gold: {\n    border: [\n      { color: 'rgb(240, 190, 60)', pos: '33% -7.4%', size: '70px 40px' },\n      { color: 'rgb(255, 210, 90)', pos: '12% -5%', size: '60px 35px' },\n      { color: 'rgb(225, 165, 40)', pos: '2.1% 68.3%', size: '40px 70px' },\n      { color: 'rgb(250, 200, 70)', pos: '2.1% 68.3%', size: '20px 35px' },\n      { color: 'rgb(255, 225, 120)', pos: '74.4% 100%', size: '180px 32px' },\n      { color: 'rgb(230, 175, 50)', pos: '55% 100%', size: '85px 26px' },\n      { color: 'rgb(245, 205, 85)', pos: '93.9% 0%', size: '74px 32px' },\n      { color: 'rgb(215, 155, 35)', pos: '100% 27.1%', size: '26px 42px' },\n      { color: 'rgb(255, 215, 100)', pos: '100% 27.1%', size: '52px 48px' },\n    ],\n    spike: { primary: 'rgb(240, 190, 60)', secondary: 'rgba(255, 210, 90,, 0.98)' },\n    spikeLt: { primary: 'rgb(173, 137, 43)', secondary: 'rgb(184, 151, 65)' },\n  },\n};\n\n/**\n * Small size color palettes (compact gradients for button-sized elements)\n */\nexport const smallColorPalettes = {\n  colorful: {\n    border: [\n      { color: 'rgb(50, 200, 80)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgb(30, 185, 170)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgb(255, 120, 40)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgb(100, 70, 255)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgb(240, 50, 180)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgb(180, 40, 240)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgb(40, 140, 255)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgb(255, 50, 100)', pos: '100% 27%', size: '11px 12px' },\n    ],\n    inner: [\n      { color: 'rgba(50, 200, 80, 0.5)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgba(30, 185, 170, 0.45)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgba(255, 120, 40, 0.35)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgba(100, 70, 255, 0.35)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgba(240, 50, 180, 0.3)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgba(180, 40, 240, 0.4)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgba(40, 140, 255, 0.3)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgba(255, 50, 100, 0.3)', pos: '100% 27%', size: '11px 12px' },\n    ],\n  },\n  mono: {\n    border: [\n      { color: 'rgb(160, 160, 160)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgb(140, 140, 140)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgb(180, 180, 180)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgb(150, 150, 150)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgb(170, 170, 170)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgb(155, 155, 155)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgb(145, 145, 145)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgb(165, 165, 165)', pos: '100% 27%', size: '11px 12px' },\n    ],\n    inner: [\n      { color: 'rgba(160, 160, 160, 0.25)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgba(140, 140, 140, 0.22)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgba(180, 180, 180, 0.17)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgba(150, 150, 150, 0.17)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgba(170, 170, 170, 0.15)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgba(155, 155, 155, 0.20)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgba(145, 145, 145, 0.15)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgba(165, 165, 165, 0.15)', pos: '100% 27%', size: '11px 12px' },\n    ],\n  },\n  ocean: {\n    border: [\n      { color: 'rgb(60, 140, 200)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgb(50, 120, 180)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgb(100, 80, 220)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgb(80, 100, 255)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgb(120, 70, 240)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgb(90, 80, 220)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgb(70, 110, 255)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgb(110, 90, 230)', pos: '100% 27%', size: '11px 12px' },\n    ],\n    inner: [\n      { color: 'rgba(60, 140, 200, 0.5)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgba(50, 120, 180, 0.45)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgba(100, 80, 220, 0.35)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgba(80, 100, 255, 0.35)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgba(120, 70, 240, 0.3)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgba(90, 80, 220, 0.4)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgba(70, 110, 255, 0.3)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgba(110, 90, 230, 0.3)', pos: '100% 27%', size: '11px 12px' },\n    ],\n  },\n  sunset: {\n    border: [\n      { color: 'rgb(255, 180, 50)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgb(255, 150, 40)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgb(255, 80, 60)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgb(255, 100, 80)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgb(255, 60, 80)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgb(255, 120, 60)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgb(255, 200, 50)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgb(255, 90, 70)', pos: '100% 27%', size: '11px 12px' },\n    ],\n    inner: [\n      { color: 'rgba(255, 180, 50, 0.5)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgba(255, 150, 40, 0.45)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgba(255, 80, 60, 0.35)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgba(255, 100, 80, 0.35)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgba(255, 60, 80, 0.3)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgba(255, 120, 60, 0.4)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgba(255, 200, 50, 0.3)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgba(255, 90, 70, 0.3)', pos: '100% 27%', size: '11px 12px' },\n    ],\n  },\n  forest: {\n    border: [\n      { color: 'rgb(46, 160, 90)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgb(30, 190, 120)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgb(70, 180, 70)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgb(20, 150, 130)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgb(90, 200, 80)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgb(40, 170, 110)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgb(120, 210, 70)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgb(35, 145, 100)', pos: '100% 27%', size: '11px 12px' },\n    ],\n    inner: [\n      { color: 'rgba(60, 195, 140,, 0.5)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgba(46, 160, 90,, 0.45)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgba(30, 190, 120,, 0.35)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgba(70, 180, 70,, 0.35)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgba(20, 150, 130,, 0.3)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgba(90, 200, 80,, 0.4)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgba(40, 170, 110,, 0.3)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgba(120, 210, 70,, 0.3)', pos: '100% 27%', size: '11px 12px' },\n    ],\n  },\n  candy: {\n    border: [\n      { color: 'rgb(240, 70, 170)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgb(255, 90, 140)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgb(215, 60, 200)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgb(255, 110, 180)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgb(200, 80, 240)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgb(250, 60, 150)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgb(230, 120, 220)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgb(245, 85, 165)', pos: '100% 27%', size: '11px 12px' },\n    ],\n    inner: [\n      { color: 'rgba(210, 70, 230,, 0.5)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgba(240, 70, 170,, 0.45)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgba(255, 90, 140,, 0.35)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgba(215, 60, 200,, 0.35)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgba(255, 110, 180,, 0.3)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgba(200, 80, 240,, 0.4)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgba(250, 60, 150,, 0.3)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgba(230, 120, 220,, 0.3)', pos: '100% 27%', size: '11px 12px' },\n    ],\n  },\n  ice: {\n    border: [\n      { color: 'rgb(90, 200, 240)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgb(60, 175, 230)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgb(130, 220, 250)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgb(70, 190, 215)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgb(110, 210, 255)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgb(50, 165, 220)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgb(150, 230, 250)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgb(85, 195, 235)', pos: '100% 27%', size: '11px 12px' },\n    ],\n    inner: [\n      { color: 'rgba(65, 180, 245,, 0.5)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgba(90, 200, 240,, 0.45)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgba(60, 175, 230,, 0.35)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgba(130, 220, 250,, 0.35)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgba(70, 190, 215,, 0.3)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgba(110, 210, 255,, 0.4)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgba(50, 165, 220,, 0.3)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgba(150, 230, 250,, 0.3)', pos: '100% 27%', size: '11px 12px' },\n    ],\n  },\n  gold: {\n    border: [\n      { color: 'rgb(240, 190, 60)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgb(255, 210, 90)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgb(225, 165, 40)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgb(250, 200, 70)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgb(255, 225, 120)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgb(230, 175, 50)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgb(245, 205, 85)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgb(215, 155, 35)', pos: '100% 27%', size: '11px 12px' },\n    ],\n    inner: [\n      { color: 'rgba(255, 215, 100,, 0.5)', pos: '2% 68%', size: '9px 18px' },\n      { color: 'rgba(240, 190, 60,, 0.45)', pos: '2% 68%', size: '4px 8px' },\n      { color: 'rgba(255, 210, 90,, 0.35)', pos: '72% -3%', size: '59px 9px' },\n      { color: 'rgba(225, 165, 40,, 0.35)', pos: '74% 100%', size: '42px 7px' },\n      { color: 'rgba(250, 200, 70,, 0.3)', pos: '100% 27%', size: '10px 17px' },\n      { color: 'rgba(255, 225, 120,, 0.4)', pos: '100% 27%', size: '10px 18px' },\n      { color: 'rgba(230, 175, 50,, 0.3)', pos: '100% 27%', size: '5px 10px' },\n      { color: 'rgba(245, 205, 85,, 0.3)', pos: '100% 27%', size: '11px 12px' },\n    ],\n  },\n};\n\nfunction getSmallColorGradients(colorVariant: BorderBeamColorVariant): string {\n  const palette = smallColorPalettes[colorVariant];\n  return palette.border\n    .map(c => `radial-gradient(ellipse ${c.size} at ${c.pos}, ${c.color}, transparent)`)\n    .join(',\\n    ');\n}\n\nfunction getSmallInnerGradients(colorVariant: BorderBeamColorVariant): string {\n  const palette = smallColorPalettes[colorVariant];\n  return palette.inner\n    .map(c => `radial-gradient(ellipse ${c.size} at ${c.pos}, ${c.color}, transparent)`)\n    .join(',\\n    ');\n}\n\nfunction getColorGradients(colorVariant: BorderBeamColorVariant): string {\n  const palette = colorPalettes[colorVariant];\n  return palette.border\n    .map(c => `radial-gradient(ellipse ${c.size} at ${c.pos}, ${c.color}, transparent)`)\n    .join(',\\n    ');\n}\n\nfunction getInnerGradients(colorVariant: BorderBeamColorVariant): string {\n  const palette = colorPalettes[colorVariant];\n  // Mono variant gets 50% lower opacity\n  const baseOpacity = colorVariant === 'mono' ? 0.225 : 0.45;\n  return palette.border\n    .map(c => {\n      const rgba = c.color.replace('rgb(', 'rgba(').replace(')', `, ${baseOpacity})`);\n      const smallerSize = c.size.split(' ').map(s => {\n        const val = parseInt(s);\n        return `${Math.round(val * 0.9)}px`;\n      }).join(' ');\n      return `radial-gradient(ellipse ${smallerSize} at ${c.pos}, ${rgba}, transparent)`;\n    })\n    .join(',\\n    ');\n}\n\nfunction getSpikeColors(colorVariant: BorderBeamColorVariant, isDark: boolean) {\n  const palette = colorPalettes[colorVariant];\n  return isDark ? palette.spike : palette.spikeLt;\n}\n\nexport const lineColorPalettes = {\n  colorful: {\n    dark: [\n      { color: 'rgb(255, 50, 100)', sizeW: 36, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(40, 180, 220)', sizeW: 30, sizeH: 32, offsetX: 39, offsetY: 0 },\n      { color: 'rgb(50, 200, 80)', sizeW: 33, sizeH: 28, offsetX: -36, offsetY: 2 },\n      { color: 'rgb(180, 40, 240)', sizeW: 29, sizeH: 34, offsetX: -54, offsetY: 0 },\n      { color: 'rgb(255, 160, 30)', sizeW: 27, sizeH: 30, offsetX: 51, offsetY: -1 },\n      { color: 'rgb(100, 70, 255)', sizeW: 36, sizeH: 24, offsetX: 21, offsetY: 1 },\n      { color: 'rgb(40, 140, 255)', sizeW: 30, sizeH: 22, offsetX: -21, offsetY: 0 },\n      { color: 'rgb(240, 50, 180)', sizeW: 25, sizeH: 28, offsetX: 66, offsetY: 1 },\n      { color: 'rgb(30, 185, 170)', sizeW: 23, sizeH: 30, offsetX: -66, offsetY: -1 },\n    ],\n    light: [\n      { color: 'rgb(255, 50, 100)', sizeW: 45, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(40, 140, 255)', sizeW: 35, sizeH: 32, offsetX: 65, offsetY: 0 },\n      { color: 'rgb(50, 200, 80)', sizeW: 40, sizeH: 28, offsetX: -60, offsetY: 2 },\n      { color: 'rgb(180, 40, 240)', sizeW: 35, sizeH: 34, offsetX: -90, offsetY: 0 },\n      { color: 'rgb(30, 185, 170)', sizeW: 38, sizeH: 30, offsetX: 85, offsetY: -1 },\n      { color: 'rgb(100, 70, 255)', sizeW: 50, sizeH: 24, offsetX: 35, offsetY: 1 },\n      { color: 'rgb(40, 140, 255)', sizeW: 40, sizeH: 22, offsetX: -35, offsetY: 0 },\n      { color: 'rgb(255, 120, 40)', sizeW: 35, sizeH: 28, offsetX: 110, offsetY: 1 },\n      { color: 'rgb(240, 50, 180)', sizeW: 30, sizeH: 30, offsetX: -110, offsetY: -1 },\n    ],\n  },\n  mono: {\n    dark: [\n      { color: 'rgb(200, 200, 200)', sizeW: 36, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(170, 170, 170)', sizeW: 30, sizeH: 32, offsetX: 39, offsetY: 0 },\n      { color: 'rgb(155, 155, 155)', sizeW: 33, sizeH: 28, offsetX: -36, offsetY: 2 },\n      { color: 'rgb(185, 185, 185)', sizeW: 29, sizeH: 34, offsetX: -54, offsetY: 0 },\n      { color: 'rgb(165, 165, 165)', sizeW: 27, sizeH: 30, offsetX: 51, offsetY: -1 },\n      { color: 'rgb(180, 180, 180)', sizeW: 36, sizeH: 24, offsetX: 21, offsetY: 1 },\n      { color: 'rgb(160, 160, 160)', sizeW: 30, sizeH: 22, offsetX: -21, offsetY: 0 },\n      { color: 'rgb(175, 175, 175)', sizeW: 25, sizeH: 28, offsetX: 66, offsetY: 1 },\n      { color: 'rgb(190, 190, 190)', sizeW: 23, sizeH: 30, offsetX: -66, offsetY: -1 },\n    ],\n    light: [\n      { color: 'rgb(100, 100, 100)', sizeW: 45, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(80, 80, 80)', sizeW: 35, sizeH: 32, offsetX: 65, offsetY: 0 },\n      { color: 'rgb(90, 90, 90)', sizeW: 40, sizeH: 28, offsetX: -60, offsetY: 2 },\n      { color: 'rgb(70, 70, 70)', sizeW: 35, sizeH: 34, offsetX: -90, offsetY: 0 },\n      { color: 'rgb(85, 85, 85)', sizeW: 38, sizeH: 30, offsetX: 85, offsetY: -1 },\n      { color: 'rgb(95, 95, 95)', sizeW: 50, sizeH: 24, offsetX: 35, offsetY: 1 },\n      { color: 'rgb(75, 75, 75)', sizeW: 40, sizeH: 22, offsetX: -35, offsetY: 0 },\n      { color: 'rgb(105, 105, 105)', sizeW: 35, sizeH: 28, offsetX: 110, offsetY: 1 },\n      { color: 'rgb(65, 65, 65)', sizeW: 30, sizeH: 30, offsetX: -110, offsetY: -1 },\n    ],\n  },\n  ocean: {\n    dark: [\n      { color: 'rgb(100, 80, 220)', sizeW: 36, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(60, 120, 255)', sizeW: 30, sizeH: 32, offsetX: 39, offsetY: 0 },\n      { color: 'rgb(80, 100, 200)', sizeW: 33, sizeH: 28, offsetX: -36, offsetY: 2 },\n      { color: 'rgb(130, 70, 255)', sizeW: 29, sizeH: 34, offsetX: -54, offsetY: 0 },\n      { color: 'rgb(70, 130, 255)', sizeW: 27, sizeH: 30, offsetX: 51, offsetY: -1 },\n      { color: 'rgb(120, 80, 255)', sizeW: 36, sizeH: 24, offsetX: 21, offsetY: 1 },\n      { color: 'rgb(90, 110, 230)', sizeW: 30, sizeH: 22, offsetX: -21, offsetY: 0 },\n      { color: 'rgb(110, 90, 240)', sizeW: 25, sizeH: 28, offsetX: 66, offsetY: 1 },\n      { color: 'rgb(140, 100, 255)', sizeW: 23, sizeH: 30, offsetX: -66, offsetY: -1 },\n    ],\n    light: [\n      { color: 'rgb(80, 60, 200)', sizeW: 45, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(50, 100, 220)', sizeW: 35, sizeH: 32, offsetX: 65, offsetY: 0 },\n      { color: 'rgb(70, 90, 190)', sizeW: 40, sizeH: 28, offsetX: -60, offsetY: 2 },\n      { color: 'rgb(110, 60, 220)', sizeW: 35, sizeH: 34, offsetX: -90, offsetY: 0 },\n      { color: 'rgb(60, 110, 230)', sizeW: 38, sizeH: 30, offsetX: 85, offsetY: -1 },\n      { color: 'rgb(100, 70, 240)', sizeW: 50, sizeH: 24, offsetX: 35, offsetY: 1 },\n      { color: 'rgb(80, 100, 210)', sizeW: 40, sizeH: 22, offsetX: -35, offsetY: 0 },\n      { color: 'rgb(90, 80, 225)', sizeW: 35, sizeH: 28, offsetX: 110, offsetY: 1 },\n      { color: 'rgb(120, 90, 245)', sizeW: 30, sizeH: 30, offsetX: -110, offsetY: -1 },\n    ],\n  },\n  sunset: {\n    dark: [\n      { color: 'rgb(255, 100, 60)', sizeW: 36, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(255, 180, 50)', sizeW: 30, sizeH: 32, offsetX: 39, offsetY: 0 },\n      { color: 'rgb(255, 140, 70)', sizeW: 33, sizeH: 28, offsetX: -36, offsetY: 2 },\n      { color: 'rgb(255, 80, 80)', sizeW: 29, sizeH: 34, offsetX: -54, offsetY: 0 },\n      { color: 'rgb(255, 200, 60)', sizeW: 27, sizeH: 30, offsetX: 51, offsetY: -1 },\n      { color: 'rgb(255, 120, 50)', sizeW: 36, sizeH: 24, offsetX: 21, offsetY: 1 },\n      { color: 'rgb(255, 160, 80)', sizeW: 30, sizeH: 22, offsetX: -21, offsetY: 0 },\n      { color: 'rgb(255, 90, 60)', sizeW: 25, sizeH: 28, offsetX: 66, offsetY: 1 },\n      { color: 'rgb(255, 70, 70)', sizeW: 23, sizeH: 30, offsetX: -66, offsetY: -1 },\n    ],\n    light: [\n      { color: 'rgb(220, 80, 40)', sizeW: 45, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(230, 150, 30)', sizeW: 35, sizeH: 32, offsetX: 65, offsetY: 0 },\n      { color: 'rgb(210, 110, 50)', sizeW: 40, sizeH: 28, offsetX: -60, offsetY: 2 },\n      { color: 'rgb(200, 60, 60)', sizeW: 35, sizeH: 34, offsetX: -90, offsetY: 0 },\n      { color: 'rgb(220, 170, 40)', sizeW: 38, sizeH: 30, offsetX: 85, offsetY: -1 },\n      { color: 'rgb(210, 100, 30)', sizeW: 50, sizeH: 24, offsetX: 35, offsetY: 1 },\n      { color: 'rgb(230, 130, 60)', sizeW: 40, sizeH: 22, offsetX: -35, offsetY: 0 },\n      { color: 'rgb(190, 70, 50)', sizeW: 35, sizeH: 28, offsetX: 110, offsetY: 1 },\n      { color: 'rgb(180, 50, 50)', sizeW: 30, sizeH: 30, offsetX: -110, offsetY: -1 },\n    ],\n  },\n  forest: {\n    dark: [\n      { color: 'rgb(46, 160, 90)', sizeW: 36, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(30, 190, 120)', sizeW: 30, sizeH: 32, offsetX: 39, offsetY: 0 },\n      { color: 'rgb(70, 180, 70)', sizeW: 33, sizeH: 28, offsetX: -36, offsetY: 2 },\n      { color: 'rgb(20, 150, 130)', sizeW: 29, sizeH: 34, offsetX: -54, offsetY: 0 },\n      { color: 'rgb(90, 200, 80)', sizeW: 27, sizeH: 30, offsetX: 51, offsetY: -1 },\n      { color: 'rgb(40, 170, 110)', sizeW: 36, sizeH: 24, offsetX: 21, offsetY: 1 },\n      { color: 'rgb(120, 210, 70)', sizeW: 30, sizeH: 22, offsetX: -21, offsetY: 0 },\n      { color: 'rgb(35, 145, 100)', sizeW: 25, sizeH: 28, offsetX: 66, offsetY: 1 },\n      { color: 'rgb(60, 195, 140)', sizeW: 23, sizeH: 30, offsetX: -66, offsetY: -1 },\n    ],\n    light: [\n      { color: 'rgb(33, 115, 65)', sizeW: 45, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(22, 137, 86)', sizeW: 35, sizeH: 32, offsetX: 65, offsetY: 0 },\n      { color: 'rgb(50, 130, 50)', sizeW: 40, sizeH: 28, offsetX: -60, offsetY: 2 },\n      { color: 'rgb(14, 108, 94)', sizeW: 35, sizeH: 34, offsetX: -90, offsetY: 0 },\n      { color: 'rgb(65, 144, 58)', sizeW: 38, sizeH: 30, offsetX: 85, offsetY: -1 },\n      { color: 'rgb(29, 122, 79)', sizeW: 50, sizeH: 24, offsetX: 35, offsetY: 1 },\n      { color: 'rgb(86, 151, 50)', sizeW: 40, sizeH: 22, offsetX: -35, offsetY: 0 },\n      { color: 'rgb(25, 104, 72)', sizeW: 35, sizeH: 28, offsetX: 110, offsetY: 1 },\n      { color: 'rgb(43, 140, 101)', sizeW: 30, sizeH: 30, offsetX: -110, offsetY: -1 },\n    ],\n  },\n  candy: {\n    dark: [\n      { color: 'rgb(240, 70, 170)', sizeW: 36, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(255, 90, 140)', sizeW: 30, sizeH: 32, offsetX: 39, offsetY: 0 },\n      { color: 'rgb(215, 60, 200)', sizeW: 33, sizeH: 28, offsetX: -36, offsetY: 2 },\n      { color: 'rgb(255, 110, 180)', sizeW: 29, sizeH: 34, offsetX: -54, offsetY: 0 },\n      { color: 'rgb(200, 80, 240)', sizeW: 27, sizeH: 30, offsetX: 51, offsetY: -1 },\n      { color: 'rgb(250, 60, 150)', sizeW: 36, sizeH: 24, offsetX: 21, offsetY: 1 },\n      { color: 'rgb(230, 120, 220)', sizeW: 30, sizeH: 22, offsetX: -21, offsetY: 0 },\n      { color: 'rgb(245, 85, 165)', sizeW: 25, sizeH: 28, offsetX: 66, offsetY: 1 },\n      { color: 'rgb(210, 70, 230)', sizeW: 23, sizeH: 30, offsetX: -66, offsetY: -1 },\n    ],\n    light: [\n      { color: 'rgb(173, 50, 122)', sizeW: 45, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(184, 65, 101)', sizeW: 35, sizeH: 32, offsetX: 65, offsetY: 0 },\n      { color: 'rgb(155, 43, 144)', sizeW: 40, sizeH: 28, offsetX: -60, offsetY: 2 },\n      { color: 'rgb(184, 79, 130)', sizeW: 35, sizeH: 34, offsetX: -90, offsetY: 0 },\n      { color: 'rgb(144, 58, 173)', sizeW: 38, sizeH: 30, offsetX: 85, offsetY: -1 },\n      { color: 'rgb(180, 43, 108)', sizeW: 50, sizeH: 24, offsetX: 35, offsetY: 1 },\n      { color: 'rgb(166, 86, 158)', sizeW: 40, sizeH: 22, offsetX: -35, offsetY: 0 },\n      { color: 'rgb(176, 61, 119)', sizeW: 35, sizeH: 28, offsetX: 110, offsetY: 1 },\n      { color: 'rgb(151, 50, 166)', sizeW: 30, sizeH: 30, offsetX: -110, offsetY: -1 },\n    ],\n  },\n  ice: {\n    dark: [\n      { color: 'rgb(90, 200, 240)', sizeW: 36, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(60, 175, 230)', sizeW: 30, sizeH: 32, offsetX: 39, offsetY: 0 },\n      { color: 'rgb(130, 220, 250)', sizeW: 33, sizeH: 28, offsetX: -36, offsetY: 2 },\n      { color: 'rgb(70, 190, 215)', sizeW: 29, sizeH: 34, offsetX: -54, offsetY: 0 },\n      { color: 'rgb(110, 210, 255)', sizeW: 27, sizeH: 30, offsetX: 51, offsetY: -1 },\n      { color: 'rgb(50, 165, 220)', sizeW: 36, sizeH: 24, offsetX: 21, offsetY: 1 },\n      { color: 'rgb(150, 230, 250)', sizeW: 30, sizeH: 22, offsetX: -21, offsetY: 0 },\n      { color: 'rgb(85, 195, 235)', sizeW: 25, sizeH: 28, offsetX: 66, offsetY: 1 },\n      { color: 'rgb(65, 180, 245)', sizeW: 23, sizeH: 30, offsetX: -66, offsetY: -1 },\n    ],\n    light: [\n      { color: 'rgb(65, 144, 173)', sizeW: 45, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(43, 126, 166)', sizeW: 35, sizeH: 32, offsetX: 65, offsetY: 0 },\n      { color: 'rgb(94, 158, 180)', sizeW: 40, sizeH: 28, offsetX: -60, offsetY: 2 },\n      { color: 'rgb(50, 137, 155)', sizeW: 35, sizeH: 34, offsetX: -90, offsetY: 0 },\n      { color: 'rgb(79, 151, 184)', sizeW: 38, sizeH: 30, offsetX: 85, offsetY: -1 },\n      { color: 'rgb(36, 119, 158)', sizeW: 50, sizeH: 24, offsetX: 35, offsetY: 1 },\n      { color: 'rgb(108, 166, 180)', sizeW: 40, sizeH: 22, offsetX: -35, offsetY: 0 },\n      { color: 'rgb(61, 140, 169)', sizeW: 35, sizeH: 28, offsetX: 110, offsetY: 1 },\n      { color: 'rgb(47, 130, 176)', sizeW: 30, sizeH: 30, offsetX: -110, offsetY: -1 },\n    ],\n  },\n  gold: {\n    dark: [\n      { color: 'rgb(240, 190, 60)', sizeW: 36, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(255, 210, 90)', sizeW: 30, sizeH: 32, offsetX: 39, offsetY: 0 },\n      { color: 'rgb(225, 165, 40)', sizeW: 33, sizeH: 28, offsetX: -36, offsetY: 2 },\n      { color: 'rgb(250, 200, 70)', sizeW: 29, sizeH: 34, offsetX: -54, offsetY: 0 },\n      { color: 'rgb(255, 225, 120)', sizeW: 27, sizeH: 30, offsetX: 51, offsetY: -1 },\n      { color: 'rgb(230, 175, 50)', sizeW: 36, sizeH: 24, offsetX: 21, offsetY: 1 },\n      { color: 'rgb(245, 205, 85)', sizeW: 30, sizeH: 22, offsetX: -21, offsetY: 0 },\n      { color: 'rgb(215, 155, 35)', sizeW: 25, sizeH: 28, offsetX: 66, offsetY: 1 },\n      { color: 'rgb(255, 215, 100)', sizeW: 23, sizeH: 30, offsetX: -66, offsetY: -1 },\n    ],\n    light: [\n      { color: 'rgb(173, 137, 43)', sizeW: 45, sizeH: 36, offsetX: 0, offsetY: 2 },\n      { color: 'rgb(184, 151, 65)', sizeW: 35, sizeH: 32, offsetX: 65, offsetY: 0 },\n      { color: 'rgb(162, 119, 29)', sizeW: 40, sizeH: 28, offsetX: -60, offsetY: 2 },\n      { color: 'rgb(180, 144, 50)', sizeW: 35, sizeH: 34, offsetX: -90, offsetY: 0 },\n      { color: 'rgb(184, 162, 86)', sizeW: 38, sizeH: 30, offsetX: 85, offsetY: -1 },\n      { color: 'rgb(166, 126, 36)', sizeW: 50, sizeH: 24, offsetX: 35, offsetY: 1 },\n      { color: 'rgb(176, 148, 61)', sizeW: 40, sizeH: 22, offsetX: -35, offsetY: 0 },\n      { color: 'rgb(155, 112, 25)', sizeW: 35, sizeH: 28, offsetX: 110, offsetY: 1 },\n      { color: 'rgb(184, 155, 72)', sizeW: 30, sizeH: 30, offsetX: -110, offsetY: -1 },\n    ],\n  },\n};\n\nfunction getLineColorGradients(colorVariant: BorderBeamColorVariant, isDark: boolean, id: string): string {\n  const palette = lineColorPalettes[colorVariant][isDark ? 'dark' : 'light'];\n  return palette\n    .map(c => {\n      const offsetXStr = c.offsetX === 0 ? '' : (c.offsetX > 0 ? ` + ${c.offsetX}px` : ` - ${Math.abs(c.offsetX)}px`);\n      const offsetYStr = c.offsetY === 0 ? '' : (c.offsetY > 0 ? ` + ${c.offsetY}px` : ` - ${Math.abs(c.offsetY)}px`);\n      return `radial-gradient(ellipse calc(${c.sizeW}px * var(--beam-w-${id})) calc(${c.sizeH}px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%${offsetXStr}) calc(100%${offsetYStr}), ${c.color}, transparent)`;\n    })\n    .join(',\\n       ');\n}\n\n// Inner gradient data matching v5.css exactly\nexport const lineInnerGradientData = {\n  colorful: [\n    { color: 'rgba(255, 50, 100, 0.48)', sizeW: 33, sizeH: 30, offsetX: 0, offsetY: 0 },\n    { color: 'rgba(40, 180, 220, 0.42)', sizeW: 24, sizeH: 26, offsetX: 39, offsetY: -3 },\n    { color: 'rgba(50, 200, 80, 0.48)', sizeW: 27, sizeH: 24, offsetX: -36, offsetY: 0 },\n    { color: 'rgba(180, 40, 240, 0.42)', sizeW: 23, sizeH: 28, offsetX: -54, offsetY: -2 },\n    { color: 'rgba(255, 160, 30, 0.50)', sizeW: 24, sizeH: 24, offsetX: 51, offsetY: -1 },\n    { color: 'rgba(100, 70, 255, 0.45)', sizeW: 30, sizeH: 20, offsetX: 21, offsetY: 0 },\n    { color: 'rgba(40, 140, 255, 0.40)', sizeW: 25, sizeH: 18, offsetX: -21, offsetY: -2 },\n    { color: 'rgba(240, 50, 180, 0.45)', sizeW: 21, sizeH: 24, offsetX: 66, offsetY: 0 },\n    { color: 'rgba(30, 185, 170, 0.52)', sizeW: 18, sizeH: 26, offsetX: -66, offsetY: -1 },\n  ],\n  mono: [\n    { color: 'rgba(200, 200, 200, 0.48)', sizeW: 33, sizeH: 30, offsetX: 0, offsetY: 0 },\n    { color: 'rgba(170, 170, 170, 0.42)', sizeW: 24, sizeH: 26, offsetX: 39, offsetY: -3 },\n    { color: 'rgba(155, 155, 155, 0.48)', sizeW: 27, sizeH: 24, offsetX: -36, offsetY: 0 },\n    { color: 'rgba(185, 185, 185, 0.42)', sizeW: 23, sizeH: 28, offsetX: -54, offsetY: -2 },\n    { color: 'rgba(165, 165, 165, 0.50)', sizeW: 24, sizeH: 24, offsetX: 51, offsetY: -1 },\n    { color: 'rgba(180, 180, 180, 0.45)', sizeW: 30, sizeH: 20, offsetX: 21, offsetY: 0 },\n    { color: 'rgba(160, 160, 160, 0.40)', sizeW: 25, sizeH: 18, offsetX: -21, offsetY: -2 },\n    { color: 'rgba(175, 175, 175, 0.45)', sizeW: 21, sizeH: 24, offsetX: 66, offsetY: 0 },\n    { color: 'rgba(190, 190, 190, 0.52)', sizeW: 18, sizeH: 26, offsetX: -66, offsetY: -1 },\n  ],\n  ocean: [\n    { color: 'rgba(100, 80, 220, 0.48)', sizeW: 33, sizeH: 30, offsetX: 0, offsetY: 0 },\n    { color: 'rgba(60, 120, 255, 0.42)', sizeW: 24, sizeH: 26, offsetX: 39, offsetY: -3 },\n    { color: 'rgba(80, 100, 200, 0.48)', sizeW: 27, sizeH: 24, offsetX: -36, offsetY: 0 },\n    { color: 'rgba(130, 70, 255, 0.42)', sizeW: 23, sizeH: 28, offsetX: -54, offsetY: -2 },\n    { color: 'rgba(70, 130, 255, 0.50)', sizeW: 24, sizeH: 24, offsetX: 51, offsetY: -1 },\n    { color: 'rgba(120, 80, 255, 0.45)', sizeW: 30, sizeH: 20, offsetX: 21, offsetY: 0 },\n    { color: 'rgba(90, 110, 230, 0.40)', sizeW: 25, sizeH: 18, offsetX: -21, offsetY: -2 },\n    { color: 'rgba(110, 90, 240, 0.45)', sizeW: 21, sizeH: 24, offsetX: 66, offsetY: 0 },\n    { color: 'rgba(140, 100, 255, 0.52)', sizeW: 18, sizeH: 26, offsetX: -66, offsetY: -1 },\n  ],\n  sunset: [\n    { color: 'rgba(255, 100, 60, 0.48)', sizeW: 33, sizeH: 30, offsetX: 0, offsetY: 0 },\n    { color: 'rgba(255, 180, 50, 0.42)', sizeW: 24, sizeH: 26, offsetX: 39, offsetY: -3 },\n    { color: 'rgba(255, 140, 70, 0.48)', sizeW: 27, sizeH: 24, offsetX: -36, offsetY: 0 },\n    { color: 'rgba(255, 80, 80, 0.42)', sizeW: 23, sizeH: 28, offsetX: -54, offsetY: -2 },\n    { color: 'rgba(255, 200, 60, 0.50)', sizeW: 24, sizeH: 24, offsetX: 51, offsetY: -1 },\n    { color: 'rgba(255, 120, 50, 0.45)', sizeW: 30, sizeH: 20, offsetX: 21, offsetY: 0 },\n    { color: 'rgba(255, 160, 80, 0.40)', sizeW: 25, sizeH: 18, offsetX: -21, offsetY: -2 },\n    { color: 'rgba(255, 90, 60, 0.45)', sizeW: 21, sizeH: 24, offsetX: 66, offsetY: 0 },\n    { color: 'rgba(255, 70, 70, 0.52)', sizeW: 18, sizeH: 26, offsetX: -66, offsetY: -1 },\n  ],\n  forest: [\n    { color: 'rgba(46, 160, 90,, 0.48)', sizeW: 33, sizeH: 30, offsetX: 0, offsetY: 0 },\n    { color: 'rgba(30, 190, 120,, 0.42)', sizeW: 24, sizeH: 26, offsetX: 39, offsetY: -3 },\n    { color: 'rgba(70, 180, 70,, 0.48)', sizeW: 27, sizeH: 24, offsetX: -36, offsetY: 0 },\n    { color: 'rgba(20, 150, 130,, 0.42)', sizeW: 23, sizeH: 28, offsetX: -54, offsetY: -2 },\n    { color: 'rgba(90, 200, 80,, 0.50)', sizeW: 24, sizeH: 24, offsetX: 51, offsetY: -1 },\n    { color: 'rgba(40, 170, 110,, 0.45)', sizeW: 30, sizeH: 20, offsetX: 21, offsetY: 0 },\n    { color: 'rgba(120, 210, 70,, 0.40)', sizeW: 25, sizeH: 18, offsetX: -21, offsetY: -2 },\n    { color: 'rgba(35, 145, 100,, 0.45)', sizeW: 21, sizeH: 24, offsetX: 66, offsetY: 0 },\n    { color: 'rgba(60, 195, 140,, 0.52)', sizeW: 18, sizeH: 26, offsetX: -66, offsetY: -1 },\n  ],\n  candy: [\n    { color: 'rgba(240, 70, 170,, 0.48)', sizeW: 33, sizeH: 30, offsetX: 0, offsetY: 0 },\n    { color: 'rgba(255, 90, 140,, 0.42)', sizeW: 24, sizeH: 26, offsetX: 39, offsetY: -3 },\n    { color: 'rgba(215, 60, 200,, 0.48)', sizeW: 27, sizeH: 24, offsetX: -36, offsetY: 0 },\n    { color: 'rgba(255, 110, 180,, 0.42)', sizeW: 23, sizeH: 28, offsetX: -54, offsetY: -2 },\n    { color: 'rgba(200, 80, 240,, 0.50)', sizeW: 24, sizeH: 24, offsetX: 51, offsetY: -1 },\n    { color: 'rgba(250, 60, 150,, 0.45)', sizeW: 30, sizeH: 20, offsetX: 21, offsetY: 0 },\n    { color: 'rgba(230, 120, 220,, 0.40)', sizeW: 25, sizeH: 18, offsetX: -21, offsetY: -2 },\n    { color: 'rgba(245, 85, 165,, 0.45)', sizeW: 21, sizeH: 24, offsetX: 66, offsetY: 0 },\n    { color: 'rgba(210, 70, 230,, 0.52)', sizeW: 18, sizeH: 26, offsetX: -66, offsetY: -1 },\n  ],\n  ice: [\n    { color: 'rgba(90, 200, 240,, 0.48)', sizeW: 33, sizeH: 30, offsetX: 0, offsetY: 0 },\n    { color: 'rgba(60, 175, 230,, 0.42)', sizeW: 24, sizeH: 26, offsetX: 39, offsetY: -3 },\n    { color: 'rgba(130, 220, 250,, 0.48)', sizeW: 27, sizeH: 24, offsetX: -36, offsetY: 0 },\n    { color: 'rgba(70, 190, 215,, 0.42)', sizeW: 23, sizeH: 28, offsetX: -54, offsetY: -2 },\n    { color: 'rgba(110, 210, 255,, 0.50)', sizeW: 24, sizeH: 24, offsetX: 51, offsetY: -1 },\n    { color: 'rgba(50, 165, 220,, 0.45)', sizeW: 30, sizeH: 20, offsetX: 21, offsetY: 0 },\n    { color: 'rgba(150, 230, 250,, 0.40)', sizeW: 25, sizeH: 18, offsetX: -21, offsetY: -2 },\n    { color: 'rgba(85, 195, 235,, 0.45)', sizeW: 21, sizeH: 24, offsetX: 66, offsetY: 0 },\n    { color: 'rgba(65, 180, 245,, 0.52)', sizeW: 18, sizeH: 26, offsetX: -66, offsetY: -1 },\n  ],\n  gold: [\n    { color: 'rgba(240, 190, 60,, 0.48)', sizeW: 33, sizeH: 30, offsetX: 0, offsetY: 0 },\n    { color: 'rgba(255, 210, 90,, 0.42)', sizeW: 24, sizeH: 26, offsetX: 39, offsetY: -3 },\n    { color: 'rgba(225, 165, 40,, 0.48)', sizeW: 27, sizeH: 24, offsetX: -36, offsetY: 0 },\n    { color: 'rgba(250, 200, 70,, 0.42)', sizeW: 23, sizeH: 28, offsetX: -54, offsetY: -2 },\n    { color: 'rgba(255, 225, 120,, 0.50)', sizeW: 24, sizeH: 24, offsetX: 51, offsetY: -1 },\n    { color: 'rgba(230, 175, 50,, 0.45)', sizeW: 30, sizeH: 20, offsetX: 21, offsetY: 0 },\n    { color: 'rgba(245, 205, 85,, 0.40)', sizeW: 25, sizeH: 18, offsetX: -21, offsetY: -2 },\n    { color: 'rgba(215, 155, 35,, 0.45)', sizeW: 21, sizeH: 24, offsetX: 66, offsetY: 0 },\n    { color: 'rgba(255, 215, 100,, 0.52)', sizeW: 18, sizeH: 26, offsetX: -66, offsetY: -1 },\n  ],\n};\n\nfunction getLineInnerGradients(colorVariant: BorderBeamColorVariant, id: string): string {\n  const data = lineInnerGradientData[colorVariant];\n  return data\n    .map(c => {\n      const offsetXStr = c.offsetX === 0 ? '' : (c.offsetX > 0 ? ` + ${c.offsetX}px` : ` - ${Math.abs(c.offsetX)}px`);\n      const offsetYStr = c.offsetY === 0 ? '' : ` - ${Math.abs(c.offsetY)}px`;\n      return `radial-gradient(ellipse calc(${c.sizeW}px * var(--beam-w-${id})) calc(${c.sizeH}px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%${offsetXStr}) calc(100%${offsetYStr}), ${c.color}, transparent)`;\n    })\n    .join(',\\n    ');\n}\n\nexport const lineBloomColors = {\n  colorful: {\n    dark: {\n      spikes: [\n        { color1: 'rgb(100, 70, 255)', color2: 'rgba(100, 70, 255, 1)' },              // 36%\n        { color1: 'rgba(255, 170, 40, 0.59)', color2: 'rgba(255, 170, 40, 0.29)' },    // 50%\n        { color1: 'rgb(50, 200, 100)', color2: 'rgba(50, 200, 100, 1)' },              // 64%\n        { color1: 'rgba(200, 50, 240, 0.91)', color2: 'rgba(200, 50, 240, 0.45)' },    // 78%\n        { color1: 'rgb(40, 140, 255)', color2: 'rgba(40, 140, 255, 1)' },              // 92%\n      ],\n    },\n    light: {\n      spikes: [\n        { color1: 'rgb(80, 50, 200)', color2: 'rgba(80, 50, 200, 0.8)' },      // 36%\n        { color1: 'rgba(210, 130, 0, 0.7)', color2: 'rgba(210, 130, 0, 0.46)' }, // 50%\n        { color1: 'rgb(30, 160, 70)', color2: 'rgba(30, 160, 70, 0.82)' },     // 64%\n        { color1: 'rgb(160, 30, 190)', color2: 'rgba(160, 30, 190, 0.7)' },    // 78%\n        { color1: 'rgb(30, 100, 200)', color2: 'rgba(30, 100, 200, 0.78)' },   // 92%\n      ],\n    },\n  },\n  mono: {\n    dark: {\n      spikes: [\n        { color1: 'rgb(200, 200, 200)', color2: 'rgba(200, 200, 200, 1)' },\n        { color1: 'rgba(180, 180, 180, 0.59)', color2: 'rgba(180, 180, 180, 0.29)' },\n        { color1: 'rgb(190, 190, 190)', color2: 'rgba(190, 190, 190, 1)' },\n        { color1: 'rgba(170, 170, 170, 0.91)', color2: 'rgba(170, 170, 170, 0.45)' },\n        { color1: 'rgb(185, 185, 185)', color2: 'rgba(185, 185, 185, 1)' },\n      ],\n    },\n    light: {\n      spikes: [\n        { color1: 'rgb(80, 80, 80)', color2: 'rgba(80, 80, 80, 0.8)' },\n        { color1: 'rgba(100, 100, 100, 0.7)', color2: 'rgba(100, 100, 100, 0.46)' },\n        { color1: 'rgb(70, 70, 70)', color2: 'rgba(70, 70, 70, 0.82)' },\n        { color1: 'rgb(90, 90, 90)', color2: 'rgba(90, 90, 90, 0.7)' },\n        { color1: 'rgb(85, 85, 85)', color2: 'rgba(85, 85, 85, 0.78)' },\n      ],\n    },\n  },\n  ocean: {\n    dark: {\n      spikes: [\n        { color1: 'rgb(100, 80, 255)', color2: 'rgb(100, 80, 255)' },\n        { color1: 'rgba(80, 130, 220, 0.59)', color2: 'rgba(80, 130, 220, 0.29)' },\n        { color1: 'rgb(60, 100, 255)', color2: 'rgb(60, 100, 255)' },\n        { color1: 'rgba(90, 120, 200, 0.91)', color2: 'rgba(90, 120, 200, 0.45)' },\n        { color1: 'rgb(120, 90, 255)', color2: 'rgb(120, 90, 255)' },\n      ],\n    },\n    light: {\n      spikes: [\n        { color1: 'rgb(50, 40, 180)', color2: 'rgba(50, 40, 180, 0.8)' },\n        { color1: 'rgba(40, 80, 200, 0.7)', color2: 'rgba(40, 80, 200, 0.46)' },\n        { color1: 'rgb(30, 50, 190)', color2: 'rgba(30, 50, 190, 0.82)' },\n        { color1: 'rgb(60, 90, 180)', color2: 'rgba(60, 90, 180, 0.7)' },\n        { color1: 'rgb(70, 60, 200)', color2: 'rgba(70, 60, 200, 0.78)' },\n      ],\n    },\n  },\n  sunset: {\n    dark: {\n      spikes: [\n        { color1: 'rgb(255, 100, 80)', color2: 'rgb(255, 100, 80)' },\n        { color1: 'rgba(255, 150, 80, 0.59)', color2: 'rgba(255, 150, 80, 0.29)' },\n        { color1: 'rgb(255, 80, 60)', color2: 'rgb(255, 80, 60)' },\n        { color1: 'rgba(255, 120, 50, 0.91)', color2: 'rgba(255, 120, 50, 0.45)' },\n        { color1: 'rgb(255, 140, 70)', color2: 'rgb(255, 140, 70)' },\n      ],\n    },\n    light: {\n      spikes: [\n        { color1: 'rgb(200, 60, 30)', color2: 'rgba(200, 60, 30, 0.8)' },\n        { color1: 'rgba(220, 100, 20, 0.7)', color2: 'rgba(220, 100, 20, 0.46)' },\n        { color1: 'rgb(180, 40, 20)', color2: 'rgba(180, 40, 20, 0.82)' },\n        { color1: 'rgb(210, 80, 10)', color2: 'rgba(210, 80, 10, 0.7)' },\n        { color1: 'rgb(190, 70, 30)', color2: 'rgba(190, 70, 30, 0.78)' },\n      ],\n    },\n  },\n  forest: {\n    dark: {\n      spikes: [\n        { color1: 'rgb(46, 160, 90)', color2: 'rgb(30, 190, 120)' },\n        { color1: 'rgba(70, 180, 70,, 0.59)', color2: 'rgba(20, 150, 130,, 0.29)' },\n        { color1: 'rgb(90, 200, 80)', color2: 'rgb(40, 170, 110)' },\n        { color1: 'rgba(120, 210, 70,, 0.91)', color2: 'rgba(35, 145, 100,, 0.45)' },\n        { color1: 'rgb(60, 195, 140)', color2: 'rgb(46, 160, 90)' },\n      ],\n    },\n    light: {\n      spikes: [\n        { color1: 'rgb(33, 115, 65)', color2: 'rgba(22, 137, 86,, 0.8)' },\n        { color1: 'rgba(50, 130, 50,, 0.7)', color2: 'rgba(14, 108, 94,, 0.46)' },\n        { color1: 'rgb(65, 144, 58)', color2: 'rgba(29, 122, 79,, 0.82)' },\n        { color1: 'rgb(86, 151, 50)', color2: 'rgba(25, 104, 72,, 0.7)' },\n        { color1: 'rgb(43, 140, 101)', color2: 'rgba(33, 115, 65,, 0.78)' },\n      ],\n    },\n  },\n  candy: {\n    dark: {\n      spikes: [\n        { color1: 'rgb(240, 70, 170)', color2: 'rgb(255, 90, 140)' },\n        { color1: 'rgba(215, 60, 200,, 0.59)', color2: 'rgba(255, 110, 180,, 0.29)' },\n        { color1: 'rgb(200, 80, 240)', color2: 'rgb(250, 60, 150)' },\n        { color1: 'rgba(230, 120, 220,, 0.91)', color2: 'rgba(245, 85, 165,, 0.45)' },\n        { color1: 'rgb(210, 70, 230)', color2: 'rgb(240, 70, 170)' },\n      ],\n    },\n    light: {\n      spikes: [\n        { color1: 'rgb(173, 50, 122)', color2: 'rgba(184, 65, 101,, 0.8)' },\n        { color1: 'rgba(155, 43, 144,, 0.7)', color2: 'rgba(184, 79, 130,, 0.46)' },\n        { color1: 'rgb(144, 58, 173)', color2: 'rgba(180, 43, 108,, 0.82)' },\n        { color1: 'rgb(166, 86, 158)', color2: 'rgba(176, 61, 119,, 0.7)' },\n        { color1: 'rgb(151, 50, 166)', color2: 'rgba(173, 50, 122,, 0.78)' },\n      ],\n    },\n  },\n  ice: {\n    dark: {\n      spikes: [\n        { color1: 'rgb(90, 200, 240)', color2: 'rgb(60, 175, 230)' },\n        { color1: 'rgba(130, 220, 250,, 0.59)', color2: 'rgba(70, 190, 215,, 0.29)' },\n        { color1: 'rgb(110, 210, 255)', color2: 'rgb(50, 165, 220)' },\n        { color1: 'rgba(150, 230, 250,, 0.91)', color2: 'rgba(85, 195, 235,, 0.45)' },\n        { color1: 'rgb(65, 180, 245)', color2: 'rgb(90, 200, 240)' },\n      ],\n    },\n    light: {\n      spikes: [\n        { color1: 'rgb(65, 144, 173)', color2: 'rgba(43, 126, 166,, 0.8)' },\n        { color1: 'rgba(94, 158, 180,, 0.7)', color2: 'rgba(50, 137, 155,, 0.46)' },\n        { color1: 'rgb(79, 151, 184)', color2: 'rgba(36, 119, 158,, 0.82)' },\n        { color1: 'rgb(108, 166, 180)', color2: 'rgba(61, 140, 169,, 0.7)' },\n        { color1: 'rgb(47, 130, 176)', color2: 'rgba(65, 144, 173,, 0.78)' },\n      ],\n    },\n  },\n  gold: {\n    dark: {\n      spikes: [\n        { color1: 'rgb(240, 190, 60)', color2: 'rgb(255, 210, 90)' },\n        { color1: 'rgba(225, 165, 40,, 0.59)', color2: 'rgba(250, 200, 70,, 0.29)' },\n        { color1: 'rgb(255, 225, 120)', color2: 'rgb(230, 175, 50)' },\n        { color1: 'rgba(245, 205, 85,, 0.91)', color2: 'rgba(215, 155, 35,, 0.45)' },\n        { color1: 'rgb(255, 215, 100)', color2: 'rgb(240, 190, 60)' },\n      ],\n    },\n    light: {\n      spikes: [\n        { color1: 'rgb(173, 137, 43)', color2: 'rgba(184, 151, 65,, 0.8)' },\n        { color1: 'rgba(162, 119, 29,, 0.7)', color2: 'rgba(180, 144, 50,, 0.46)' },\n        { color1: 'rgb(184, 162, 86)', color2: 'rgba(166, 126, 36,, 0.82)' },\n        { color1: 'rgb(176, 148, 61)', color2: 'rgba(155, 112, 25,, 0.7)' },\n        { color1: 'rgb(184, 155, 72)', color2: 'rgba(173, 137, 43,, 0.78)' },\n      ],\n    },\n  },\n};\n\nfunction withAlpha(color: string, alpha: number): string {\n  const rgbaMatch = color.match(/^rgba\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*[\\d.]+\\s*\\)$/);\n  if (rgbaMatch) return `rgba(${rgbaMatch[1]}, ${rgbaMatch[2]}, ${rgbaMatch[3]}, ${alpha})`;\n  const rgbMatch = color.match(/^rgb\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*\\)$/);\n  if (rgbMatch) return `rgba(${rgbMatch[1]}, ${rgbMatch[2]}, ${rgbMatch[3]}, ${alpha})`;\n  return color;\n}\n\nfunction attenuateSpike(color: string, factor: number): string {\n  const rgbaMatch = color.match(/^rgba\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*\\)$/);\n  if (rgbaMatch) return `rgba(${rgbaMatch[1]}, ${rgbaMatch[2]}, ${rgbaMatch[3]}, ${(parseFloat(rgbaMatch[4]) * factor).toFixed(2)})`;\n  const rgbMatch = color.match(/^rgb\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*\\)$/);\n  if (rgbMatch) return `rgba(${rgbMatch[1]}, ${rgbMatch[2]}, ${rgbMatch[3]}, ${factor.toFixed(2)})`;\n  return color;\n}\n\nfunction getLineBloomGradients(colorVariant: BorderBeamColorVariant, isDark: boolean, id: string): string {\n  const spikeColors = getSpikeColors(colorVariant, isDark);\n  const bloomData = lineBloomColors[colorVariant][isDark ? 'dark' : 'light'];\n  const isMono = colorVariant === 'mono';\n\n  // Mono uses uniform gray so thin spikes at full opacity look like harsh bars.\n  // Attenuate opacity and widen the thin gradients so they appear as soft glows.\n  const att = isMono ? 0.14 : 1;\n  const sc1     = isMono ? attenuateSpike(spikeColors.primary, 0.14) : spikeColors.primary;\n  const sc1_mid = isMono ? attenuateSpike(spikeColors.primary, 0.09) : spikeColors.primary;\n  const sc2     = isMono ? attenuateSpike(spikeColors.secondary, 0.12) : spikeColors.secondary;\n  const sc2_mid = isMono ? withAlpha(spikeColors.secondary, 0.06) : withAlpha(spikeColors.secondary, 0.49);\n\n  const spikes = bloomData.spikes.map(s => isMono\n    ? { color1: attenuateSpike(s.color1, att), color2: attenuateSpike(s.color2, att * 0.7) }\n    : s\n  );\n\n  // Mono: wide, blurred soft spikes; shortened heights\n  const thinW1 = isMono ? '12px'  : '0.8px';\n  const thinW2 = isMono ? '14px'  : '2px';\n  const thinW3 = isMono ? '12px'  : '1.2px';\n  const thinW4 = isMono ? '10px'  : '0.6px';\n  const thinH1 = isMono ? '42px'  : '92px';\n  const thinH2 = isMono ? '38px'  : '72px';\n  const thinH3 = isMono ? '40px'  : '85px';\n  const thinH4 = isMono ? '32px'  : '60px';\n  const thinLW = isMono ? '12px'  : '1px';\n\n  // Main glow: center dot + ambient — mono gets 50% lower opacity\n  const glowDotC   = isMono ? 'rgba(255, 255, 255, 0.5)'  : 'rgba(255, 255, 255, 1)';\n  const glowDot20  = isMono ? 'rgba(255, 255, 255, 0.45)' : 'rgba(255, 255, 255, 0.9)';\n  const glowDot50  = isMono ? 'rgba(255, 255, 255, 0.25)' : 'rgba(255, 255, 255, 0.5)';\n  const glowAmbC   = isMono ? 'rgba(255, 255, 255, 0.15)' : 'rgba(255, 255, 255, 0.3)';\n  const glowAmb25  = isMono ? 'rgba(255, 255, 255, 0.06)' : 'rgba(255, 255, 255, 0.12)';\n  const glowAmb55  = isMono ? 'rgba(255, 255, 255, 0.015)': 'rgba(255, 255, 255, 0.03)';\n\n  if (isDark) {\n    return `radial-gradient(ellipse calc(${thinW1} * var(--beam-spike-${id}) * var(--beam-spike-mul, 1)) calc(${thinH1} * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 8% calc(100% - 2px), ${sc1}, ${sc1_mid} 30%, transparent 88%),\n       radial-gradient(ellipse calc(10px * var(--beam-spike2-${id}) * var(--beam-spike-mul, 1)) calc(35px * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 22% calc(100% - 4px), ${sc2}, ${sc2_mid} 50%, transparent 95%),\n       radial-gradient(ellipse calc(${thinW2} * (2 - var(--beam-spike-${id})) * var(--beam-spike-mul, 1)) calc(${thinH2} * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 36% calc(100% - 3px), ${spikes[0].color1}, ${spikes[0].color2} 40%, transparent 90%),\n       radial-gradient(ellipse calc(14px * var(--beam-spike2-${id}) * var(--beam-spike-mul, 1)) calc(28px * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 50% calc(100% - 2px), ${spikes[1].color1}, ${spikes[1].color2} 55%, transparent 96%),\n       radial-gradient(ellipse calc(${thinW3} * (2 - var(--beam-spike2-${id})) * var(--beam-spike-mul, 1)) calc(${thinH3} * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 64% calc(100% - 4px), ${spikes[2].color1}, ${spikes[2].color2} 35%, transparent 89%),\n       radial-gradient(ellipse calc(7px * var(--beam-spike-${id}) * var(--beam-spike-mul, 1)) calc(45px * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 78% calc(100% - 2px), ${spikes[3].color1}, ${spikes[3].color2} 48%, transparent 94%),\n       radial-gradient(ellipse calc(${thinW4} * (2 - var(--beam-spike-${id})) * var(--beam-spike-mul, 1)) calc(${thinH4} * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 92% calc(100% - 3px), ${spikes[4].color1}, ${spikes[4].color2} 42%, transparent 91%),\n       radial-gradient(ellipse calc(21px * var(--beam-spike-${id})) calc(15px * var(--beam-spike2-${id})) at calc(var(--beam-x-${id}) * 100%) calc(100% + 1px), ${glowDotC} 0%, ${glowDot20} 20%, ${glowDot50} 50%, transparent 100%),\n       radial-gradient(ellipse calc(42px * var(--beam-w-${id})) calc(40px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) 100%, ${glowAmbC} 0%, ${glowAmb25} 25%, ${glowAmb55} 55%, transparent 80%)`;\n  } else {\n    const sc1_lt = isMono ? attenuateSpike(spikeColors.primary, 0.11) : withAlpha(spikeColors.primary, 0.85);\n    const sc2_lt = isMono ? attenuateSpike(spikeColors.secondary, 0.09) : withAlpha(spikeColors.secondary, 0.7);\n    return `radial-gradient(ellipse calc(${thinW1} * var(--beam-spike-${id}) * var(--beam-spike-mul, 1)) calc(${thinH1} * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 8% calc(100% - 2px), ${sc1}, ${sc1_lt} 30%, transparent 88%),\n       radial-gradient(ellipse calc(10px * var(--beam-spike2-${id}) * var(--beam-spike-mul, 1)) calc(35px * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 22% calc(100% - 4px), ${sc2}, ${sc2_lt} 50%, transparent 95%),\n       radial-gradient(ellipse calc(${thinW2} * (2 - var(--beam-spike-${id})) * var(--beam-spike-mul, 1)) calc(${thinH2} * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 36% calc(100% - 3px), ${spikes[0].color1}, ${spikes[0].color2} 40%, transparent 90%),\n       radial-gradient(ellipse calc(14px * var(--beam-spike2-${id}) * var(--beam-spike-mul, 1)) calc(28px * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 50% calc(100% - 2px), ${spikes[1].color1}, ${spikes[1].color2} 55%, transparent 96%),\n       radial-gradient(ellipse calc(${thinW3} * (2 - var(--beam-spike2-${id})) * var(--beam-spike-mul, 1)) calc(${thinH3} * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 64% calc(100% - 4px), ${spikes[2].color1}, ${spikes[2].color2} 35%, transparent 89%),\n       radial-gradient(ellipse calc(7px * var(--beam-spike-${id}) * var(--beam-spike-mul, 1)) calc(45px * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 78% calc(100% - 2px), ${spikes[3].color1}, ${spikes[3].color2} 48%, transparent 94%),\n       radial-gradient(ellipse calc(${thinLW} * (2 - var(--beam-spike-${id})) * var(--beam-spike-mul, 1)) calc(${thinH4} * var(--beam-h-${id}) * var(--beam-spike-mul, 1)) at 92% calc(100% - 3px), ${spikes[4].color1}, ${spikes[4].color2} 42%, transparent 91%),\n       radial-gradient(ellipse calc(50px * var(--beam-w-${id})) calc(32px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) calc(100%), rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.18) 30%, rgba(0, 0, 0, 0.03) 60%, transparent 85%)`;\n  }\n}\n\n/* ──────────────────────────────────────────────────────────────────────────\n * Pulse family (breathing glow, no rotation) — ported from the v5 prototype\n * Card 4 (\"pulse-inner\", contained) and Card 5 (\"pulse-outside\", outward bloom).\n *\n * Both effects animate three independent size/drift regions (g1/g2/g3) and four\n * per-quadrant opacity oscillators (tl/tr/bl/br) on desynced periods, plus a\n * global height oscillator (gh) and a hue-shift filter. The gradient COLORS come\n * from the shared `colorPalettes` (so every color variant + strength works), while\n * the geometry below (sizes/positions/region/quadrant) is identical across colors.\n * ──────────────────────────────────────────────────────────────────────────*/\n\ntype PulseRegion = 1 | 2 | 3;\ntype PulseQuad = 'tl' | 'tr' | 'bl' | 'br';\n\n// Which size-region (g1/g2/g3) and opacity-quadrant each of the 9 palette\n// gradients belongs to (taken from the v5 Card 4 ::after ordering).\nexport const PULSE_RING_MAP: { region: PulseRegion; quad: PulseQuad }[] = [\n  { region: 1, quad: 'tl' },\n  { region: 2, quad: 'tl' },\n  { region: 3, quad: 'bl' },\n  { region: 1, quad: 'bl' },\n  { region: 2, quad: 'br' },\n  { region: 3, quad: 'br' },\n  { region: 1, quad: 'tr' },\n  { region: 2, quad: 'tr' },\n  { region: 3, quad: 'tr' },\n];\n\n// Card 4 inner-perimeter (::before) gradient sizes — slightly smaller than the ring.\nexport const PULSE_INNER_SIZES: [number, number][] = [\n  [65, 35], [55, 30], [35, 65], [15, 30], [173, 28], [80, 22], [69, 28], [22, 38], [47, 44],\n];\n\nexport interface PulseGradientDef {\n  ci: number; // index into colorPalettes[variant].border\n  region: PulseRegion;\n  quad: PulseQuad;\n  w: number;\n  h: number;\n  x?: string; // explicit position (outer effect); falls back to palette pos\n  y?: string;\n}\n\n// Card 4 bloom — 7 of the 9 colors, expanded sizes (positions come from palette).\nexport const PULSE_INNER_BLOOM: PulseGradientDef[] = [\n  { ci: 0, region: 1, quad: 'tl', w: 84, h: 48 },\n  { ci: 1, region: 2, quad: 'tl', w: 72, h: 42 },\n  { ci: 2, region: 3, quad: 'bl', w: 48, h: 84 },\n  { ci: 4, region: 2, quad: 'br', w: 216, h: 38 },\n  { ci: 5, region: 3, quad: 'br', w: 102, h: 31 },\n  { ci: 6, region: 1, quad: 'tr', w: 89, h: 38 },\n  { ci: 8, region: 3, quad: 'tr', w: 62, h: 58 },\n];\n\n// Card 5 outward core (::after hairline + ::before glow share this edge-positioned set).\nexport const PULSE_OUTER_CORE: PulseGradientDef[] = [\n  { ci: 0, region: 1, quad: 'tl', w: 80, h: 19, x: '27%', y: '0%' },\n  { ci: 6, region: 2, quad: 'tr', w: 74, h: 11, x: '73%', y: '-1%' },\n  { ci: 7, region: 3, quad: 'tr', w: 15, h: 44, x: '100%', y: '33%' },\n  { ci: 8, region: 1, quad: 'br', w: 19, h: 38, x: '101%', y: '72%' },\n  { ci: 4, region: 2, quad: 'br', w: 84, h: 13, x: '67%', y: '100%' },\n  { ci: 1, region: 3, quad: 'bl', w: 60, h: 21, x: '24%', y: '101%' },\n  { ci: 2, region: 1, quad: 'bl', w: 17, h: 40, x: '0%', y: '60%' },\n  { ci: 3, region: 2, quad: 'tl', w: 13, h: 32, x: '-1%', y: '28%' },\n];\n\n// Card 5 outward bloom — wider/blurred halo (7 gradients).\nexport const PULSE_OUTER_BLOOM: PulseGradientDef[] = [\n  { ci: 0, region: 1, quad: 'tl', w: 110, h: 30, x: '27%', y: '3%' },\n  { ci: 6, region: 2, quad: 'tr', w: 100, h: 20, x: '73%', y: '1%' },\n  { ci: 7, region: 3, quad: 'tr', w: 26, h: 62, x: '100%', y: '33%' },\n  { ci: 8, region: 1, quad: 'br', w: 30, h: 56, x: '101%', y: '72%' },\n  { ci: 4, region: 2, quad: 'br', w: 120, h: 22, x: '67%', y: '99%' },\n  { ci: 1, region: 3, quad: 'bl', w: 88, h: 32, x: '24%', y: '99%' },\n  { ci: 2, region: 1, quad: 'bl', w: 28, h: 58, x: '0%', y: '60%' },\n];\n\nfunction fmtNum(v: number): string {\n  return (+v.toFixed(3)).toString();\n}\n\n// Convert an `rgb()` palette color into `rgba()` whose alpha is the live quadrant\n// opacity custom property, so the gradient breathes per-quadrant.\nfunction withAlphaVar(color: string, quad: PulseQuad, id: string): string {\n  const m = color.match(/^rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/);\n  const rgb = m ? `${m[1]}, ${m[2]}, ${m[3]}` : '255, 255, 255';\n  return `rgba(${rgb}, var(--bop-${quad}-${id}))`;\n}\n\nfunction pulseGrad(\n  color: string,\n  w: number,\n  h: number,\n  region: PulseRegion,\n  quad: PulseQuad,\n  x: string,\n  y: string,\n  id: string\n): string {\n  // `--pulse-glow-sx/sy` (set inline by the component for pulse-outside) scale the\n  // blob WIDTH/HEIGHT to the measured element size, so the glow fits any component.\n  // Positions stay percentage-based, so blobs keep hugging the element's edges.\n  // Defaults to 1 (e.g. pulse-inner never sets them), leaving geometry unchanged.\n  // `--pulse-glow-boost` is a consumer hook: a relative multiplier on top of the\n  // measured scale, so the glow can be intensified proportionally on any element.\n  return `radial-gradient(ellipse calc(${w}px * var(--bw${region}-${id}) * var(--pulse-glow-sx, 1) * var(--pulse-glow-boost, 1)) calc(${h}px * var(--bh${region}-${id}) * var(--bgh-${id}) * var(--pulse-glow-sy, 1) * var(--pulse-glow-boost, 1)) at calc(${x} + var(--bx${region}-${id})) calc(${y} + var(--by${region}-${id})), ${withAlphaVar(color, quad, id)}, transparent)`;\n}\n\n// The 9-gradient perimeter ring (Card 4 ::after / Card 5 stroke share this) —\n// positions + sizes come straight from the palette, region/quad from PULSE_RING_MAP.\nfunction pulseRingGradients(variant: BorderBeamColorVariant, id: string): string {\n  return colorPalettes[variant].border\n    .map((c, i) => {\n      const { region, quad } = PULSE_RING_MAP[i];\n      const [x, y] = c.pos.split(' ');\n      const [w, h] = c.size.split(' ').map(parseFloat);\n      return pulseGrad(c.color, w, h, region, quad, x, y, id);\n    })\n    .join(',\\n    ');\n}\n\n// Card 4 inner-perimeter gradients (smaller sizes) plus the bright corner accents.\nfunction pulseInnerGradients(variant: BorderBeamColorVariant, id: string, isDark: boolean): string {\n  const palette = colorPalettes[variant].border;\n  const grads = palette.map((c, i) => {\n    const { region, quad } = PULSE_RING_MAP[i];\n    const [x, y] = c.pos.split(' ');\n    const [w, h] = PULSE_INNER_SIZES[i];\n    return pulseGrad(c.color, w, h, region, quad, x, y, id);\n  });\n  const cornerRGB = isDark ? '255, 255, 255' : '0, 0, 0';\n  const cornerAlpha = isDark ? 0.18 : 0.08;\n  const corners: [string, string, PulseQuad][] = [\n    ['0%', '0%', 'tl'],\n    ['100%', '0%', 'tr'],\n    ['0%', '100%', 'bl'],\n    ['100%', '100%', 'br'],\n  ];\n  const cornerGrads = corners.map(\n    ([x, y, q]) =>\n      `radial-gradient(ellipse 60px 60px at ${x} ${y}, rgba(${cornerRGB}, calc(${cornerAlpha} * var(--bop-${q}-${id}))), transparent 70%)`\n  );\n  return [...grads, ...cornerGrads].join(',\\n    ');\n}\n\n// Emit a fixed gradient table (used by inner bloom + both outer layers).\nfunction pulseTableGradients(\n  table: PulseGradientDef[],\n  variant: BorderBeamColorVariant,\n  id: string\n): string {\n  const palette = colorPalettes[variant].border;\n  return table\n    .map(e => {\n      const c = palette[e.ci];\n      const [px, py] = c.pos.split(' ');\n      return pulseGrad(c.color, e.w, e.h, e.region, e.quad, e.x ?? px, e.y ?? py, id);\n    })\n    .join(',\\n    ');\n}\n\n// Frozen variant of the bloom gradients: emits literal sizes/positions with a\n// fixed per-blob alpha (the time-average of the breathing range) instead of the\n// live `var(--bw…/--bop…)` custom properties. Because the bloom's background no\n// longer changes per frame, its heavily-blurred bitmap is painted ONCE and cached\n// by the compositor rather than re-rasterized 60–120×/sec — the single biggest\n// per-frame cost in the pulse effect.\nfunction pulseTableGradientsStatic(\n  table: PulseGradientDef[],\n  variant: BorderBeamColorVariant,\n  frozenAlpha: number\n): string {\n  const palette = colorPalettes[variant].border;\n  const a = +frozenAlpha.toFixed(3);\n  return table\n    .map(e => {\n      const c = palette[e.ci];\n      const [px, py] = c.pos.split(' ');\n      const x = e.x ?? px;\n      const y = e.y ?? py;\n      const m = c.color.match(/^rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/);\n      const rgb = m ? `${m[1]}, ${m[2]}, ${m[3]}` : '255, 255, 255';\n      // Scale the blob to the measured element via `--pulse-glow-sx/sy` (same as\n      // the live stroke/core layers). The var only changes on resize, so the\n      // blurred bloom bitmap is still painted once and cached between resizes.\n      // Defaults to 1 (pulse-inner never sets it), leaving inner geometry as-is.\n      return `radial-gradient(ellipse calc(${e.w}px * var(--pulse-glow-sx, 1) * var(--pulse-glow-boost, 1)) calc(${e.h}px * var(--pulse-glow-sy, 1) * var(--pulse-glow-boost, 1)) at ${x} ${y}, rgba(${rgb}, ${a}), transparent)`;\n    })\n    .join(',\\n    ');\n}\n\n// Pauses every animation on an instance (wrapper + pseudo layers + bloom) when it\n// carries the `data-paused` attribute. Driven by an IntersectionObserver so beams\n// that are scrolled offscreen stop doing per-frame paint work entirely.\nfunction pausedAnimationsRule(id: string): string {\n  return `\n[data-beam=\"${id}\"][data-paused],\n[data-beam=\"${id}\"][data-paused]::after,\n[data-beam=\"${id}\"][data-paused]::before,\n[data-beam=\"${id}\"][data-paused] [data-beam-bloom] {\n  animation-play-state: paused !important;\n}`;\n}\n\n// @property registrations for all per-instance pulse custom properties.\nfunction pulsePropertyRegs(id: string): string {\n  const numbers = ['bw1', 'bh1', 'bw2', 'bh2', 'bw3', 'bh3', 'bgh', 'bop-tl', 'bop-tr', 'bop-bl', 'bop-br'];\n  const lengths = ['bx1', 'by1', 'bx2', 'by2', 'bx3', 'by3'];\n  const numReg = numbers\n    .map(\n      n => `@property --${n}-${id} {\\n  syntax: \"<number>\";\\n  initial-value: 1;\\n  inherits: true;\\n}`\n    )\n    .join('\\n\\n');\n  const lenReg = lengths\n    .map(\n      n => `@property --${n}-${id} {\\n  syntax: \"<length>\";\\n  initial-value: 0px;\\n  inherits: true;\\n}`\n    )\n    .join('\\n\\n');\n  return `${numReg}\\n\\n${lenReg}\\n\\n@property --beam-opacity-${id} {\\n  syntax: \"<number>\";\\n  initial-value: 0;\\n  inherits: true;\\n}\\n\\n@property --beam-hue-${id} {\\n  syntax: \"<angle>\";\\n  initial-value: 0deg;\\n  inherits: true;\\n}`;\n}\n\n// ── Pulse breathing driver ───────────────────────────────────────────────────\n// The breathing motion (size/drift/quadrant-opacity/height) and the slow hue\n// drift used to run as ~15 per-instance CSS `@property` keyframe animations at\n// the display refresh rate (60–120 Hz). Because each value feeds the painted\n// gradients/filters, that meant repainting the breathing layers 60–120×/sec.\n// The motion is very slow (1.6–6.4 s periods), so we instead drive the same CSS\n// vars from a single shared requestAnimationFrame loop throttled to ~30 fps\n// (see pulseDriver.ts). This halves the paint frequency on 60 Hz displays and\n// quarters it on 120 Hz, with no perceptible change to the breathing.\n\n/** A single sinusoidal oscillator that ping-pongs a CSS var between `a` and `b`. */\nexport interface PulseOscillatorDef {\n  prop: string;\n  a: number;\n  b: number;\n  /** Full period in seconds. */\n  period: number;\n  /** Phase offset in seconds (desyncs otherwise-identical oscillators). */\n  delay: number;\n  /** '' for unitless <number> vars, 'px' for <length> drift vars. */\n  unit: '' | 'px';\n}\n\nexport interface PulseDriverConfig {\n  oscillators: PulseOscillatorDef[];\n  /**\n   * Hue motion driven into `--beam-hue-<id>`; null when colors are static.\n   * `continuous` rotates a full 360° loop over `period` (so every palette color\n   * cycles through every edge for a lively, ever-changing wash); otherwise it\n   * ping-pongs between -range and +range.\n   */\n  hue: { prop: string; range: number; period: number; continuous?: boolean } | null;\n}\n\n/** Theme/size/duration-tuned breathing parameters (shared by CSS + JS driver). */\nexport function pulseParams(size: BorderBeamSize, theme: 'dark' | 'light', duration: number) {\n  const isDark = theme === 'dark';\n  const durScale = duration / 2.3;\n  if (size === 'pulse-inner') {\n    return {\n      sp: 0.28,\n      dr: isDark ? 33 : 40,\n      op: isDark ? 0.48 : 0.45,\n      gh: isDark ? 0.34 : 0.22,\n      bs: (isDark ? 1.9 : 2.6) * durScale,\n      ss: (isDark ? 2.6 : 4.6) * durScale,\n      ghs: (isDark ? 2.4 : 5.5) * durScale,\n      // Full hue revolution period (seconds) — colors continuously cycle.\n      huePeriod: 16,\n    };\n  }\n  return {\n    sp: isDark ? 0.28 : 0.36,\n    dr: isDark ? 14 : 19,\n    op: isDark ? 0.46 : 0,\n    gh: isDark ? 0.16 : 0.58,\n    bs: (isDark ? 2.3 : 3.7) * durScale,\n    ss: (isDark ? 6.4 : 4.6) * durScale,\n    ghs: (isDark ? 2.4 : 3.8) * durScale,\n    // Full hue revolution period (seconds) — colors continuously cycle.\n    huePeriod: 14,\n  };\n}\n\n/** Build the oscillator table for an instance (matches the former keyframes). */\nexport function pulseOscillatorDefs(id: string, p: ReturnType<typeof pulseParams>): PulseOscillatorDef[] {\n  const { sp, dr, op, gh, bs, ss, ghs } = p;\n  return [\n    { prop: `--bw1-${id}`, a: 1 - sp, b: 1 + sp * 1.1, period: ss * 0.9, delay: 0, unit: '' },\n    { prop: `--bh1-${id}`, a: 1 + sp * 0.9, b: 1 - sp * 0.85, period: ss * 1.26, delay: 0, unit: '' },\n    { prop: `--bx1-${id}`, a: -dr, b: dr * 0.9, period: bs * 1.6, delay: 0, unit: 'px' },\n    { prop: `--by1-${id}`, a: dr * 0.55, b: -dr * 0.7, period: bs * 1.6, delay: 0, unit: 'px' },\n    { prop: `--bw2-${id}`, a: 1 + sp, b: 1 - sp * 0.85, period: ss * 1.1, delay: 0, unit: '' },\n    { prop: `--bh2-${id}`, a: 1 - sp * 0.8, b: 1 + sp * 1.05, period: ss * 0.81, delay: 0, unit: '' },\n    { prop: `--bx2-${id}`, a: dr * 0.8, b: -dr * 0.9, period: bs * 1.88, delay: 0, unit: 'px' },\n    { prop: `--by2-${id}`, a: -dr, b: dr * 0.65, period: bs * 1.88, delay: 0, unit: 'px' },\n    { prop: `--bw3-${id}`, a: 1 - sp * 0.6, b: 1 + sp * 1.15, period: ss * 0.98, delay: 0, unit: '' },\n    { prop: `--bh3-${id}`, a: 1 + sp * 0.75, b: 1 - sp, period: ss * 1.4, delay: 0, unit: '' },\n    { prop: `--bx3-${id}`, a: -dr * 0.6, b: dr, period: bs * 1.45, delay: 0, unit: 'px' },\n    { prop: `--by3-${id}`, a: -dr * 0.85, b: dr * 0.45, period: bs * 1.45, delay: 0, unit: 'px' },\n    { prop: `--bgh-${id}`, a: 1 - gh, b: 1 + gh, period: ghs, delay: 0, unit: '' },\n    { prop: `--bop-tl-${id}`, a: 1 - op, b: 1, period: bs, delay: 0, unit: '' },\n    { prop: `--bop-tr-${id}`, a: 1 - op, b: 1, period: bs * 1.32, delay: bs * 0.28, unit: '' },\n    { prop: `--bop-bl-${id}`, a: 1 - op, b: 1, period: bs * 0.84, delay: bs * 0.55, unit: '' },\n    { prop: `--bop-br-${id}`, a: 1 - op, b: 1, period: bs * 1.58, delay: bs * 0.83, unit: '' },\n  ];\n}\n\n/**\n * Returns the runtime config the JS driver needs to animate a pulse instance,\n * or null for non-pulse sizes. Kept in sync with the CSS by sharing pulseParams.\n */\nexport function getPulseDriverConfig(\n  size: BorderBeamSize,\n  theme: 'dark' | 'light',\n  duration: number,\n  hueRange: number,\n  staticColors: boolean,\n  id: string\n): PulseDriverConfig | null {\n  if (size !== 'pulse-inner' && size !== 'pulse-outside') return null;\n  const p = pulseParams(size, theme, duration);\n  return {\n    oscillators: pulseOscillatorDefs(id, p),\n    // Pulse colors continuously rotate a full hue circle so the palette is never\n    // pinned to fixed edges (no more \"always red top-right / green left\").\n    hue: staticColors\n      ? null\n      : { prop: `--beam-hue-${id}`, range: 360, period: p.huePeriod, continuous: true },\n  };\n}\n\n// Only the (short, one-shot) fade is still a CSS animation; the breathing is\n// driven from JS so it can be frame-rate capped and paused offscreen.\nfunction pulseWrapperAnimation(id: string, fadeName: string, fadeDur: number): string {\n  return `  animation: ${fadeName}-${id} ${fadeDur}s ease forwards;`;\n}\n\ninterface GenerateStylesOptions {\n  id: string;\n  borderRadius: number;\n  borderWidth: number;\n  duration: number;\n  strokeOpacity: number;\n  innerOpacity: number;\n  bloomOpacity: number;\n  innerShadow: string;\n  size: BorderBeamSize;\n  colorVariant: BorderBeamColorVariant;\n  staticColors: boolean;\n  brightness: number;\n  saturation: number;\n  hueRange: number;\n  theme: 'dark' | 'light';\n  /** Opacity of the 1px hairline outline (pulse-outside only). Falls back to 0. */\n  hairlineOpacity?: number;\n  /** Multiplies every glow blur radius. Falls back to 1 (the tuned defaults). */\n  glowSize?: number;\n}\n\n/** Scales a tuned blur radius by `glowSize`, rounded to a sensible px step.\n *  Kept above 0 so a glow layer never collapses to a hard edge. */\nfunction scaleBlur(px: number, glowSize = 1): number {\n  return Math.max(0.5, Math.round(px * glowSize * 100) / 100);\n}\n\n/**\n * Generate complete CSS for a BorderBeam instance\n */\nexport function generateBeamCSS(options: GenerateStylesOptions): string {\n  const { size } = options;\n\n  if (size === 'line') {\n    return generateLineVariantCSS(options);\n  }\n  \n  if (size === 'sm') {\n    return generateSmallVariantCSS(options);\n  }\n\n  if (size === 'pulse-inner') {\n    return generatePulseInnerVariantCSS(options);\n  }\n\n  if (size === 'pulse-outside') {\n    return generatePulseOuterVariantCSS(options);\n  }\n\n  return generateBorderVariantCSS(options);\n}\n\nfunction generateSmallVariantCSS(options: GenerateStylesOptions): string {\n  const {\n    id,\n    borderRadius,\n    borderWidth,\n    duration,\n    strokeOpacity,\n    innerOpacity,\n    bloomOpacity,\n    innerShadow,\n    colorVariant,\n    staticColors,\n    brightness,\n    saturation,\n    hueRange,\n    theme,\n    glowSize = 1,\n  } = options;\n\n  const innerRadius = Math.max(0, borderRadius - borderWidth);\n  \n  const monoOpacityMultiplier = colorVariant === 'mono' ? 0.5 : 1.0;\n  const finalStrokeOpacity = strokeOpacity * monoOpacityMultiplier;\n  const finalInnerOpacity = innerOpacity * monoOpacityMultiplier;\n  const finalBloomOpacity = bloomOpacity * monoOpacityMultiplier;\n  \n  const hueShiftAnimation = staticColors \n    ? '' \n    : `animation: beam-hue-shift-${id} 12s ease-in-out infinite;`;\n  \n  const hueShiftKeyframes = staticColors ? '' : `\n@keyframes beam-hue-shift-${id} {\n  0% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) - ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n  50% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) + ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n  100% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) - ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n}`;\n\n  const isDark = theme === 'dark';\n  \n  const whiteGradient = isDark\n    ? `conic-gradient(\n        from var(--beam-angle-${id}),\n        transparent 0%, transparent 54%,\n        rgba(255, 255, 255, 0.1) 57%,\n        rgba(255, 255, 255, 0.3) 60%,\n        rgba(255, 255, 255, 0.6) 63%,\n        rgba(255, 255, 255, 0.75) 66%,\n        rgba(255, 255, 255, 0.6) 69%,\n        rgba(255, 255, 255, 0.3) 72%,\n        rgba(255, 255, 255, 0.1) 75%,\n        transparent 78%, transparent 100%\n      )`\n    : `conic-gradient(\n        from var(--beam-angle-${id}),\n        transparent 0%, transparent 54%,\n        rgba(0, 0, 0, 0.08) 57%,\n        rgba(0, 0, 0, 0.2) 60%,\n        rgba(0, 0, 0, 0.4) 63%,\n        rgba(0, 0, 0, 0.55) 66%,\n        rgba(0, 0, 0, 0.4) 69%,\n        rgba(0, 0, 0, 0.2) 72%,\n        rgba(0, 0, 0, 0.08) 75%,\n        transparent 78%, transparent 100%\n      )`;\n\n  const colorGradients = getSmallColorGradients(colorVariant);\n  const innerGradients = getSmallInnerGradients(colorVariant);\n\n  const bloomGradient = isDark\n    ? `conic-gradient(\n        from var(--beam-angle-${id}),\n        transparent 0%, transparent 58%,\n        rgba(255, 255, 255, 0.03) 62%,\n        rgba(255, 255, 255, 0.08) 65%,\n        rgba(255, 255, 255, 0.2) 67%,\n        rgba(255, 255, 255, 0.45) 69%,\n        rgba(255, 255, 255, 0.85) 70%,\n        rgba(255, 255, 255, 0.85) 70.5%,\n        rgba(255, 255, 255, 0.45) 71.5%,\n        rgba(255, 255, 255, 0.2) 73%,\n        rgba(255, 255, 255, 0.08) 75%,\n        rgba(255, 255, 255, 0.03) 78%,\n        transparent 82%\n      )`\n    : `conic-gradient(\n        from var(--beam-angle-${id}),\n        transparent 0%, transparent 58%,\n        rgba(0, 0, 0, 0.02) 62%,\n        rgba(0, 0, 0, 0.08) 65%,\n        rgba(0, 0, 0, 0.2) 67%,\n        rgba(0, 0, 0, 0.4) 69%,\n        rgba(0, 0, 0, 0.6) 70%,\n        rgba(0, 0, 0, 0.6) 70.5%,\n        rgba(0, 0, 0, 0.4) 71.5%,\n        rgba(0, 0, 0, 0.2) 73%,\n        rgba(0, 0, 0, 0.08) 75%,\n        rgba(0, 0, 0, 0.02) 78%,\n        transparent 82%\n      )`;\n\n  // Small variant uses wider mask to show more of the beam around the smaller element\n  const smallMask = `conic-gradient(\n    from var(--beam-angle-${id}),\n    transparent 0%, transparent 22%,\n    rgba(255, 255, 255, 0.12) 28%, rgba(255, 255, 255, 0.4) 36%,\n    white 46%, white 82%,\n    rgba(255, 255, 255, 0.4) 88%, rgba(255, 255, 255, 0.12) 94%,\n    transparent 97%, transparent 100%\n  )`;\n\n  return `\n@property --beam-angle-${id} {\n  syntax: \"<angle>\";\n  initial-value: 0deg;\n  inherits: true;\n}\n\n@property --beam-opacity-${id} {\n  syntax: \"<number>\";\n  initial-value: 0;\n  inherits: true;\n}\n\n[data-beam=\"${id}\"] {\n  position: relative;\n  border-radius: ${borderRadius}px;\n  overflow: hidden;\n}\n\n[data-beam=\"${id}\"][data-active] {\n  animation:\n    beam-spin-${id} ${duration}s linear infinite,\n    beam-fade-in-${id} 0.6s ease forwards;\n}\n\n[data-beam=\"${id}\"][data-fading] {\n  animation:\n    beam-spin-${id} ${duration}s linear infinite,\n    beam-fade-out-${id} 0.5s ease forwards;\n}\n\n[data-beam=\"${id}\"][data-active]::after,\n[data-beam=\"${id}\"][data-fading]::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${innerRadius}px;\n  padding: ${borderWidth}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${whiteGradient},${colorGradients};\n  -webkit-mask:\n    conic-gradient(\n      from var(--beam-angle-${id}),\n      transparent 0%, transparent 30%,\n      rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,\n      white 52%, white 80%,\n      rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,\n      transparent 95%, transparent 100%\n    ),\n    linear-gradient(#fff 0 0) content-box,\n    linear-gradient(#fff 0 0);\n  -webkit-mask-composite: source-in, xor;\n  mask:\n    conic-gradient(\n      from var(--beam-angle-${id}),\n      transparent 0%, transparent 30%,\n      rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,\n      white 52%, white 80%,\n      rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,\n      transparent 95%, transparent 100%\n    ),\n    linear-gradient(#fff 0 0) content-box,\n    linear-gradient(#fff 0 0);\n  mask-composite: intersect, exclude;\n  pointer-events: none;\n  z-index: 2;\n  opacity: calc(var(--beam-opacity-${id}) * ${finalStrokeOpacity.toFixed(2)} * var(--beam-stroke-opacity, 1) * var(--beam-strength, 1));\n  ${hueShiftAnimation}\n}\n\n[data-beam=\"${id}\"][data-active]::before,\n[data-beam=\"${id}\"][data-fading]::before {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${borderRadius}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${innerGradients};\n  box-shadow: inset 0 0 5px 1px ${innerShadow};\n  -webkit-mask-image: ${smallMask};\n  -webkit-mask-composite: source-over;\n  mask-image: ${smallMask};\n  mask-composite: add;\n  pointer-events: none;\n  z-index: 1;\n  opacity: calc(var(--beam-opacity-${id}) * ${finalInnerOpacity.toFixed(2)} * var(--beam-inner-opacity, 1) * var(--beam-strength, 1));\n  ${hueShiftAnimation}\n}\n\n[data-beam=\"${id}\"] [data-beam-bloom] {\n  display: none;\n  position: absolute;\n  inset: 0;\n  border-radius: ${innerRadius}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${bloomGradient};\n  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  -webkit-mask-composite: xor;\n  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  mask-composite: exclude;\n  padding: ${borderWidth}px;\n  filter: blur(${scaleBlur(8, glowSize)}px) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)});\n  pointer-events: none;\n  z-index: 3;\n  opacity: 0;\n}\n\n[data-beam=\"${id}\"][data-active] [data-beam-bloom],\n[data-beam=\"${id}\"][data-fading] [data-beam-bloom] {\n  display: block;\n  opacity: calc(var(--beam-opacity-${id}) * ${finalBloomOpacity.toFixed(2)} * var(--beam-bloom-opacity, 1) * var(--beam-strength, 1));\n}\n\n@keyframes beam-spin-${id} {\n  to { --beam-angle-${id}: 360deg; }\n}\n\n@keyframes beam-fade-in-${id} {\n  to { --beam-opacity-${id}: 1; }\n}\n\n@keyframes beam-fade-out-${id} {\n  from { --beam-opacity-${id}: 1; }\n  to { --beam-opacity-${id}: 0; }\n}\n${hueShiftKeyframes}\n${pausedAnimationsRule(id)}\n`;\n}\n\nfunction generateBorderVariantCSS(options: GenerateStylesOptions): string {\n  const {\n    id,\n    borderRadius,\n    borderWidth,\n    duration,\n    strokeOpacity,\n    innerOpacity,\n    bloomOpacity,\n    innerShadow,\n    colorVariant,\n    staticColors,\n    brightness,\n    saturation,\n    hueRange,\n    theme,\n    glowSize = 1,\n  } = options;\n\n  const innerRadius = Math.max(0, borderRadius - borderWidth);\n  \n  // Mono variant gets 50% lower opacity\n  const monoOpacityMultiplier = colorVariant === 'mono' ? 0.5 : 1.0;\n  const finalStrokeOpacity = strokeOpacity * monoOpacityMultiplier;\n  const finalInnerOpacity = innerOpacity * monoOpacityMultiplier;\n  const finalBloomOpacity = bloomOpacity * monoOpacityMultiplier;\n  \n  const hueShiftAnimation = staticColors \n    ? '' \n    : `animation: beam-hue-shift-${id} 12s ease-in-out infinite;`;\n  \n  const hueShiftKeyframes = staticColors ? '' : `\n@keyframes beam-hue-shift-${id} {\n  0% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) - ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n  50% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) + ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n  100% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) - ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n}`;\n\n  const isDark = theme === 'dark';\n  \n  const whiteGradient = isDark\n    ? `conic-gradient(\n        from var(--beam-angle-${id}),\n        transparent 0%, transparent 54%,\n        rgba(255, 255, 255, 0.1) 57%,\n        rgba(255, 255, 255, 0.3) 60%,\n        rgba(255, 255, 255, 0.6) 63%,\n        rgba(255, 255, 255, 0.75) 66%,\n        rgba(255, 255, 255, 0.6) 69%,\n        rgba(255, 255, 255, 0.3) 72%,\n        rgba(255, 255, 255, 0.1) 75%,\n        transparent 78%, transparent 100%\n      )`\n    : `conic-gradient(\n        from var(--beam-angle-${id}),\n        transparent 0%, transparent 54%,\n        rgba(0, 0, 0, 0.08) 57%,\n        rgba(0, 0, 0, 0.2) 60%,\n        rgba(0, 0, 0, 0.4) 63%,\n        rgba(0, 0, 0, 0.55) 66%,\n        rgba(0, 0, 0, 0.4) 69%,\n        rgba(0, 0, 0, 0.2) 72%,\n        rgba(0, 0, 0, 0.08) 75%,\n        transparent 78%, transparent 100%\n      )`;\n\n  const colorGradients = getColorGradients(colorVariant);\n  const innerGradients = getInnerGradients(colorVariant);\n\n  const bloomGradient = isDark\n    ? `conic-gradient(\n        from var(--beam-angle-${id}),\n        transparent 0%, transparent 58%,\n        rgba(255, 255, 255, 0.03) 62%,\n        rgba(255, 255, 255, 0.08) 65%,\n        rgba(255, 255, 255, 0.2) 67%,\n        rgba(255, 255, 255, 0.45) 69%,\n        rgba(255, 255, 255, 0.85) 70%,\n        rgba(255, 255, 255, 0.85) 70.5%,\n        rgba(255, 255, 255, 0.45) 71.5%,\n        rgba(255, 255, 255, 0.2) 73%,\n        rgba(255, 255, 255, 0.08) 75%,\n        rgba(255, 255, 255, 0.03) 78%,\n        transparent 82%\n      )`\n    : `conic-gradient(\n        from var(--beam-angle-${id}),\n        transparent 0%, transparent 58%,\n        rgba(0, 0, 0, 0.02) 62%,\n        rgba(0, 0, 0, 0.08) 65%,\n        rgba(0, 0, 0, 0.2) 67%,\n        rgba(0, 0, 0, 0.4) 69%,\n        rgba(0, 0, 0, 0.6) 70%,\n        rgba(0, 0, 0, 0.6) 70.5%,\n        rgba(0, 0, 0, 0.4) 71.5%,\n        rgba(0, 0, 0, 0.2) 73%,\n        rgba(0, 0, 0, 0.08) 75%,\n        rgba(0, 0, 0, 0.02) 78%,\n        transparent 82%\n      )`;\n\n  return `\n@property --beam-angle-${id} {\n  syntax: \"<angle>\";\n  initial-value: 0deg;\n  inherits: true;\n}\n\n@property --beam-opacity-${id} {\n  syntax: \"<number>\";\n  initial-value: 0;\n  inherits: true;\n}\n\n[data-beam=\"${id}\"] {\n  position: relative;\n  border-radius: ${borderRadius}px;\n  overflow: hidden;\n}\n\n[data-beam=\"${id}\"][data-active] {\n  animation:\n    beam-spin-${id} ${duration}s linear infinite,\n    beam-fade-in-${id} 0.6s ease forwards;\n}\n\n[data-beam=\"${id}\"][data-fading] {\n  animation:\n    beam-spin-${id} ${duration}s linear infinite,\n    beam-fade-out-${id} 0.5s ease forwards;\n}\n\n[data-beam=\"${id}\"][data-active]::after,\n[data-beam=\"${id}\"][data-fading]::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${innerRadius}px;\n  padding: ${borderWidth}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${whiteGradient},${colorGradients};\n  -webkit-mask:\n    conic-gradient(\n      from var(--beam-angle-${id}),\n      transparent 0%, transparent 30%,\n      rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,\n      white 52%, white 80%,\n      rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,\n      transparent 95%, transparent 100%\n    ),\n    linear-gradient(#fff 0 0) content-box,\n    linear-gradient(#fff 0 0);\n  -webkit-mask-composite: source-in, xor;\n  mask:\n    conic-gradient(\n      from var(--beam-angle-${id}),\n      transparent 0%, transparent 30%,\n      rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,\n      white 52%, white 80%,\n      rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,\n      transparent 95%, transparent 100%\n    ),\n    linear-gradient(#fff 0 0) content-box,\n    linear-gradient(#fff 0 0);\n  mask-composite: intersect, exclude;\n  pointer-events: none;\n  z-index: 2;\n  opacity: calc(var(--beam-opacity-${id}) * ${finalStrokeOpacity.toFixed(2)} * var(--beam-stroke-opacity, 1) * var(--beam-strength, 1));\n  ${hueShiftAnimation}\n}\n\n[data-beam=\"${id}\"][data-active]::before,\n[data-beam=\"${id}\"][data-fading]::before {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${borderRadius}px;\n  background: ${innerGradients};\n  box-shadow: inset 0 0 9px 1px ${innerShadow};\n  -webkit-mask-image:\n    conic-gradient(\n      from var(--beam-angle-${id}),\n      transparent 0%, transparent 30%,\n      rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,\n      white 52%, white 80%,\n      rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,\n      transparent 95%, transparent 100%\n    ),\n    linear-gradient(white, transparent 28px, transparent calc(100% - 28px), white),\n    linear-gradient(to right, white, transparent 28px, transparent calc(100% - 28px), white);\n  -webkit-mask-composite: source-in, source-over;\n  mask-image:\n    conic-gradient(\n      from var(--beam-angle-${id}),\n      transparent 0%, transparent 30%,\n      rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,\n      white 52%, white 80%,\n      rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,\n      transparent 95%, transparent 100%\n    ),\n    linear-gradient(white, transparent 28px, transparent calc(100% - 28px), white),\n    linear-gradient(to right, white, transparent 28px, transparent calc(100% - 28px), white);\n  mask-composite: intersect, add;\n  pointer-events: none;\n  z-index: 1;\n  opacity: calc(var(--beam-opacity-${id}) * ${finalInnerOpacity.toFixed(2)} * var(--beam-inner-opacity, 1) * var(--beam-strength, 1));\n  clip-path: inset(0 round ${borderRadius}px);\n  ${hueShiftAnimation}\n}\n\n[data-beam=\"${id}\"] [data-beam-bloom] {\n  display: none;\n  position: absolute;\n  inset: 0;\n  border-radius: ${innerRadius}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${bloomGradient};\n  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  -webkit-mask-composite: xor;\n  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  mask-composite: exclude;\n  padding: ${borderWidth}px;\n  filter: blur(${scaleBlur(8, glowSize)}px) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)});\n  pointer-events: none;\n  z-index: 3;\n  opacity: 0;\n}\n\n[data-beam=\"${id}\"][data-active] [data-beam-bloom],\n[data-beam=\"${id}\"][data-fading] [data-beam-bloom] {\n  display: block;\n  opacity: calc(var(--beam-opacity-${id}) * ${finalBloomOpacity.toFixed(2)} * var(--beam-bloom-opacity, 1) * var(--beam-strength, 1));\n}\n\n@keyframes beam-spin-${id} {\n  to { --beam-angle-${id}: 360deg; }\n}\n\n@keyframes beam-fade-in-${id} {\n  to { --beam-opacity-${id}: 1; }\n}\n\n@keyframes beam-fade-out-${id} {\n  from { --beam-opacity-${id}: 1; }\n  to { --beam-opacity-${id}: 0; }\n}\n${hueShiftKeyframes}\n${pausedAnimationsRule(id)}\n`;\n}\n\n/**\n * Pulse Inner — contained breathing glow (port of v5 Card 4).\n * A full colorful perimeter ring (::after), an inner perimeter glow with corner\n * accents (::before), and a soft blurred bloom, all clipped inside the element.\n */\nfunction generatePulseInnerVariantCSS(options: GenerateStylesOptions): string {\n  const {\n    id, borderRadius, borderWidth, duration,\n    strokeOpacity, innerOpacity, bloomOpacity,\n    colorVariant, staticColors, brightness, saturation, hueRange, theme,\n    glowSize = 1,\n  } = options;\n\n  const isDark = theme === 'dark';\n\n  const monoMul = colorVariant === 'mono' ? 0.5 : 1.0;\n  const sStroke = (strokeOpacity * monoMul).toFixed(2);\n  const sInner = (innerOpacity * monoMul).toFixed(2);\n  const sBloom = (bloomOpacity * monoMul).toFixed(2);\n\n  // Breathing parameters (theme-tuned). The motion itself is now driven from JS\n  // (see getPulseDriverConfig / pulseDriver.ts); only `op` is needed here to set\n  // the frozen bloom's average alpha.\n  const { op } = pulseParams('pulse-inner', theme, duration);\n  const bloomBlur = scaleBlur(8, glowSize);\n\n  const b = brightness.toFixed(2);\n  const s = saturation.toFixed(2);\n\n  // Slow hue drift is driven into --beam-hue-<id> by the JS loop (capped fps),\n  // so the breathing layers no longer repaint at the display refresh rate.\n  const ringAnim = staticColors\n    ? `filter: brightness(${b}) saturate(${s});`\n    : `filter: hue-rotate(calc(var(--beam-hue-base, 0deg) + var(--beam-hue-${id}))) brightness(${b}) saturate(${s});`;\n  // Bloom shares the SAME hue rotation as the ring so the wide glow and the tight\n  // ring stay color-synced. Gradients keep frozen opacity; only hue-rotate varies.\n  const bloomAnim = staticColors\n    ? `filter: blur(${bloomBlur}px) brightness(${b}) saturate(${s});`\n    : `filter: blur(${bloomBlur}px) hue-rotate(calc(var(--beam-hue-base, 0deg) + var(--beam-hue-${id}))) brightness(${b}) saturate(${s});`;\n\n  const ringGradients = pulseRingGradients(colorVariant, id);\n  const innerGradients = pulseInnerGradients(colorVariant, id, isDark);\n  // Frozen at the breathing time-average (midpoint of the [1-op, 1] opacity range).\n  const bloomGradients = pulseTableGradientsStatic(PULSE_INNER_BLOOM, colorVariant, 1 - op * 0.5);\n\n  return `\n${pulsePropertyRegs(id)}\n\n[data-beam=\"${id}\"] {\n  position: relative;\n  border-radius: ${borderRadius}px;\n  overflow: hidden;\n  isolation: isolate;\n}\n\n[data-beam=\"${id}\"][data-active] {\n${pulseWrapperAnimation(id, 'beam-fade-in', 0.6)}\n}\n\n[data-beam=\"${id}\"][data-fading] {\n${pulseWrapperAnimation(id, 'beam-fade-out', 0.5)}\n}\n\n[data-beam=\"${id}\"][data-active]::after,\n[data-beam=\"${id}\"][data-fading]::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${borderRadius}px;\n  padding: ${borderWidth}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${ringGradients};\n  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  -webkit-mask-composite: xor;\n  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  mask-composite: exclude;\n  pointer-events: none;\n  z-index: 2;\n  will-change: opacity, filter;\n  opacity: calc(var(--beam-opacity-${id}) * ${sStroke} * var(--beam-stroke-opacity, 1) * var(--beam-strength, 1));\n  ${ringAnim}\n}\n\n[data-beam=\"${id}\"][data-active]::before,\n[data-beam=\"${id}\"][data-fading]::before {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${borderRadius}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${innerGradients};\n  -webkit-mask-image:\n    linear-gradient(white, transparent 28px, transparent calc(100% - 28px), white),\n    linear-gradient(to right, white, transparent 28px, transparent calc(100% - 28px), white);\n  -webkit-mask-composite: source-over;\n  mask-image:\n    linear-gradient(white, transparent 28px, transparent calc(100% - 28px), white),\n    linear-gradient(to right, white, transparent 28px, transparent calc(100% - 28px), white);\n  mask-composite: add;\n  pointer-events: none;\n  z-index: 1;\n  will-change: opacity, filter;\n  opacity: calc(var(--beam-opacity-${id}) * ${sInner} * var(--beam-inner-opacity, 1) * var(--beam-strength, 1));\n  ${ringAnim}\n}\n\n[data-beam=\"${id}\"] [data-beam-bloom] {\n  display: none;\n  position: absolute;\n  inset: 0;\n  border-radius: ${borderRadius}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${bloomGradients};\n  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  -webkit-mask-composite: xor;\n  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  mask-composite: exclude;\n  padding: ${borderWidth}px;\n  pointer-events: none;\n  z-index: 3;\n  will-change: opacity;\n  opacity: 0;\n}\n\n[data-beam=\"${id}\"][data-active] [data-beam-bloom],\n[data-beam=\"${id}\"][data-fading] [data-beam-bloom] {\n  display: block;\n  opacity: calc(var(--beam-opacity-${id}) * ${sBloom} * var(--beam-bloom-opacity, 1) * var(--beam-strength, 1));\n  ${bloomAnim}\n}\n\n@keyframes beam-fade-in-${id} { to { --beam-opacity-${id}: 1; } }\n@keyframes beam-fade-out-${id} { from { --beam-opacity-${id}: 1; } to { --beam-opacity-${id}: 0; } }\n${pausedAnimationsRule(id)}\n\n@media (prefers-reduced-motion: reduce) {\n  [data-beam=\"${id}\"][data-active],\n  [data-beam=\"${id}\"][data-fading],\n  [data-beam=\"${id}\"][data-active]::after,\n  [data-beam=\"${id}\"][data-fading]::after,\n  [data-beam=\"${id}\"][data-active]::before,\n  [data-beam=\"${id}\"][data-fading]::before,\n  [data-beam=\"${id}\"][data-active] [data-beam-bloom],\n  [data-beam=\"${id}\"][data-fading] [data-beam-bloom] {\n    animation: none !important;\n  }\n}\n`;\n}\n\n/**\n * Pulse Outside — outward-blooming breathing glow (port of v5 Card 5).\n * A crisp 1px colored stroke hugs the outer edge (::after), while the colorful\n * core (::before) and soft halo (bloom) radiate OUTWARD behind the element\n * (z-index:-1), so the glow spills outside and is never cropped.\n *\n * Requires the wrapped child to be opaque so the inner part is covered and only\n * the outward halo shows.\n */\nfunction generatePulseOuterVariantCSS(options: GenerateStylesOptions): string {\n  const {\n    id, borderRadius, duration,\n    strokeOpacity, innerOpacity, bloomOpacity,\n    colorVariant, staticColors, brightness, saturation, hueRange, theme,\n    hairlineOpacity = 0,\n    glowSize = 1,\n  } = options;\n\n  const isDark = theme === 'dark';\n\n  const monoMul = colorVariant === 'mono' ? 0.5 : 1.0;\n  const sStroke = (strokeOpacity * monoMul).toFixed(2);\n  const sInner = (innerOpacity * monoMul).toFixed(2);\n  const sBloom = (bloomOpacity * monoMul).toFixed(2);\n\n  // A constant 1px hairline frames the element. It is painted on the inner 1px\n  // ring of the border-box (same place a standard `inset 0 0 0 1px` component\n  // border sits) so the beam hairline/stroke align with the wrapped element's\n  // own hairline instead of floating 1px outside it.\n  const hairRGB = isDark ? '70, 70, 70' : '0, 0, 0';\n  const hairOp = hairlineOpacity.toFixed(2);\n  const hairlineLine = `linear-gradient(rgba(${hairRGB}, ${hairOp}), rgba(${hairRGB}, ${hairOp}))`;\n\n  // Breathing parameters (theme-tuned). The motion is driven from JS now\n  // (getPulseDriverConfig / pulseDriver.ts); only `op` is needed here for the\n  // frozen bloom's average alpha.\n  const { op } = pulseParams('pulse-outside', theme, duration);\n\n  // Theme-dependent outward-glow constants (ported from v5 c6 defaults).\n  const sw = 0.95; // glow width size\n  const sh = 0.9; // glow height size (same in both themes)\n  const glowBlur = scaleBlur(isDark ? 3 : 6, glowSize);\n  const bloomBlur = scaleBlur(isDark ? 22.5 : 15, glowSize);\n\n  const b = brightness.toFixed(2);\n  const s = saturation.toFixed(2);\n\n  // Slow hue drift is driven into --beam-hue-<id> by the JS loop (capped fps).\n  const strokeAnim = staticColors\n    ? `filter: brightness(${b}) saturate(${s});`\n    : `filter: hue-rotate(calc(var(--beam-hue-base, 0deg) + var(--beam-hue-${id}))) brightness(${b}) saturate(${s});`;\n  // Consumer hooks (--beam-core-blur / --beam-bloom-blur / --beam-glow-brightness /\n  // --beam-glow-saturate) let integrators tune the glow WITHOUT overriding the whole\n  // `filter` — replacing it externally would drop the hue-rotate term and desync the\n  // glow colors from the stroke ring.\n  const glowBright = `brightness(var(--beam-glow-brightness, ${b})) saturate(var(--beam-glow-saturate, ${s}))`;\n  const coreAnim = staticColors\n    ? `filter: blur(var(--beam-core-blur, ${glowBlur}px)) ${glowBright};`\n    : `filter: blur(var(--beam-core-blur, ${glowBlur}px)) hue-rotate(calc(var(--beam-hue-base, 0deg) + var(--beam-hue-${id}))) ${glowBright};`;\n  // Bloom (large halo) shares the SAME hue rotation as the core/stroke so the\n  // wide glow and the tight glow stay in color sync (most visible on blue/green).\n  // Its gradients keep frozen opacity, so only the cheap hue-rotate varies.\n  const bloomAnim = staticColors\n    ? `filter: blur(var(--beam-bloom-blur, ${bloomBlur}px)) ${glowBright};`\n    : `filter: blur(var(--beam-bloom-blur, ${bloomBlur}px)) hue-rotate(calc(var(--beam-hue-base, 0deg) + var(--beam-hue-${id}))) ${glowBright};`;\n\n  const strokeGradients = pulseTableGradients(PULSE_OUTER_CORE, colorVariant, id);\n  const coreGradients = pulseTableGradients(PULSE_OUTER_CORE, colorVariant, id);\n  // Frozen at the breathing time-average (midpoint of the [1-op, 1] opacity range).\n  const bloomGradients = pulseTableGradientsStatic(PULSE_OUTER_BLOOM, colorVariant, 1 - op * 0.5);\n  // Paint a static hairline in the SAME masked ring as the stroke glow so their\n  // position and anti-aliasing always match exactly.\n  const strokeBackground = hairlineOpacity > 0\n    ? `${strokeGradients},\n    ${hairlineLine}`\n    : strokeGradients;\n\n  return `\n${pulsePropertyRegs(id)}\n\n[data-beam=\"${id}\"] {\n  position: relative;\n  border-radius: ${borderRadius}px;\n  overflow: visible;\n  isolation: isolate;\n}\n\n[data-beam=\"${id}\"][data-active] {\n${pulseWrapperAnimation(id, 'beam-fade-in', 0.6)}\n}\n\n[data-beam=\"${id}\"][data-fading] {\n${pulseWrapperAnimation(id, 'beam-fade-out', 0.5)}\n}\n${hairlineOpacity > 0 ? `\n/* Idle hairline — painted above the (opaque) child in the inner 1px edge ring so\n   it overlaps a standard inset component border exactly. */\n[data-beam=\"${id}\"]::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${borderRadius}px;\n  padding: 1px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${hairlineLine};\n  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  -webkit-mask-composite: xor;\n  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  mask-composite: exclude;\n  pointer-events: none;\n  z-index: 2;\n}\n` : ''}\n[data-beam=\"${id}\"][data-active]::after,\n[data-beam=\"${id}\"][data-fading]::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${borderRadius}px;\n  padding: 1px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${strokeBackground};\n  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  -webkit-mask-composite: xor;\n  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);\n  mask-composite: exclude;\n  pointer-events: none;\n  z-index: 2;\n  will-change: opacity, filter;\n  opacity: calc(var(--beam-opacity-${id}) * ${sStroke} * var(--beam-stroke-opacity, 1) * var(--beam-strength, 1));\n  ${strokeAnim}\n}\n\n[data-beam=\"${id}\"][data-active]::before,\n[data-beam=\"${id}\"][data-fading]::before {\n  content: \"\";\n  position: absolute;\n  inset: -10px;\n  z-index: -1;\n  border-radius: ${borderRadius + 10}px;\n  background: ${coreGradients};\n  transform: scale(${sw}, ${sh});\n  pointer-events: none;\n  will-change: opacity, filter;\n  opacity: calc(var(--beam-opacity-${id}) * ${sInner} * var(--beam-inner-opacity, 1) * var(--beam-strength, 1));\n  ${coreAnim}\n}\n\n[data-beam=\"${id}\"] [data-beam-bloom] {\n  display: none;\n  position: absolute;\n  inset: -30px;\n  z-index: -1;\n  border-radius: ${borderRadius + 30}px;\n  background: ${bloomGradients};\n  transform: scale(${sw}, ${sh});\n  pointer-events: none;\n  will-change: transform;\n  opacity: 0;\n}\n\n[data-beam=\"${id}\"][data-active] [data-beam-bloom],\n[data-beam=\"${id}\"][data-fading] [data-beam-bloom] {\n  display: block;\n  opacity: calc(var(--beam-opacity-${id}) * ${sBloom} * var(--beam-bloom-opacity, 1) * var(--beam-strength, 1));\n  ${bloomAnim}\n}\n\n@keyframes beam-fade-in-${id} { to { --beam-opacity-${id}: 1; } }\n@keyframes beam-fade-out-${id} { from { --beam-opacity-${id}: 1; } to { --beam-opacity-${id}: 0; } }\n${pausedAnimationsRule(id)}\n\n@media (prefers-reduced-motion: reduce) {\n  [data-beam=\"${id}\"][data-active],\n  [data-beam=\"${id}\"][data-fading],\n  [data-beam=\"${id}\"][data-active]::after,\n  [data-beam=\"${id}\"][data-fading]::after,\n  [data-beam=\"${id}\"][data-active]::before,\n  [data-beam=\"${id}\"][data-fading]::before,\n  [data-beam=\"${id}\"][data-active] [data-beam-bloom],\n  [data-beam=\"${id}\"][data-fading] [data-beam-bloom] {\n    animation: none !important;\n  }\n}\n`;\n}\n\nfunction generateLineVariantCSS(options: GenerateStylesOptions): string {\n  const {\n    id,\n    borderRadius,\n    borderWidth,\n    duration,\n    strokeOpacity,\n    innerOpacity,\n    bloomOpacity,\n    innerShadow,\n    colorVariant,\n    staticColors,\n    brightness,\n    saturation,\n    hueRange,\n    theme,\n    glowSize = 1,\n  } = options;\n\n  const innerRadius = Math.max(0, borderRadius - borderWidth);\n  const isDark = theme === 'dark';\n  \n  const finalStrokeOpacity = strokeOpacity;\n  const finalInnerOpacity = innerOpacity;\n  const finalBloomOpacity = bloomOpacity;\n  \n  const hueShiftAnimation = staticColors \n    ? '' \n    : `animation: beam-hue-shift-${id} 12s ease-in-out infinite;`;\n\n  const hueShiftBloomAnimation = staticColors\n    ? ''\n    : `animation: beam-hue-shift-bloom-${id} 8s ease-in-out infinite;`;\n  \n  const hueShiftKeyframes = staticColors ? '' : `\n@keyframes beam-hue-shift-${id} {\n  0% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) - ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n  50% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) + ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n  100% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) - ${hueRange}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n}\n\n@keyframes beam-hue-shift-bloom-${id} {\n  0% { filter: blur(${scaleBlur(8, glowSize)}px) hue-rotate(calc(var(--beam-hue-base, 0deg) - ${hueRange + 10}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n  50% { filter: blur(${scaleBlur(8, glowSize)}px) hue-rotate(calc(var(--beam-hue-base, 0deg) + ${hueRange + 10}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n  100% { filter: blur(${scaleBlur(8, glowSize)}px) hue-rotate(calc(var(--beam-hue-base, 0deg) - ${hueRange + 10}deg)) brightness(${brightness.toFixed(2)}) saturate(${saturation.toFixed(2)}); }\n}`;\n\n  const whiteHighlight = isDark\n    ? `radial-gradient(\n        ellipse calc(24px * var(--beam-w-${id})) calc(28px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) calc(100% + 2px),\n        rgba(255, 255, 255, 0.38) 0%,\n        rgba(255, 255, 255, 0.12) 30%,\n        transparent 65%\n      )`\n    : `radial-gradient(\n        ellipse calc(35px * var(--beam-w-${id})) calc(28px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) calc(100% + 2px),\n        rgba(0, 0, 0, 0.6) 0%,\n        rgba(0, 0, 0, 0.25) 35%,\n        transparent 70%\n      )`;\n\n  const colorGradients = getLineColorGradients(colorVariant, isDark, id);\n  const innerGradients = getLineInnerGradients(colorVariant, id);\n\n  const bloomGradients = getLineBloomGradients(colorVariant, isDark, id);\n  const monoBloomBlur = colorVariant === 'mono' ? 'filter: blur(6px);' : '';\n\n  return `\n@property --beam-x-${id} {\n  syntax: \"<number>\";\n  initial-value: 0;\n  inherits: true;\n}\n\n@property --beam-w-${id} {\n  syntax: \"<number>\";\n  initial-value: 1;\n  inherits: true;\n}\n\n@property --beam-h-${id} {\n  syntax: \"<number>\";\n  initial-value: 1;\n  inherits: true;\n}\n\n@property --beam-spike-${id} {\n  syntax: \"<number>\";\n  initial-value: 1;\n  inherits: true;\n}\n\n@property --beam-spike2-${id} {\n  syntax: \"<number>\";\n  initial-value: 1;\n  inherits: true;\n}\n\n@property --beam-edge-${id} {\n  syntax: \"<number>\";\n  initial-value: 1;\n  inherits: true;\n}\n\n@property --beam-opacity-${id} {\n  syntax: \"<number>\";\n  initial-value: 0;\n  inherits: true;\n}\n\n[data-beam=\"${id}\"] {\n  position: relative;\n  border-radius: ${borderRadius}px;\n  overflow: hidden;\n}\n\n[data-beam=\"${id}\"][data-active] {\n  animation:\n    beam-travel-${id} ${duration}s linear infinite,\n    beam-edge-fade-${id} ${duration}s linear infinite,\n    beam-breathe-${id} ${(duration * 1.3).toFixed(1)}s ease-in-out infinite,\n    beam-spike-${id} ${(duration * 1.33).toFixed(1)}s ease-in-out infinite,\n    beam-spike2-${id} ${(duration * 1.7).toFixed(1)}s ease-in-out infinite,\n    beam-fade-in-${id} 0.6s ease forwards;\n}\n\n[data-beam=\"${id}\"][data-fading] {\n  animation:\n    beam-travel-${id} ${duration}s linear infinite,\n    beam-edge-fade-${id} ${duration}s linear infinite,\n    beam-breathe-${id} ${(duration * 1.3).toFixed(1)}s ease-in-out infinite,\n    beam-spike-${id} ${(duration * 1.33).toFixed(1)}s ease-in-out infinite,\n    beam-spike2-${id} ${(duration * 1.7).toFixed(1)}s ease-in-out infinite,\n    beam-fade-out-${id} 0.5s ease forwards;\n}\n\n[data-beam=\"${id}\"][data-active]::after,\n[data-beam=\"${id}\"][data-fading]::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${innerRadius}px;\n  padding: ${borderWidth}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  background: ${whiteHighlight}, ${colorGradients};\n  -webkit-mask:\n    radial-gradient(\n      ellipse calc(78px * var(--beam-w-${id})) calc(60px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) 100%,\n      white 0%, rgba(255, 255, 255, 0.5) 45%, transparent 100%\n    ),\n    linear-gradient(#fff 0 0) content-box,\n    linear-gradient(#fff 0 0);\n  -webkit-mask-composite: source-in, xor;\n  mask:\n    radial-gradient(\n      ellipse calc(78px * var(--beam-w-${id})) calc(60px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) 100%,\n      white 0%, rgba(255, 255, 255, 0.5) 45%, transparent 100%\n    ),\n    linear-gradient(#fff 0 0) content-box,\n    linear-gradient(#fff 0 0);\n  mask-composite: intersect, exclude;\n  pointer-events: none;\n  z-index: 2;\n  opacity: calc(var(--beam-opacity-${id}) * var(--beam-edge-${id}) * ${finalStrokeOpacity.toFixed(2)} * var(--beam-stroke-opacity, 1) * var(--beam-strength, 1));\n  ${hueShiftAnimation}\n}\n\n[data-beam=\"${id}\"][data-active]::before,\n[data-beam=\"${id}\"][data-fading]::before {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  border-radius: ${borderRadius}px;\n  background: ${innerGradients};\n  box-shadow: inset 0 0 9px 1px ${innerShadow};\n  -webkit-mask-image:\n    radial-gradient(\n      ellipse calc(78px * var(--beam-w-${id})) calc(60px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) 100%,\n      white 0%, rgba(255, 255, 255, 0.5) 45%, transparent 100%\n    ),\n    linear-gradient(white, transparent 28px, transparent calc(100% - 28px), white),\n    linear-gradient(to right, white, transparent 28px, transparent calc(100% - 28px), white);\n  -webkit-mask-composite: source-in, source-over;\n  mask-image:\n    radial-gradient(\n      ellipse calc(78px * var(--beam-w-${id})) calc(60px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) 100%,\n      white 0%, rgba(255, 255, 255, 0.5) 45%, transparent 100%\n    ),\n    linear-gradient(white, transparent 28px, transparent calc(100% - 28px), white),\n    linear-gradient(to right, white, transparent 28px, transparent calc(100% - 28px), white);\n  mask-composite: intersect, add;\n  pointer-events: none;\n  z-index: 1;\n  opacity: calc(var(--beam-opacity-${id}) * var(--beam-edge-${id}) * ${finalInnerOpacity.toFixed(2)} * var(--beam-inner-opacity, 1) * var(--beam-strength, 1));\n  clip-path: inset(0 round ${borderRadius}px);\n  ${hueShiftAnimation}\n}\n\n[data-beam=\"${id}\"] [data-beam-bloom] {\n  display: none;\n  position: absolute;\n  inset: 0;\n  border-radius: ${innerRadius}px;\n  clip-path: inset(0 round ${borderRadius}px);\n  padding: 0;\n  -webkit-mask: radial-gradient(\n    ellipse calc(84px * var(--beam-w-${id})) calc(110px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) 100%,\n    white 0%, rgba(255, 255, 255, 0.5) 35%, transparent 100%\n  );\n  -webkit-mask-composite: source-over;\n  mask: radial-gradient(\n    ellipse calc(84px * var(--beam-w-${id})) calc(110px * var(--beam-h-${id})) at calc(var(--beam-x-${id}) * 100%) 100%,\n    white 0%, rgba(255, 255, 255, 0.5) 35%, transparent 100%\n  );\n  mask-composite: add;\n  background: ${bloomGradients};\n  ${monoBloomBlur}\n  pointer-events: none;\n  z-index: 3;\n  opacity: 0;\n}\n\n[data-beam=\"${id}\"][data-active] [data-beam-bloom],\n[data-beam=\"${id}\"][data-fading] [data-beam-bloom] {\n  display: block;\n  opacity: calc(var(--beam-opacity-${id}) * var(--beam-edge-${id}) * ${finalBloomOpacity.toFixed(2)} * var(--beam-bloom-opacity, 1) * var(--beam-strength, 1));\n  ${hueShiftBloomAnimation}\n}\n\n@keyframes beam-travel-${id} {\n  0%   { --beam-x-${id}: 0.06;  --beam-w-${id}: 0.5; }\n  10%  { --beam-x-${id}: 0.15;  --beam-w-${id}: 0.8; }\n  20%  { --beam-x-${id}: 0.25;  --beam-w-${id}: 1.1; }\n  30%  { --beam-x-${id}: 0.35;  --beam-w-${id}: 1.3; }\n  40%  { --beam-x-${id}: 0.44;  --beam-w-${id}: 1.45; }\n  50%  { --beam-x-${id}: 0.5;   --beam-w-${id}: 1.5; }\n  60%  { --beam-x-${id}: 0.56;  --beam-w-${id}: 1.45; }\n  70%  { --beam-x-${id}: 0.65;  --beam-w-${id}: 1.3; }\n  80%  { --beam-x-${id}: 0.75;  --beam-w-${id}: 1.1; }\n  90%  { --beam-x-${id}: 0.85;  --beam-w-${id}: 0.8; }\n  100% { --beam-x-${id}: 0.94;  --beam-w-${id}: 0.5; }\n}\n\n@keyframes beam-edge-fade-${id} {\n  0%    { --beam-edge-${id}: 0; }\n  12.5% { --beam-edge-${id}: 0; }\n  32.5% { --beam-edge-${id}: 1; }\n  67.5% { --beam-edge-${id}: 1; }\n  87.5% { --beam-edge-${id}: 0; }\n  100%  { --beam-edge-${id}: 0; }\n}\n\n@keyframes beam-breathe-${id} {\n  0%, 100% { --beam-h-${id}: 0.8; }\n  25%      { --beam-h-${id}: 1.25; }\n  55%      { --beam-h-${id}: 0.85; }\n  80%      { --beam-h-${id}: 1.3; }\n}\n\n@keyframes beam-spike-${id} {\n  0%   { --beam-spike-${id}: 0.8; }\n  25%  { --beam-spike-${id}: 1.3; }\n  50%  { --beam-spike-${id}: 0.9; }\n  75%  { --beam-spike-${id}: 1.4; }\n  100% { --beam-spike-${id}: 0.8; }\n}\n\n@keyframes beam-spike2-${id} {\n  0%   { --beam-spike2-${id}: 1.2; }\n  25%  { --beam-spike2-${id}: 0.7; }\n  50%  { --beam-spike2-${id}: 1.4; }\n  75%  { --beam-spike2-${id}: 0.8; }\n  100% { --beam-spike2-${id}: 1.2; }\n}\n\n@keyframes beam-fade-in-${id} {\n  to { --beam-opacity-${id}: 1; }\n}\n\n@keyframes beam-fade-out-${id} {\n  from { --beam-opacity-${id}: 1; }\n  to { --beam-opacity-${id}: 0; }\n}\n${hueShiftKeyframes}\n${pausedAnimationsRule(id)}\n`;\n}\n"
        },
        {
          "path": "components/effects/border-beam/upstream/pulseDriver.ts",
          "target": "@components/effects/border-beam/upstream/pulseDriver.ts",
          "type": "registry:component",
          "content": "import type { PulseDriverConfig } from './styles';\n\n/**\n * Shared breathing driver for the Pulse effects.\n *\n * The pulse breathing (size / drift / per-quadrant opacity / height) and the\n * slow hue drift used to run as ~15 per-instance CSS `@property` keyframe\n * animations at the display refresh rate (60–120 Hz). Because each value feeds\n * the painted gradients/filters, that repainted the breathing layers 60–120×/s.\n *\n * The motion is very slow (1.6–6.4 s periods), so instead every registered\n * instance is driven from a SINGLE shared requestAnimationFrame loop throttled\n * to ~30 fps. This halves the paint frequency on 60 Hz displays and quarters it\n * on 120 Hz, with no perceptible change to the breathing.\n *\n * Each oscillator ping-pongs a CSS custom property between `a` and `b` with an\n * ease-in-out (cosine) curve over `period` seconds, offset by `delay` seconds so\n * otherwise-identical oscillators desync (matching the former CSS keyframes +\n * animation-delay).\n */\n\ninterface PulseInstance {\n  el: HTMLElement;\n  config: PulseDriverConfig;\n}\n\nconst instances = new Set<PulseInstance>();\nlet rafId: number | null = null;\nlet lastFrame = 0;\n\n// ~30 fps. Subtract a small slack so a frame that lands a hair early still runs.\nconst FRAME_INTERVAL = 1000 / 30 - 2;\n\nconst TWO_PI = Math.PI * 2;\n\nfunction now(): number {\n  return typeof performance !== 'undefined' ? performance.now() : Date.now();\n}\n\n/** Cosine ease-in-out factor in [0, 1]: 0 at phase 0/1, 1 at phase 0.5. */\nfunction pingPong(phase: number): number {\n  return (1 - Math.cos(TWO_PI * phase)) / 2;\n}\n\nfunction frame(ts: number): void {\n  rafId = requestAnimationFrame(frame);\n\n  if (ts - lastFrame < FRAME_INTERVAL) return;\n  lastFrame = ts;\n\n  const tSec = ts / 1000;\n\n  instances.forEach(({ el, config }) => {\n    for (const osc of config.oscillators) {\n      // Match CSS animation-delay semantics: a positive delay starts later.\n      const phase = (tSec - osc.delay) / osc.period;\n      const value = osc.a + (osc.b - osc.a) * pingPong(phase);\n      el.style.setProperty(\n        osc.prop,\n        osc.unit === 'px' ? `${value.toFixed(2)}px` : value.toFixed(4)\n      );\n    }\n\n    if (config.hue) {\n      const { prop, range, period, continuous } = config.hue;\n      // `continuous` rotates a full circle (0→range, looping) so every color\n      // sweeps through every edge; otherwise drift between -range and +range.\n      const value = continuous\n        ? ((tSec / period) % 1) * range\n        : -range + 2 * range * pingPong(tSec / period);\n      el.style.setProperty(prop, `${value.toFixed(2)}deg`);\n    }\n  });\n}\n\nfunction startLoop(): void {\n  if (rafId == null) {\n    lastFrame = 0;\n    rafId = requestAnimationFrame(frame);\n  }\n}\n\nfunction stopLoopIfIdle(): void {\n  if (instances.size === 0 && rafId != null) {\n    cancelAnimationFrame(rafId);\n    rafId = null;\n  }\n}\n\n/**\n * Register an element to be driven by the shared pulse loop.\n *\n * @returns a cleanup function that unregisters the instance (and stops the\n *          shared loop once no instances remain).\n */\nexport function registerPulseInstance(\n  el: HTMLElement,\n  config: PulseDriverConfig\n): () => void {\n  const instance: PulseInstance = { el, config };\n  instances.add(instance);\n  startLoop();\n\n  return () => {\n    instances.delete(instance);\n    stopLoopIfIdle();\n  };\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/effects/border-beam/LICENSE",
          "target": "@components/effects/border-beam/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Jakub Antalik\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/effects/border-beam/SOURCE.json",
          "target": "@components/effects/border-beam/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"border-beam\",\n  \"repository\": \"https://github.com/Jakubantalik/Libraries.dev\",\n  \"revision\": \"422180dd7a5ac646c85deedc65500c4a74339127\",\n  \"packageVersion\": \"1.4.0\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Jakub Antalik\",\n  \"copiedPath\": \"upstream/\",\n  \"copiedFiles\": [\n    \"packages/border-beam/src/BorderBeam.tsx\",\n    \"packages/border-beam/src/index.ts\",\n    \"packages/border-beam/src/pulseDriver.ts\",\n    \"packages/border-beam/src/styles.ts\",\n    \"packages/border-beam/src/types.ts\"\n  ],\n  \"relationship\": \"Source-faithful copy of the pinned public React package. The top-level client facade retains the complete props API and sets restrained mono, automatic-theme, and 0.6-strength defaults.\"\n}\n"
        }
      ],
      "categories": [
        "Libraries.dev"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "img-fx",
      "type": "registry:block",
      "title": "Img Fx",
      "description": "img fx",
      "dependencies": [
        "tailwindcss@^4.1.7",
        "three@0.149.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/effects/img-fx.tsx",
          "target": "@components/effects/img-fx.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nexport * from \"./img-fx/upstream\"\n"
        },
        {
          "path": "components/effects/img-fx/upstream/index.ts",
          "target": "@components/effects/img-fx/upstream/index.ts",
          "type": "registry:component",
          "content": "export { ImageGeneration } from './ImageGeneration';\n\nexport type {\n  ImageGenerationCycleEvent,\n  ImageGenerationHandle,\n  ImageGenerationPreset,\n  ImageGenerationProps,\n  ImageGenerationTheme\n} from './types';\n\nexport {\n  PRESETS,\n  hexToRgb,\n  parseCssColor,\n  type EasingKey,\n  type MaskShape,\n  type MosaicConfig,\n  type Preset,\n  type PresetMode,\n  type PresetName,\n  type PresetTheme,\n  type RevealConfig\n} from './presets';\n\n// Power-user surface: expose the engine primitives so consumers can drive the\n// renderer + reveal pipeline without React.\nexport {\n  createCycle,\n  createInstance,\n  createReveal,\n  destroyInstance,\n  ease,\n  effectiveCardBg,\n  getFrameRate,\n  getMaxDpr,\n  loadImage,\n  pickRandomImage,\n  samplePaletteFromCanvas,\n  setFrameRate,\n  setInstanceCardBg,\n  setInstanceColors,\n  setInstancePaused,\n  setInstancePreset,\n  setInstanceStrength,\n  setInstanceVisible,\n  setMaxDpr,\n  setSharedFragmentShader,\n  IMAGE_FRAGMENT_SHADER,\n  updateInstanceSize,\n  type CreateInstanceOptions,\n  type CreateRevealOptions,\n  type Cycle,\n  type CycleEvent,\n  type CycleOptions,\n  type CyclePhase,\n  type EaseFn,\n  type Instance,\n  type RevealState,\n  type RevealStartOptions,\n  type SampledPalette\n} from './engine';\n"
        },
        {
          "path": "components/effects/img-fx/upstream/ImageGeneration.tsx",
          "target": "@components/effects/img-fx/upstream/ImageGeneration.tsx",
          "type": "registry:component",
          "content": "import {\n  forwardRef,\n  useEffect,\n  useImperativeHandle,\n  useLayoutEffect,\n  useMemo,\n  useRef,\n  useState,\n  type CSSProperties\n} from 'react';\nimport {\n  createCycle,\n  createInstance,\n  createReveal,\n  destroyInstance,\n  renderInstanceOnce,\n  samplePaletteFromCanvas,\n  setInstanceCardBg,\n  setInstanceColors,\n  setInstancePaused,\n  setInstancePixelScale,\n  setInstancePreset,\n  setInstanceSpeed,\n  setInstanceStrength,\n  setInstanceVisible,\n  setSharedFragmentShader,\n  updateInstanceSize,\n  type Cycle,\n  type Instance,\n  type RevealState,\n  type SampledPalette\n} from './engine';\nimport { PRESETS } from './presets';\nimport { ensureStylesInjected } from './styles';\nimport type {\n  ImageGenerationHandle,\n  ImageGenerationPreset,\n  ImageGenerationProps,\n  ImageGenerationTheme\n} from './types';\n\nensureStylesInjected();\n\n/**\n * Resolve `'auto'` to a concrete `'dark' | 'light'` value, checking sources in\n * priority order so the library plays nicely with the most common app-side\n * theme conventions (not just the OS-level media query):\n *\n *   1. `<html data-theme=\"dark|light\">`          — shadcn / many SSR apps\n *   2. `<html class=\"dark\">` / `class=\"light\">`  — Tailwind v3 darkMode: class\n *   3. `<html style=\"color-scheme: dark\">`       — CSS-only theme toggles\n *   4. `matchMedia('(prefers-color-scheme: dark)')` — OS / browser preference\n *   5. Default `'dark'`                          — SSR-safe fallback\n *\n * Live updates: subscribed to both the matchMedia change event AND a\n * MutationObserver on `<html>` for `class` / `style` / `data-theme` changes,\n * so toggling a theme-class via JS reflects in the shader without remount.\n */\nfunction detectTheme(): 'dark' | 'light' {\n  if (typeof document === 'undefined') return 'dark';\n  const html = document.documentElement;\n\n  const dataTheme = html.getAttribute('data-theme');\n  if (dataTheme === 'dark' || dataTheme === 'light') return dataTheme;\n\n  if (html.classList.contains('dark')) return 'dark';\n  if (html.classList.contains('light')) return 'light';\n\n  const colorScheme = html.style.colorScheme || getComputedStyle(html).colorScheme;\n  if (colorScheme === 'dark') return 'dark';\n  if (colorScheme === 'light') return 'light';\n\n  if (typeof window !== 'undefined' && window.matchMedia) {\n    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n  }\n  return 'dark';\n}\n\nfunction useResolvedTheme(theme: ImageGenerationTheme): 'dark' | 'light' {\n  const [resolved, setResolved] = useState<'dark' | 'light'>(() => {\n    if (theme !== 'auto') return theme;\n    return detectTheme();\n  });\n\n  useEffect(() => {\n    if (theme !== 'auto') {\n      setResolved(theme);\n      return;\n    }\n    if (typeof window === 'undefined') return;\n\n    const update = (): void => setResolved(detectTheme());\n    update();\n\n    const mql = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;\n    mql?.addEventListener('change', update);\n\n    let mo: MutationObserver | null = null;\n    if (typeof document !== 'undefined' && typeof MutationObserver !== 'undefined') {\n      mo = new MutationObserver(update);\n      mo.observe(document.documentElement, {\n        attributes: true,\n        attributeFilter: ['class', 'style', 'data-theme']\n      });\n    }\n\n    return () => {\n      mql?.removeEventListener('change', update);\n      mo?.disconnect();\n    };\n  }, [theme]);\n\n  return resolved;\n}\n\nfunction normaliseImages(input: string | string[] | undefined): string[] {\n  if (!input) return [];\n  if (typeof input === 'string') return [input];\n  return input.slice();\n}\n\n/** The regenerate churn always runs on one of these pixel-mosaic presets. */\nconst PIXEL_CHURN_PRESETS = ['pixels-mechanic', 'pixels-organic'] as const;\n\ntype PixelChurnPreset = (typeof PIXEL_CHURN_PRESETS)[number];\n\nfunction isPixelChurnPreset(name: ImageGenerationPreset): name is PixelChurnPreset {\n  return (PIXEL_CHURN_PRESETS as readonly string[]).includes(name);\n}\n\nexport const ImageGeneration = forwardRef<ImageGenerationHandle, ImageGenerationProps>(function ImageGeneration(\n  {\n    children,\n    preset = 'pixels-organic',\n    theme = 'auto',\n    strength = 1,\n    speed = 1,\n    pixelScale = 1,\n    cardBg: cardBgProp,\n    colors,\n    images,\n    autoReveal = false,\n    revealDelayRange = [2, 4],\n    revealInitialDelay,\n    revealHoldMs = 2000,\n    revealFadeOutMs = 300,\n    borderRadius,\n    paused = false,\n    fragmentShader,\n    onCycle,\n    excludeSrcs,\n    className,\n    style,\n    ...rest\n  },\n  forwardedRef\n) {\n  const rootRef = useRef<HTMLDivElement | null>(null);\n  const shaderCanvasRef = useRef<HTMLCanvasElement | null>(null);\n  const overlayCanvasRef = useRef<HTMLCanvasElement | null>(null);\n  const contentRef = useRef<HTMLDivElement | null>(null);\n  const instanceRef = useRef<Instance | null>(null);\n  const revealRef = useRef<RevealState | null>(null);\n  const cycleRef = useRef<Cycle | null>(null);\n  const onCycleRef = useRef(onCycle);\n  const excludeSrcsRef = useRef(excludeSrcs);\n\n  // Transient image-derived recolor for the regenerate churn. While set, it\n  // overrides the palette + card surface (shader uniforms AND the wrapper's\n  // CSS background) so the effect wears the outgoing image's colors; cleared\n  // automatically when the next image reaches `visible`.\n  const [regenTint, setRegenTint] = useState<SampledPalette | null>(null);\n\n  // Transient preset override for the regenerate churn. The churn must always\n  // run on a pixel-mosaic preset (`pixels-mechanic` / `pixels-organic`): when\n  // the active preset is not one of those (e.g. `sweep-gradient`), a random\n  // pixel preset is swapped onto the instance for the churn's duration and\n  // the authored preset is restored once the next image is fully visible.\n  const [regenPresetName, setRegenPresetName] = useState<ImageGenerationPreset | null>(null);\n\n  useImperativeHandle(\n    forwardedRef,\n    () => ({\n      get element() {\n        return rootRef.current;\n      },\n      triggerReveal(opts) {\n        cycleRef.current?.triggerOnce(opts);\n      },\n      triggerHide() {\n        cycleRef.current?.triggerHide();\n      },\n      triggerRegenerate(opts) {\n        const cycle = cycleRef.current;\n        if (!cycle || pausedRef.current) return;\n        const phase = cycle.getPhase();\n        if (phase !== 'reveal' && phase !== 'visible') return;\n        // The churn always runs on a pixel-mosaic preset: keep the active\n        // preset when it's already one, otherwise (e.g. sweep-gradient)\n        // temporarily switch the instance to a random pixel preset. The\n        // authored preset is restored when the next image reaches `visible`.\n        const activePreset = presetRef.current;\n        const churnName = isPixelChurnPreset(activePreset)\n          ? null\n          : PIXEL_CHURN_PRESETS[Math.floor(Math.random() * PIXEL_CHURN_PRESETS.length)];\n        // Recolor the effect from the visible image (overlay canvas) so the\n        // churn showing through the dropped cells reads as pixelation born\n        // from that image rather than the preset's stock palette. The sample\n        // maps onto the CHURN preset's palette slots (the preset actually\n        // rendering during the churn), not the outgoing preset's.\n        if (opts?.tintFromImage ?? true) {\n          const overlay = overlayCanvasRef.current;\n          if (overlay) {\n            const churnColors = churnName\n              ? PRESETS[churnName].modes[resolvedThemeRef.current].colors\n              : presetModeRef.current.colors;\n            const sampled = samplePaletteFromCanvas(overlay, churnColors);\n            if (sampled) setRegenTint(sampled);\n          }\n        }\n        if (churnName) setRegenPresetName(churnName);\n        const autoReveal = opts?.autoReveal ?? true;\n        cycle.triggerBoil(\n          autoReveal ? { autoRevealAfterMs: opts?.durationMs ?? 4000 } : undefined\n        );\n      },\n      isImageActive() {\n        const phase = cycleRef.current?.getPhase() ?? 'idle';\n        return phase === 'reveal' || phase === 'visible' || phase === 'hide';\n      }\n    }),\n    []\n  );\n  useLayoutEffect(() => {\n    ensureStylesInjected();\n  }, []);\n\n  // Keep the latest callbacks live without re-subscribing the cycle.\n  useEffect(() => {\n    onCycleRef.current = onCycle;\n  }, [onCycle]);\n  useEffect(() => {\n    excludeSrcsRef.current = excludeSrcs;\n  }, [excludeSrcs]);\n\n  const resolvedTheme = useResolvedTheme(theme);\n  const presetMode = useMemo(() => PRESETS[preset].modes[resolvedTheme], [preset, resolvedTheme]);\n  // Effective background colour (override > preset). Drives both the wrapper's\n  // CSS background and the shader's `u_cardBg` uniform so contrast logic in\n  // the shader stays in sync with the actual host card surface.\n  const cardBg = cardBgProp ?? presetMode.cardBg;\n\n  // Live refs for the imperative `triggerRegenerate` (its handle is created\n  // once with empty deps, so it must read current values through refs).\n  const presetModeRef = useRef(presetMode);\n  presetModeRef.current = presetMode;\n  const presetRef = useRef(preset);\n  presetRef.current = preset;\n  const resolvedThemeRef = useRef(resolvedTheme);\n  resolvedThemeRef.current = resolvedTheme;\n  const pausedRef = useRef(paused);\n  pausedRef.current = paused;\n\n  // Normalised image pool + refs holding the latest cycle inputs so the\n  // mount-only lifecycle effect can read them when constructing the cycle.\n  // (The cycle itself is created in the lifecycle effect so manual\n  // `triggerReveal()` works regardless of the `autoReveal` flag.)\n  const imagesArr = useMemo(() => normaliseImages(images), [images]);\n  const imagesArrRef = useRef(imagesArr);\n  const revealDelayRangeRef = useRef(revealDelayRange);\n  const revealHoldMsRef = useRef(revealHoldMs);\n  const revealFadeOutMsRef = useRef(revealFadeOutMs);\n  imagesArrRef.current = imagesArr;\n  revealDelayRangeRef.current = revealDelayRange;\n  revealHoldMsRef.current = revealHoldMs;\n  revealFadeOutMsRef.current = revealFadeOutMs;\n\n  // Resolve `revealInitialDelay` into a stable ms value at mount time.\n  // Range tuples randomise ONCE here so re-renders never reseed the value.\n  // biome-ignore lint/correctness/useExhaustiveDependencies: intentional one-shot resolution at mount\n  const initialDelayMsRef = useRef<number | undefined>(\n    useMemo(() => {\n      if (revealInitialDelay == null) return undefined;\n      if (typeof revealInitialDelay === 'number') {\n        return Math.max(0, revealInitialDelay) * 1000;\n      }\n      const [min, max] = revealInitialDelay;\n      const lo = Math.max(0, Math.min(min, max));\n      const hi = Math.max(0, Math.max(min, max));\n      return (lo + Math.random() * (hi - lo)) * 1000;\n    }, [])\n  );\n\n  // Lifecycle: create instance + reveal on mount, destroy on unmount.\n  // biome-ignore lint/correctness/useExhaustiveDependencies: stable lifecycle effect; preset / theme syncs handled separately\n  useLayoutEffect(() => {\n    const root = rootRef.current;\n    const shader = shaderCanvasRef.current;\n    const overlay = overlayCanvasRef.current;\n    if (!root || !shader || !overlay) return;\n\n    // Dynamic measure: size from the root's bounding box and corner radius\n    // from the wrapped child's computed style (falls back to the root if the\n    // child has none). The shader can only render a single uniform corner\n    // radius, so we sample `borderTopLeftRadius` and apply it on all four\n    // corners — matches how the canvases inherit border-radius from the root.\n    const measure = (): { w: number; h: number; r: number } => {\n      const rect = root.getBoundingClientRect();\n      const w = Math.max(1, Math.round(rect.width));\n      const h = Math.max(1, Math.round(rect.height));\n      let r = 0;\n      if (typeof borderRadius === 'number') {\n        r = borderRadius;\n      } else {\n        const childEl = contentRef.current?.firstElementChild as HTMLElement | null;\n        if (childEl) {\n          const parsed = parseFloat(getComputedStyle(childEl).borderTopLeftRadius);\n          if (Number.isFinite(parsed) && parsed > 0) r = parsed;\n        }\n        if (r === 0) {\n          const parsed = parseFloat(getComputedStyle(root).borderTopLeftRadius);\n          if (Number.isFinite(parsed) && parsed > 0) r = parsed;\n        }\n      }\n      return { w, h, r };\n    };\n\n    const initial = measure();\n    const inst = createInstance({\n      canvas: shader,\n      cssWidth: initial.w,\n      cssHeight: initial.h,\n      preset: presetMode,\n      strength,\n      speed,\n      cardBg: cardBgProp ?? null,\n      pixelScale\n    });\n    instanceRef.current = inst;\n    inst.canvas.style.opacity = String(Math.max(0, Math.min(1, strength)));\n\n    const reveal = createReveal({\n      canvas: overlay,\n      cssWidth: initial.w,\n      cssHeight: initial.h,\n      shaderCanvas: shader\n    });\n    inst.reveal = reveal;\n    revealRef.current = reveal;\n\n    // Cycle is created up-front (independent of `autoReveal`) so that the\n    // imperative `triggerReveal()` works for manual user-driven reveals too.\n    // `start()` is only called when `autoReveal` is true (separate effect).\n    const cycle = createCycle({\n      reveal,\n      images: imagesArrRef.current,\n      delayRange: revealDelayRangeRef.current,\n      holdMs: revealHoldMsRef.current,\n      fadeOutMs: revealFadeOutMsRef.current,\n      initialDelayMs: initialDelayMsRef.current,\n      onPhase: (e) => {\n        // A fully-visible image ends any regenerate churn — restore the\n        // preset palette / consumer-provided colors and the authored preset.\n        // (No-op re-set when nothing is active; React bails on identical\n        // state.)\n        if (e.phase === 'visible') {\n          setRegenTint(null);\n          setRegenPresetName(null);\n        }\n        onCycleRef.current?.(e);\n      },\n      excludeSrcs: () => excludeSrcsRef.current?.() ?? null\n    });\n    cycleRef.current = cycle;\n    if (paused) cycle.setPaused(true);\n\n    root.style.setProperty('--image-gen-radius', `${initial.r}px`);\n    root.style.borderRadius = `${initial.r}px`;\n\n    // Sync the wrapper's dimensions + corner radius to the host card.\n    //\n    // The radius must follow the wrapped child dynamically so the effect\n    // always matches whatever the consumer's card looks like — even if they\n    // toggle a class, adjust an inline style, or swap the child entirely.\n    //\n    // Three observers handle the three change vectors:\n    //   1. ResizeObserver on root  -> wrapper resized (window resize, parent\n    //      flex/grid change, container query, etc.)\n    //   2. ResizeObserver on child -> child intrinsic size changed (text\n    //      reflow, image load), which can also imply a CSS recalc that\n    //      affects radius.\n    //   3. MutationObserver on child -> class / style / data-* attribute\n    //      changes that may swap border-radius without touching size (theme\n    //      toggle, hover/active class flip from parent, etc.).\n    //\n    // All three coalesce through a single rAF so the canvas isn't resized\n    // more than once per frame.\n    let resizeRaf = 0;\n    let lastW = -1;\n    let lastH = -1;\n    let lastR = -1;\n    const applyMeasure = (): void => {\n      resizeRaf = 0;\n      const i = instanceRef.current;\n      if (!i) return;\n      const next = measure();\n      // Skip GL resize if dimensions didn't actually change; still re-apply\n      // border-radius because that's the cheap part and may have moved.\n      if (next.w !== lastW || next.h !== lastH) {\n        updateInstanceSize(i, next.w, next.h);\n        lastW = next.w;\n        lastH = next.h;\n      }\n      if (next.r !== lastR) {\n        root.style.setProperty('--image-gen-radius', `${next.r}px`);\n        root.style.borderRadius = `${next.r}px`;\n        lastR = next.r;\n      }\n    };\n    const scheduleMeasure = (): void => {\n      if (resizeRaf !== 0) return;\n      resizeRaf = requestAnimationFrame(applyMeasure);\n    };\n\n    const ro = new ResizeObserver(scheduleMeasure);\n    ro.observe(root);\n    const childEl = contentRef.current?.firstElementChild as HTMLElement | null;\n    if (childEl) ro.observe(childEl);\n\n    // Watch for CSS-affecting attribute changes on the child so radius\n    // updates that don't trigger a resize (e.g. swapping a `rounded-lg`\n    // class with `rounded-xl`) are still reflected immediately.\n    let mo: MutationObserver | null = null;\n    if (childEl && typeof MutationObserver !== 'undefined') {\n      mo = new MutationObserver(scheduleMeasure);\n      mo.observe(childEl, {\n        attributes: true,\n        attributeFilter: ['class', 'style']\n      });\n    }\n    // Initialise cached dimensions from the first measure so the guard\n    // above doesn't spuriously re-apply identical values on the next tick.\n    lastW = initial.w;\n    lastH = initial.h;\n    lastR = initial.r;\n\n    let io: IntersectionObserver | null = null;\n    if (typeof IntersectionObserver !== 'undefined') {\n      io = new IntersectionObserver(\n        (entries) => {\n          const i = instanceRef.current;\n          if (!i) return;\n          for (const e of entries) setInstanceVisible(i, e.isIntersecting);\n        },\n        { rootMargin: '64px' }\n      );\n      io.observe(root);\n    }\n\n    return () => {\n      ro.disconnect();\n      mo?.disconnect();\n      io?.disconnect();\n      if (resizeRaf !== 0) cancelAnimationFrame(resizeRaf);\n      cycleRef.current?.dispose();\n      cycleRef.current = null;\n      reveal.dispose();\n      revealRef.current = null;\n      const i = instanceRef.current;\n      if (i) destroyInstance(i);\n      instanceRef.current = null;\n    };\n  }, []);\n\n  // Sync preset/theme to the instance + force a one-shot repaint so paused\n  // instances reflect the prop change live (rAF tick is gated on `!paused`).\n  // An active regenerate churn preset override takes precedence over the prop.\n  useEffect(() => {\n    const i = instanceRef.current;\n    if (!i) return;\n    const effectiveMode = regenPresetName\n      ? PRESETS[regenPresetName].modes[resolvedTheme]\n      : presetMode;\n    setInstancePreset(i, effectiveMode);\n    renderInstanceOnce(i);\n  }, [presetMode, regenPresetName, resolvedTheme]);\n\n  // Sync cardBg override to the instance (shader uniform + reveal helper),\n  // then repaint once so the change shows immediately even while paused.\n  // An active regenerate tint takes precedence over the prop.\n  useEffect(() => {\n    const i = instanceRef.current;\n    if (!i) return;\n    setInstanceCardBg(i, regenTint?.cardBg ?? cardBgProp ?? null);\n    renderInstanceOnce(i);\n  }, [cardBgProp, regenTint]);\n\n  // Sync the palette override (per-slot colors, e.g. sampled from an image).\n  // An active regenerate tint takes precedence over the prop.\n  useEffect(() => {\n    const i = instanceRef.current;\n    if (!i) return;\n    setInstanceColors(i, regenTint?.colors ?? colors ?? null);\n    renderInstanceOnce(i);\n  }, [colors, regenTint]);\n\n  // Sync strength via the visible canvas opacity (no shader recompile).\n  // The `opacity` style change is purely DOM and applies even while paused;\n  // no GL repaint needed.\n  useEffect(() => {\n    const i = instanceRef.current;\n    if (!i) return;\n    setInstanceStrength(i, strength);\n    if (i.canvas) {\n      i.canvas.style.opacity = String(Math.max(0, Math.min(1, strength)));\n    }\n  }, [strength]);\n\n  // Sync speed — scales the instance's animation clock, no repaint needed.\n  useEffect(() => {\n    const i = instanceRef.current;\n    if (!i) return;\n    setInstanceSpeed(i, speed);\n  }, [speed]);\n\n  // Sync pixelScale (recomputes the mosaic grid density) and repaint once so\n  // the change is visible immediately even while paused.\n  useEffect(() => {\n    const i = instanceRef.current;\n    if (!i) return;\n    setInstancePixelScale(i, pixelScale);\n    renderInstanceOnce(i);\n  }, [pixelScale]);\n\n  // Sync paused.\n  // Custom fragment stage: page-wide while set, back to the bundled one when\n  // this instance drops it or unmounts.\n  useEffect(() => {\n    if (!fragmentShader) return;\n    setSharedFragmentShader(fragmentShader);\n    return () => setSharedFragmentShader(null);\n  }, [fragmentShader]);\n\n  useEffect(() => {\n    const i = instanceRef.current;\n    if (i) setInstancePaused(i, paused);\n    cycleRef.current?.setPaused(paused);\n  }, [paused]);\n\n  // Patch live updates to the always-on cycle (avoid recreating per prop change).\n  useEffect(() => {\n    cycleRef.current?.setImages(imagesArr);\n  }, [imagesArr]);\n  useEffect(() => {\n    cycleRef.current?.setOptions({\n      delayRange: revealDelayRange,\n      holdMs: revealHoldMs,\n      fadeOutMs: revealFadeOutMs\n    });\n  }, [revealDelayRange, revealHoldMs, revealFadeOutMs]);\n\n  // Start/stop the auto-loop in response to the `autoReveal` flag. The cycle\n  // itself is created in the lifecycle effect so manual `triggerReveal()` works\n  // even when `autoReveal === false`.\n  useEffect(() => {\n    const cycle = cycleRef.current;\n    if (!cycle) return;\n    if (autoReveal) {\n      cycle.start();\n      return () => cycle.stop();\n    }\n    cycle.stop();\n    return undefined;\n  }, [autoReveal]);\n\n  const wrapperStyle = useMemo<CSSProperties>(() => {\n    return {\n      // During a regenerate churn the card surface wears the outgoing\n      // image's average color so the dropped cells read as image pixels.\n      background: regenTint?.cardBg ?? cardBg,\n      ...style\n    };\n  }, [cardBg, regenTint, style]);\n\n  return (\n    <div\n      {...rest}\n      ref={rootRef}\n      className={['image-gen-root', className].filter(Boolean).join(' ')}\n      data-preset={preset}\n      data-theme={resolvedTheme}\n      data-paused={paused ? 'true' : undefined}\n      style={wrapperStyle}\n    >\n      <canvas ref={shaderCanvasRef} className=\"image-gen-shader\" aria-hidden=\"true\" />\n      <canvas ref={overlayCanvasRef} className=\"image-gen-overlay\" aria-hidden=\"true\" />\n      <div ref={contentRef} className=\"image-gen-child\">\n        {children}\n      </div>\n    </div>\n  );\n});\n\nImageGeneration.displayName = 'ImageGeneration';\n"
        },
        {
          "path": "components/effects/img-fx/upstream/engine/index.ts",
          "target": "@components/effects/img-fx/upstream/engine/index.ts",
          "type": "registry:component",
          "content": "/** Public engine surface — exposes the renderer/reveal/cycle primitives so\n *  power users can drive the pipeline without React. */\n\nexport {\n  createInstance,\n  destroyInstance,\n  effectiveCardBg,\n  effectiveCellSize,\n  getFrameRate,\n  getMaxDpr,\n  renderInstanceOnce,\n  setFrameRate,\n  setInstanceCardBg,\n  setInstanceColors,\n  setInstancePaused,\n  setInstancePixelScale,\n  setInstancePreset,\n  setInstanceSpeed,\n  setInstanceStrength,\n  setInstanceVisible,\n  setMaxDpr,\n  setSharedFragmentShader,\n  updateInstanceSize,\n  type CreateInstanceOptions,\n  type Instance\n} from './renderer';\n\nexport { FRAG_SRC as IMAGE_FRAGMENT_SHADER } from './shaders';\n\nexport {\n  createReveal,\n  loadImage,\n  pickRandomImage,\n  type CreateRevealOptions,\n  type RevealState,\n  type RevealStartOptions\n} from './reveal';\n\nexport {\n  createCycle,\n  type Cycle,\n  type CycleEvent,\n  type CycleOptions,\n  type CyclePhase\n} from './cycle';\n\nexport { samplePaletteFromCanvas, type SampledPalette } from './palette';\n\nexport { ease, EASING_FNS, type EaseFn } from './tween';\n"
        },
        {
          "path": "components/effects/img-fx/upstream/engine/renderer.ts",
          "target": "@components/effects/img-fx/upstream/engine/renderer.ts",
          "type": "registry:component",
          "content": "/**\n * Shared Three.js renderer driving every <ImageGeneration> on the page.\n *\n * Architecture:\n *   1. One module-scope SharedRenderer is lazily created on first card mount.\n *      It owns a single offscreen <canvas> + THREE.WebGLRenderer + ortho\n *      camera + ShaderMaterial + plane mesh.\n *   2. Each card registers an Instance: a visible 2D canvas + its own\n *      uniform cache + dirty flag + reveal/cycle state. Per frame the loop\n *      sizes the SHARED GL canvas to the largest active card (grow-only —\n *      never shrinks), then for each visible/unpaused instance: sets\n *      u_resolution to the instance's pixel size, sets the GL viewport +\n *      scissor to the bottom-left iw×ih sub-rect (the only sub-rect where\n *      `gl_FragCoord / u_resolution` lands in [0..1]), renders, and copies\n *      that sub-rect into the visible 2D canvas via drawImage.\n *      This avoids reallocating the GL drawing buffer every frame when\n *      multiple cards of different sizes share the renderer — the original\n *      \"setSize per instance per frame\" churn was exhausting Chrome's GPU\n *      memory budget over the course of a few minutes of continuous\n *      animation and crashing the WebGL context.\n *   3. IntersectionObserver pauses offscreen instances; when no instances\n *      are active the rAF loop is cancelled entirely (re-armed by the next\n *      visibility / pause / size change), so a fully-offscreen page costs\n *      essentially nothing.\n *   4. WebGL context loss is handled: on `webglcontextlost` the rAF is\n *      cancelled and uniforms marked dirty; on `webglcontextrestored` the\n *      renderer recovers and resumes.\n *   5. Last unmount disposes everything (geometry, material, renderer).\n *\n * This mirrors the metal-fx shared-renderer pattern but built around Three.js\n * (peer dep) so the GLSL from image.html drops in unchanged.\n */\nimport * as THREE from 'three';\nimport { parseCssColor, type EnginePresetMode, type PresetMode } from '../presets';\nimport { FRAG_SRC, VERT_SRC } from './shaders';\nimport type { RevealState } from './reveal';\n\n/** Frame interval (ms). 10 fps cap is the sweet spot for the bundled presets\n *  — they drift at `speed` 0.3-0.9 rad/s, which is a phase delta of just\n *  0.03-0.09 rad per frame at 10 fps (well below the perceptual flicker\n *  threshold for smoothly varying fields). Drops shader + reveal work by\n *  ~33% vs. the previous 15 fps cap; for fast-moving custom presets the\n *  consumer can opt back up via `setFrameRate(15)` or higher. */\nlet frameIntervalMs = 1000 / 10;\n/** Maximum device-pixel-ratio applied to the GL canvas (image.html line 952).\n *  At 1.25 (vs the original 1.5) fragment work drops by ~31% per render\n *  with essentially no visible difference on the cell-quantised mosaic\n *  presets bundled with the library. Mutable via `setMaxDpr()`. */\nlet maxDpr = 1.25;\n/** Maximum device-pixel-ratio applied to the *visible* 2D canvas (the one\n *  the user actually sees) and, by extension, the reveal image drawn into\n *  it. Decoupled from `maxDpr` because:\n *\n *  - GL fragment work scales with `maxDpr²` and is the dominant per-frame\n *    cost — bumping it is expensive.\n *  - The visible canvas only receives ONE hardware-accelerated `drawImage`\n *    per frame (rect copy from the GL framebuffer) plus, briefly during\n *    reveal, the photographic image draw. Both are cheap even at 2× DPR.\n *\n *  Capping the *visible* canvas higher fixes the iOS-Safari / iOS-Firefox\n *  blur that 1.25× produced on `devicePixelRatio: 3` retina screens:\n *  the GL framebuffer (still rendered at `maxDpr`=1.25) is upscaled into\n *  the visible canvas with nearest-neighbour `drawImage`, so the cell\n *  mosaic stays crisp at no extra GL cost, while the reveal image —\n *  which `paintMaskedFrame` always draws with `imageSmoothingEnabled =\n *  true` at full quality — lands at the device's native pixel grid.\n *  2 is the standard \"retina2x\" cap; going to 3 on iPhone is below visual\n *  acuity for this content and would just chew CPU on the per-frame\n *  drawImage copy. */\nconst MAX_CANVAS_DPR = 2;\n\nfunction resolveCanvasDpr(): number {\n  if (typeof window === 'undefined') return 1;\n  return Math.min(window.devicePixelRatio || 1, MAX_CANVAS_DPR);\n}\n\n/** Instance handle returned by `createInstance`. Each <ImageGeneration> owns one. */\nexport interface Instance {\n  /** Visible 2D canvas painted into the host wrapper. */\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  /** CSS-px size (synced from ResizeObserver). */\n  cssWidth: number;\n  cssHeight: number;\n  /** GL render DPR cached at creation; refreshed on resize. Caps at\n   *  `maxDpr` (default 1.25) — this is the cheap-fragment-shader knob. */\n  dpr: number;\n  /** Display DPR for the visible 2D canvas (and reveal image). Caps at\n   *  `MAX_CANVAS_DPR` (default 2). May exceed `dpr`: when it does, the\n   *  low-DPR GL framebuffer is upscaled into the visible canvas with\n   *  `imageSmoothingEnabled = false` so the cell mosaic stays crisp at\n   *  no extra GL cost, while the reveal image — drawn directly into\n   *  this canvas with smoothing enabled — gets the device's full pixel\n   *  density. Fixes blur on iOS Safari/Firefox where DPR=3. */\n  canvasDpr: number;\n  /** Active preset mode block (dark or light).\n   *\n   * Typed as `EnginePresetMode` (the wider engine-internal shape)\n   * even though the public `setInstancePreset` accepts a narrower\n   * `PresetMode` — the cast is sound because the runtime objects\n   * exported via PRESETS always carry the dot-mode fields. */\n  preset: EnginePresetMode;\n  /** Optional override for `preset.cardBg` (#rrggbb). When set, this color is\n   *  used as the shader's `u_cardBg` and forwarded to the reveal helper so\n   *  background-derived shader logic stays in sync with the host card color. */\n  cardBgOverride: string | null;\n  /** Optional per-slot palette override (CSS colors, up to 7 entries). A slot\n   *  with a value replaces the preset color verbatim (bypassing the card-bg\n   *  linked remap); missing/undefined slots fall back to the preset palette.\n   *  Lets consumers re-tint the running effect (e.g. from an image) without\n   *  authoring a whole preset. */\n  colorsOverride: (string | null | undefined)[] | null;\n  /** Strength multiplier 0..1 (drives `canvas.style.opacity`). */\n  strength: number;\n  /** Animation-clock multiplier on top of the preset's baked speed. Scales\n   *  the per-frame time delta, so drift, churn and flicker all speed up or\n   *  slow down together. 1 = preset tempo. */\n  speedMul: number;\n  /** Pixel-cell on-screen size multiplier. 1 = preset default, 0.5 = cells at\n   *  half size (finer / zoomed out), 2 = double size (chunkier / zoomed in).\n   *  Applied by dividing the shader grid's base cell count so both the shader\n   *  mosaic and the reveal dissolve share the same scaled grid. */\n  pixelScale: number;\n  /** True when in viewport. */\n  visible: boolean;\n  /** True when the user has paused this instance. */\n  paused: boolean;\n  /** Dirty flag - true until uniforms have been re-uploaded. */\n  uniformsDirty: boolean;\n  /** Reveal state (image overlay drawn on top of shader). Null when no overlay. */\n  reveal: RevealState | null;\n  /** Per-instance accumulated time so each card animates at its own preset.speed. */\n  accumulatedTime: number;\n  /** When created (ms) — used for first-tick init only. */\n  startedAtMs: number;\n}\n\ninterface SharedRenderer {\n  glCanvas: HTMLCanvasElement;\n  /** WebGL2 context if available, otherwise WebGL1. */\n  gl: WebGLRenderingContext | WebGL2RenderingContext;\n  renderer: THREE.WebGLRenderer;\n  scene: THREE.Scene;\n  camera: THREE.OrthographicCamera;\n  material: THREE.ShaderMaterial;\n  geometry: THREE.PlaneGeometry;\n  mesh: THREE.Mesh;\n  uniforms: Record<string, THREE.IUniform>;\n  instances: Set<Instance>;\n  /** 0 means the rAF loop is currently asleep (no active instances).\n   *  The loop is re-armed by `wakeLoop()` whenever an instance becomes\n   *  visible/unpaused or its size grows past the current GL canvas. */\n  rafId: number;\n  lastFrameMs: number;\n  lastTickMs: number;\n  /** Last instance whose uniforms were uploaded to `uniforms`. Used to skip\n   *  re-uploading full uniform blocks when the same clean instance renders\n   *  again back-to-back (e.g. single-card page, manual repaint). Null after\n   *  destroy or when the next instance can't trust this cache. */\n  lastInstance: Instance | null;\n  /** WebGL context loss handlers — kept so we can detach on dispose. */\n  onContextLost: ((e: Event) => void) | null;\n  onContextRestored: (() => void) | null;\n  contextLost: boolean;\n}\n\nlet SHARED: SharedRenderer | null = null;\n\nfunction createUniforms(): Record<string, THREE.IUniform> {\n  return {\n    u_resolution: { value: new THREE.Vector2(1, 1) },\n    u_dpr: { value: 1 },\n    u_time: { value: 0 },\n    u_color1: { value: new THREE.Color(0x1a1a1a) },\n    u_color2: { value: new THREE.Color(0x808080) },\n    u_color3: { value: new THREE.Color(0xd9d9d9) },\n    u_color4: { value: new THREE.Color(0x404040) },\n    u_color5: { value: new THREE.Color(0xc0c0c0) },\n    u_color6: { value: new THREE.Color(0x606060) },\n    u_color7: { value: new THREE.Color(0xa0a0a0) },\n    u_cardBg: { value: new THREE.Color(0x0f0f0f) },\n    u_alpha1: { value: 1 },\n    u_alpha2: { value: 1 },\n    u_alpha3: { value: 1 },\n    u_alpha4: { value: 1 },\n    u_alpha5: { value: 1 },\n    u_alpha6: { value: 1 },\n    u_alpha7: { value: 1 },\n    u_speed: { value: 1 },\n    u_intensity: { value: 1 },\n    u_scale: { value: 1.5 },\n    u_direction: { value: 0 },\n    u_softness: { value: 0.75 },\n    u_distortion: { value: 0.3 },\n    u_complexity: { value: 0.2 },\n    u_shape: { value: 0.5 },\n    u_flicker: { value: 0 },\n    u_vignette: { value: 0.25 },\n    u_vigOpacity: { value: 1 },\n    u_blur: { value: 0 },\n    u_highlight: { value: 0.4 },\n    u_shaderOpacity: { value: 1 },\n    u_cellSize: { value: 0.5 },\n    u_gap: { value: 0.3 },\n    u_dotSize: { value: 0.8 },\n    u_dotSoftness: { value: 0.1 },\n    u_dotOpacity: { value: 1 },\n    u_hlScale: { value: 0 },\n    u_fillOpacity: { value: 0 },\n    u_edgeFade: { value: 16 },\n    u_fadeStr: { value: 1 },\n    u_dotMode: { value: 2 },\n    u_effect: { value: 4 },\n    u_sweepEase: { value: 0 }\n  };\n}\n\nfunction ensureShared(): SharedRenderer {\n  if (SHARED) return SHARED;\n\n  const glCanvas = document.createElement('canvas');\n  glCanvas.width = 8;\n  glCanvas.height = 8;\n\n  // `preserveDrawingBuffer: false` is the default and the right choice here:\n  // we drawImage() the GL canvas into the visible 2D canvas IMMEDIATELY after\n  // every renderer.render() in the same JS tick, so we never need the swap\n  // chain to preserve back-buffer contents between frames. Preserving it was\n  // forcing extra GPU memory retention which compounded the GL-buffer churn\n  // issue and contributed to multi-minute crashes in Chrome.\n  const renderer = new THREE.WebGLRenderer({\n    canvas: glCanvas,\n    alpha: true,\n    premultipliedAlpha: false,\n    preserveDrawingBuffer: false,\n    antialias: false,\n    powerPreference: 'high-performance'\n  });\n  renderer.setPixelRatio(Math.min(typeof window !== 'undefined' ? window.devicePixelRatio : 1, maxDpr));\n  renderer.setClearColor(0x000000, 0);\n  renderer.autoClear = true;\n\n  const gl = renderer.getContext();\n\n  const scene = new THREE.Scene();\n  const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n\n  const uniforms = createUniforms();\n  const material = new THREE.ShaderMaterial({\n    vertexShader: VERT_SRC,\n    fragmentShader: FRAG_SRC,\n    uniforms,\n    transparent: true,\n    depthTest: false,\n    depthWrite: false,\n    blending: THREE.NormalBlending\n  });\n  const geometry = new THREE.PlaneGeometry(2, 2);\n  const mesh = new THREE.Mesh(geometry, material);\n  scene.add(mesh);\n\n  SHARED = {\n    glCanvas,\n    gl,\n    renderer,\n    scene,\n    camera,\n    material,\n    geometry,\n    mesh,\n    uniforms,\n    instances: new Set(),\n    rafId: 0,\n    lastFrameMs: 0,\n    lastTickMs: performance.now(),\n    lastInstance: null,\n    onContextLost: null,\n    onContextRestored: null,\n    contextLost: false\n  };\n\n  // WebGL context loss recovery. Without this, a transient GPU hiccup (driver\n  // reset, tab backgrounded too long, GPU OOM, etc.) would permanently freeze\n  // every <ImageGeneration> on the page. `preventDefault()` on `lost` tells\n  // the browser we'd like a restored context; on `restored` we re-arm the\n  // loop and force every instance to re-upload its uniforms.\n  const onLost = (e: Event): void => {\n    e.preventDefault();\n    if (!SHARED) return;\n    SHARED.contextLost = true;\n    if (SHARED.rafId !== 0) {\n      cancelAnimationFrame(SHARED.rafId);\n      SHARED.rafId = 0;\n    }\n  };\n  const onRestored = (): void => {\n    if (!SHARED) return;\n    SHARED.contextLost = false;\n    SHARED.lastInstance = null;\n    for (const inst of SHARED.instances) inst.uniformsDirty = true;\n    wakeLoop();\n  };\n  glCanvas.addEventListener('webglcontextlost', onLost as EventListener, false);\n  glCanvas.addEventListener('webglcontextrestored', onRestored, false);\n  SHARED.onContextLost = onLost;\n  SHARED.onContextRestored = onRestored;\n\n  wakeLoop();\n  return SHARED;\n}\n\nfunction destroyShared(): void {\n  if (!SHARED) return;\n  if (SHARED.rafId !== 0) cancelAnimationFrame(SHARED.rafId);\n  if (SHARED.onContextLost) {\n    SHARED.glCanvas.removeEventListener('webglcontextlost', SHARED.onContextLost as EventListener, false);\n  }\n  if (SHARED.onContextRestored) {\n    SHARED.glCanvas.removeEventListener('webglcontextrestored', SHARED.onContextRestored, false);\n  }\n  SHARED.geometry.dispose();\n  SHARED.material.dispose();\n  SHARED.renderer.dispose();\n  SHARED = null;\n}\n\nfunction uploadInstanceUniforms(s: SharedRenderer, inst: Instance): void {\n  const p = inst.preset;\n  const u = s.uniforms;\n  u.u_effect.value = p.effectIndex;\n  u.u_speed.value = p.speed;\n  // Strength above 1 boosts the shader's palette intensity and highlight\n  // (canvas opacity is already at 1 there), so the top of the strength\n  // range reads as a markedly more prominent effect rather than saturating\n  // early. The 2.2 slope makes strength=2 roughly a 3× intensity push.\n  const boost = 1 + Math.max(0, inst.strength - 1) * 2.2;\n  u.u_intensity.value = p.intensity * boost;\n  u.u_scale.value = p.scale;\n  u.u_direction.value = (p.direction * Math.PI) / 180;\n  u.u_softness.value = p.softness;\n  u.u_distortion.value = p.distortion;\n  u.u_complexity.value = p.complexity;\n  u.u_shape.value = p.shape;\n  u.u_flicker.value = p.flicker ?? 0;\n  u.u_vignette.value = p.vignette;\n  u.u_vigOpacity.value = p.vigOpacity;\n  u.u_blur.value = p.blur;\n  u.u_highlight.value = p.highlight * boost;\n  u.u_shaderOpacity.value = p.shaderOpacity;\n  u.u_dotMode.value = p.dotMode;\n  u.u_sweepEase.value = p.sweepEase != null ? Math.floor(p.sweepEase) : 0;\n\n  const mosaic = p.dotMode === 1 ? p.pixelConfig : p.dotConfig;\n  u.u_cellSize.value = effectiveCellSize(mosaic.cellSize, inst.pixelScale);\n  u.u_gap.value = mosaic.gap;\n  u.u_dotSize.value = mosaic.dotSize;\n  u.u_dotSoftness.value = mosaic.dotSoftness;\n  u.u_dotOpacity.value = mosaic.dotOpacity;\n  u.u_hlScale.value = mosaic.hlScale;\n  u.u_fillOpacity.value = mosaic.fillOpacity;\n  u.u_edgeFade.value = mosaic.edgeFade;\n  u.u_fadeStr.value = mosaic.fadeStr;\n\n  // `cardBgOverride` comes straight from the consumer's `cardBg` prop and is\n  // documented as accepting any CSS colour, so route through parseCssColor\n  // (alpha is dropped — see the parseCssColor JSDoc for why). The bundled\n  // preset's own `cardBg` is always hex and hits the fast path.\n  const [br, bg, bb] = parseCssColor(inst.cardBgOverride ?? p.cardBg);\n\n  for (let i = 0; i < 7; i++) {\n    const override = inst.colorsOverride?.[i];\n    const [r, g, b] = override != null ? parseCssColor(override) : effectivePaletteColor(inst, i);\n    (u[`u_color${i + 1}`].value as THREE.Color).setRGB(r, g, b);\n    u[`u_alpha${i + 1}`].value = p.alphas[i];\n  }\n  (u.u_cardBg.value as THREE.Color).setRGB(br, bg, bb);\n\n  inst.uniformsDirty = false;\n}\n\n/** Hex (#rrggbb) currently in effect for this instance, accounting for override. */\nexport function effectiveCardBg(inst: Instance): string {\n  return inst.cardBgOverride ?? inst.preset.cardBg;\n}\n\n/**\n * Palette colour `index` (0–6) as [r,g,b] in 0–1, after the card-linked remap\n * (port of image.html's card-variable behaviour).\n *\n * Any preset colour authored to equal the preset's OWN canonical `cardBg` is\n * treated as a \"card variable\": when the consumer overrides `cardBg`, those\n * colours follow the new surface instead of staying at the preset default\n * (otherwise e.g. sweep-gradient's #0f0f0f swatches read as dark blocks on a\n * #1B1B1B demo card). With no override the effective bg equals the preset bg,\n * so the comparison is a no-op and the raw colour is returned unchanged.\n *\n * Shared by the shader uniform upload and the reveal mask so the effect and\n * its reveal silhouette stay in lockstep.\n */\nexport function effectivePaletteColor(inst: Instance, index: number): [number, number, number] {\n  const p = inst.preset;\n  const [r, g, b] = parseCssColor(p.colors[index]);\n  if (inst.cardBgOverride == null) return [r, g, b];\n  const [pbr, pbg, pbb] = parseCssColor(p.cardBg);\n  const chan = (v: number): number => Math.round(v * 255);\n  if (chan(r) === chan(pbr) && chan(g) === chan(pbg) && chan(b) === chan(pbb)) {\n    return parseCssColor(inst.cardBgOverride);\n  }\n  return [r, g, b];\n}\n\n/** Compute the pixel-space size an instance currently needs from the GL\n *  framebuffer (CSS px × DPR, floored, min 1). Used by both the grow-only\n *  canvas sizer and per-paint viewport setup so the two stay in lockstep. */\nfunction instancePixelSize(inst: Instance): { iw: number; ih: number } {\n  return {\n    iw: Math.max(1, Math.floor(inst.cssWidth * inst.dpr)),\n    ih: Math.max(1, Math.floor(inst.cssHeight * inst.dpr))\n  };\n}\n\n/** Grow the shared GL canvas if any active instance now needs more pixels\n *  than it currently provides. NEVER SHRINKS — frequent shrink/grow cycles\n *  reallocate the GL drawing buffer (each call is 1-10 MB of GPU memory\n *  churn) and that was the primary cause of multi-minute Chrome crashes.\n *\n *  Called once at the top of each frame (before iterating instances) so the\n *  canvas size is stable for the entire tick. */\nfunction maybeGrowGlCanvas(s: SharedRenderer): void {\n  let needCssW = 0;\n  let needCssH = 0;\n  for (const inst of s.instances) {\n    if (!inst.visible || inst.paused) continue;\n    if (inst.cssWidth > needCssW) needCssW = inst.cssWidth;\n    if (inst.cssHeight > needCssH) needCssH = inst.cssHeight;\n  }\n  if (needCssW <= 0 || needCssH <= 0) return;\n  const dpr = s.renderer.getPixelRatio();\n  const needPxW = Math.max(1, Math.floor(needCssW * dpr));\n  const needPxH = Math.max(1, Math.floor(needCssH * dpr));\n  const curW = s.glCanvas.width;\n  const curH = s.glCanvas.height;\n  if (needPxW <= curW && needPxH <= curH) return;\n  // Pass CSS px (setSize multiplies by pixel ratio internally). Pick the max\n  // of the current and required dimensions so neither axis ever contracts.\n  const targetCssW = Math.max(needCssW, curW / Math.max(dpr, 0.0001));\n  const targetCssH = Math.max(needCssH, curH / Math.max(dpr, 0.0001));\n  s.renderer.setSize(targetCssW, targetCssH, false);\n}\n\n/** Inner render — assumes the caller has already gated on visibility / size /\n *  pause where appropriate AND has called `maybeGrowGlCanvas` for the frame.\n *\n *  Renders the instance into the BOTTOM-LEFT iw×ih sub-rect of the shared GL\n *  canvas. That sub-rect is the only one where the shader's\n *  `uv = gl_FragCoord.xy / u_resolution` lands in `[0..1]² ` (because\n *  gl_FragCoord is window-relative in WebGL with origin at the bottom-left,\n *  and we set u_resolution to the instance's pixel size). After rendering,\n *  we drawImage() that sub-rect into the visible 2D canvas — the source\n *  rect's image-space y is `glCanvas.height - ih` because image-space coords\n *  have origin at the top-left while the framebuffer's origin is at the\n *  bottom-left.\n *\n *  Uniform block re-upload is skipped when the same clean instance just\n *  rendered AND its `uniformsDirty` flag is clear (only `u_time` and\n *  `u_resolution` need refreshing in that case). For multi-card pages\n *  instances rotate so this always re-uploads, but it removes the cost\n *  for single-card pages, manual `renderInstanceOnce` repaints, and\n *  reveal sampling re-renders that don't switch instance. */\nfunction paintInstance(s: SharedRenderer, inst: Instance, nowMs: number): void {\n  if (s.contextLost) return;\n  const { iw, ih } = instancePixelSize(inst);\n\n  // Constrain rendering to the instance-sized bottom-left sub-rect. setViewport\n  // and setScissor on the WebGLRenderer accept CSS pixels and multiply by the\n  // renderer's pixel ratio internally, so pass the CSS dims to keep math simple.\n  const cssW = Math.max(1, inst.cssWidth);\n  const cssH = Math.max(1, inst.cssHeight);\n  s.renderer.setViewport(0, 0, cssW, cssH);\n  s.renderer.setScissor(0, 0, cssW, cssH);\n  s.renderer.setScissorTest(true);\n\n  // u_resolution drives the shader's cell sizes, vignette, edge fade etc.\n  // It MUST match the viewport size so `gl_FragCoord / u_resolution` produces\n  // sensible UVs inside the rendered sub-rect.\n  (s.uniforms.u_resolution.value as THREE.Vector2).set(iw, ih);\n  s.uniforms.u_dpr.value = inst.dpr || 1;\n\n  // Reuse uniforms when the same clean instance is rendering again.\n  const canReuseUniforms = s.lastInstance === inst && !inst.uniformsDirty;\n  if (!canReuseUniforms) {\n    uploadInstanceUniforms(s, inst);\n    s.lastInstance = inst;\n  }\n  s.uniforms.u_time.value = inst.accumulatedTime;\n\n  s.renderer.render(s.scene, s.camera);\n\n  // Resize the visible canvas to the instance's pixel size — at the\n  // *display* DPR cap (`canvasDpr`, default 2), not the GL DPR (`dpr`,\n  // default 1.25). Sizing this canvas higher than the GL framebuffer is\n  // what gives iOS Safari/Firefox a sharp reveal image: `paintMaskedFrame`\n  // draws the photograph directly into this canvas with\n  // `imageSmoothingEnabled = true`, so the image lands at the device's\n  // native pixel grid (DPR 3 on iPhone, DPR 2 on iPad) instead of getting\n  // CSS-upscaled from 1.25× by the browser.\n  //\n  // The reallocation cost is the same as before — the canvas only\n  // triggers a buffer alloc when the instance itself resizes — and the\n  // per-frame compositing cost adds one hardware-accelerated rect copy\n  // at (`dispW × dispH`) which is sub-ms on any GPU-backed 2D context.\n  const dispW = Math.max(1, Math.floor(inst.cssWidth * inst.canvasDpr));\n  const dispH = Math.max(1, Math.floor(inst.cssHeight * inst.canvasDpr));\n  if (inst.canvas.width !== dispW || inst.canvas.height !== dispH) {\n    inst.canvas.width = dispW;\n    inst.canvas.height = dispH;\n  }\n  inst.ctx.clearRect(0, 0, dispW, dispH);\n  // Source rect is the bottom-left iw×ih of the framebuffer. In image-space\n  // (top-left origin) that lives at sy = glCanvas.height - ih.\n  const sy = s.glCanvas.height - ih;\n  // Disable smoothing for the GL → visible upscale: the shader output is a\n  // sharp cell mosaic and nearest-neighbour preserves block edges (bilinear\n  // would melt them into a mushy gradient — the exact iOS blur we're\n  // fixing for the reveal image, but inverted for the shader). The reveal\n  // pipeline (`paintMaskedFrame` and friends) explicitly re-enables\n  // smoothing before drawing the photographic image, so this setting only\n  // affects this single drawImage call.\n  inst.ctx.imageSmoothingEnabled = false;\n  inst.ctx.drawImage(s.glCanvas, 0, sy, iw, ih, 0, 0, dispW, dispH);\n\n  // Reveal pipeline (defined in reveal.ts) — paints overlay image into its\n  // own mask canvas; we just notify it that the shader frame just finished.\n  // Sampling inside `afterShaderFrame` mutates u_dotMode/u_fillOpacity, so\n  // invalidate the uniform cache after the hook runs.\n  inst.reveal?.afterShaderFrame(s, inst, nowMs);\n  if (inst.reveal && inst.reveal.isActive()) {\n    s.lastInstance = null;\n  }\n}\n\n/** Render a single instance into its visible canvas (rAF tick path).\n *  Skips paused / offscreen / zero-size instances so the loop stays cheap. */\nfunction renderInstance(s: SharedRenderer, inst: Instance, nowMs: number): void {\n  if (!inst.visible || inst.paused) return;\n  if (inst.cssWidth < 1 || inst.cssHeight < 1) return;\n  paintInstance(s, inst, nowMs);\n}\n\n/**\n * Force a single repaint of an instance regardless of its pause state.\n * Used by React sync effects (preset / cardBg changes etc.) so paused cards\n * still reflect prop edits live in the playground without resuming the\n * animation loop. Skips if the instance is offscreen or zero-sized.\n */\nexport function renderInstanceOnce(inst: Instance): void {\n  if (!SHARED) return;\n  if (SHARED.contextLost) return;\n  if (!inst.visible) return;\n  if (inst.cssWidth < 1 || inst.cssHeight < 1) return;\n  // Make sure the GL canvas is big enough for this one-shot repaint even if\n  // the loop is currently asleep (no auto-render instance is keeping it\n  // sized).\n  maybeGrowGlCanvas(SHARED);\n  paintInstance(SHARED, inst, performance.now());\n}\n\nlet onAfterTick: (() => void) | null = null;\n/** Hook for cycle scheduler so it can advance phase timers in lockstep. */\nexport function setAfterTick(cb: (() => void) | null): void {\n  onAfterTick = cb;\n}\n\n/** Quick check: is at least one instance currently animating (visible &\n *  unpaused)? Used to decide whether the rAF loop should sleep. */\nfunction hasActiveInstances(s: SharedRenderer): boolean {\n  for (const inst of s.instances) {\n    if (inst.visible && !inst.paused) return true;\n  }\n  return false;\n}\n\nconst tick = (now: number): void => {\n  if (!SHARED) return;\n  if (SHARED.contextLost) {\n    SHARED.rafId = 0;\n    return;\n  }\n\n  // Sleep the rAF loop when nothing is animating. The loop re-arms via\n  // `wakeLoop()` when visibility / pause / size next changes — so a fully\n  // offscreen or fully-paused page costs essentially zero CPU.\n  if (!hasActiveInstances(SHARED)) {\n    SHARED.rafId = 0;\n    onAfterTick?.();\n    return;\n  }\n\n  SHARED.rafId = requestAnimationFrame(tick);\n\n  const elapsed = now - SHARED.lastFrameMs;\n  if (elapsed < frameIntervalMs) return;\n  SHARED.lastFrameMs = now - (elapsed % frameIntervalMs);\n\n  const deltaSec = (now - SHARED.lastTickMs) / 1000;\n  SHARED.lastTickMs = now;\n\n  for (const inst of SHARED.instances) {\n    if (inst.visible && !inst.paused) {\n      inst.accumulatedTime += deltaSec * inst.speedMul;\n    }\n  }\n\n  // Grow-only resize ONCE per frame (not per instance) so the GL drawing\n  // buffer is reallocated at most a handful of times across the lifetime of\n  // the page rather than tens of thousands of times per minute.\n  maybeGrowGlCanvas(SHARED);\n\n  for (const inst of SHARED.instances) {\n    renderInstance(SHARED, inst, now);\n  }\n\n  onAfterTick?.();\n};\n\n/** Arm the rAF loop if it's currently asleep. Safe to call repeatedly. */\nfunction wakeLoop(): void {\n  if (!SHARED) return;\n  if (SHARED.contextLost) return;\n  if (SHARED.rafId !== 0) return;\n  SHARED.lastTickMs = performance.now();\n  SHARED.lastFrameMs = SHARED.lastTickMs;\n  SHARED.rafId = requestAnimationFrame(tick);\n}\n\n/** Public API */\n\nexport interface CreateInstanceOptions {\n  canvas: HTMLCanvasElement;\n  cssWidth: number;\n  cssHeight: number;\n  preset: PresetMode;\n  strength?: number;\n  /** Animation-clock multiplier (see `Instance.speedMul`). @default 1 */\n  speed?: number;\n  cardBg?: string | null;\n  /** Pixel-cell size multiplier (see `Instance.pixelScale`). @default 1 */\n  pixelScale?: number;\n}\n\n/**\n * Resolve the effective `cellSize` (0..1 preset value) for an instance's\n * `pixelScale`. The shader derives the mosaic grid from\n * `gridCounts(6 + cellSize * 74)`, so scaling the on-screen cell *size* by\n * `pixelScale` means dividing that base count by `pixelScale` (smaller cells\n * = more of them). Returning a re-derived `cellSize` keeps the shader and the\n * reveal dissolve — which both compute `6 + cellSize * 74` independently —\n * perfectly in lockstep without threading an extra uniform.\n *\n * The result can fall below 0 (very chunky) or above 1 (very fine); the\n * shader's `gridCounts` floor of 2 cells keeps that safe.\n */\nexport function effectiveCellSize(cellSize: number, pixelScale: number): number {\n  if (!(pixelScale > 0) || pixelScale === 1) return cellSize;\n  const baseCount = (6 + cellSize * 74) / pixelScale;\n  return (baseCount - 6) / 74;\n}\n\nexport function createInstance(opts: CreateInstanceOptions): Instance {\n  const s = ensureShared();\n  const ctx = opts.canvas.getContext('2d');\n  if (!ctx) throw new Error('img-fx: 2D context unavailable');\n  const inst: Instance = {\n    canvas: opts.canvas,\n    ctx,\n    cssWidth: opts.cssWidth,\n    cssHeight: opts.cssHeight,\n    dpr: Math.min(typeof window !== 'undefined' ? window.devicePixelRatio : 1, maxDpr),\n    canvasDpr: resolveCanvasDpr(),\n    // Public `PresetMode` widens to `EnginePresetMode` at the\n    // boundary — see `Instance.preset` for the rationale.\n    preset: opts.preset as EnginePresetMode,\n    cardBgOverride: opts.cardBg ?? null,\n    colorsOverride: null,\n    strength: Math.max(0, Math.min(2, opts.strength ?? 1)),\n    speedMul: opts.speed != null && opts.speed > 0 ? opts.speed : 1,\n    pixelScale: opts.pixelScale != null && opts.pixelScale > 0 ? opts.pixelScale : 1,\n    visible: true,\n    paused: false,\n    uniformsDirty: true,\n    reveal: null,\n    accumulatedTime: Math.random() * 1000,\n    startedAtMs: performance.now()\n  };\n  s.instances.add(inst);\n  wakeLoop();\n  return inst;\n}\n\nexport function destroyInstance(inst: Instance): void {\n  if (!SHARED) return;\n  SHARED.instances.delete(inst);\n  // Drop the uniform-cache pointer if it referenced the dead instance, so the\n  // next render of any other instance won't trust stale per-instance uniforms.\n  if (SHARED.lastInstance === inst) SHARED.lastInstance = null;\n  inst.reveal?.dispose();\n  inst.reveal = null;\n  if (SHARED.instances.size === 0) destroyShared();\n}\n\nexport function updateInstanceSize(inst: Instance, cssWidth: number, cssHeight: number): void {\n  inst.cssWidth = cssWidth;\n  inst.cssHeight = cssHeight;\n  if (typeof window !== 'undefined') {\n    inst.dpr = Math.min(window.devicePixelRatio, maxDpr);\n    // Refresh visible-canvas DPR too — covers monitor swaps and OS\n    // zoom changes that move `devicePixelRatio` while the page is open.\n    inst.canvasDpr = resolveCanvasDpr();\n  }\n}\n\nexport function setInstancePreset(inst: Instance, preset: PresetMode): void {\n  // Same widening cast as `createInstance` — see `Instance.preset`.\n  inst.preset = preset as EnginePresetMode;\n  inst.uniformsDirty = true;\n}\n\nexport function setInstanceCardBg(inst: Instance, cardBg: string | null): void {\n  inst.cardBgOverride = cardBg;\n  inst.uniformsDirty = true;\n}\n\n/** Per-slot palette override (see `Instance.colorsOverride`). Pass null to\n *  restore the preset palette. */\nexport function setInstanceColors(inst: Instance, colors: (string | null | undefined)[] | null): void {\n  inst.colorsOverride = colors && colors.length > 0 ? colors.slice(0, 7) : null;\n  inst.uniformsDirty = true;\n}\n\nexport function setInstanceVisible(inst: Instance, visible: boolean): void {\n  inst.visible = visible;\n  if (visible) wakeLoop();\n}\n\nexport function setInstancePaused(inst: Instance, paused: boolean): void {\n  inst.paused = paused;\n  if (!paused) wakeLoop();\n}\n\nexport function setInstanceStrength(inst: Instance, strength: number): void {\n  inst.strength = Math.max(0, Math.min(2, strength));\n  // The boost region (>1) feeds u_intensity, which is baked into the cached\n  // uniform block — invalidate so the change paints on the next frame.\n  inst.uniformsDirty = true;\n}\n\nexport function setInstanceSpeed(inst: Instance, speed: number): void {\n  inst.speedMul = speed > 0 ? speed : 1;\n}\n\nexport function setInstancePixelScale(inst: Instance, pixelScale: number): void {\n  inst.pixelScale = pixelScale > 0 ? pixelScale : 1;\n  // Cell count is derived from pixelScale at uniform-upload time, so a change\n  // must invalidate the cached uniform block.\n  inst.uniformsDirty = true;\n}\n\n/**\n * Cap the rAF tick rate (frames per second). Applies globally to every\n * instance sharing the renderer. Values are clamped to a sensible range so\n * a callsite can't accidentally starve the loop or burn CPU at >60.\n *\n * @example setFrameRate(10) // default — best for slow-drift presets\n * @example setFrameRate(15) // smoother for faster custom presets\n * @example setFrameRate(30) // restore the original cap\n */\nexport function setFrameRate(fps: number): void {\n  const safe = Math.max(1, Math.min(60, fps));\n  frameIntervalMs = 1000 / safe;\n}\n\n/**\n * Cap the device-pixel-ratio used by the GL canvas. Lower values mean\n * fewer fragments to shade per frame (~quadratic GPU saving). Updates the\n * shared `THREE.WebGLRenderer.setPixelRatio` AND every live instance's\n * cached `inst.dpr` so the next render uses the new ratio. Existing\n * instances are forced to re-upload uniforms because the change invalidates\n * the per-instance `u_dpr` value used by the shader's CSS-px calculations.\n *\n * Values are clamped to [1, 4]. Pass `1` for the strongest GPU saving on\n * retina displays; the default is `1.25`.\n */\nexport function setMaxDpr(dpr: number): void {\n  maxDpr = Math.max(1, Math.min(4, dpr));\n  if (!SHARED) return;\n  const next = Math.min(typeof window !== 'undefined' ? window.devicePixelRatio : 1, maxDpr);\n  SHARED.renderer.setPixelRatio(next);\n  // Force every instance to re-pick its DPR + re-upload uniforms next paint\n  // so `u_dpr`, `u_resolution`, and the GL canvas size all stay coherent.\n  for (const inst of SHARED.instances) {\n    inst.dpr = next;\n    inst.uniformsDirty = true;\n  }\n  // Invalidate the uniform cache so the next paint re-uploads rather than\n  // rolling forward with stale per-instance values.\n  SHARED.lastInstance = null;\n}\n\n/** Read the current cap (frames per second). */\nexport function getFrameRate(): number {\n  return 1000 / frameIntervalMs;\n}\n\n/** Read the current MAX_DPR cap. */\nexport function getMaxDpr(): number {\n  return maxDpr;\n}\n\n/** Internal helper for the reveal sampler — exposes the shared renderer to\n *  reveal.ts so it can momentarily re-render with a different dotMode and read\n *  pixels back via gl.readPixels. */\n/** Swap the fragment stage every instance renders with, or `null` for the\n *  bundled one. The material is shared, so this is page-wide. Compile\n *  errors surface from three.js on the next render — validate the source\n *  on a scratch context first if it comes from somewhere untrusted. */\nexport function setSharedFragmentShader(src: string | null): void {\n  const s = ensureShared();\n  const next = src ?? FRAG_SRC;\n  if (s.material.fragmentShader === next) return;\n  s.material.fragmentShader = next;\n  s.material.needsUpdate = true;\n  for (const inst of s.instances) inst.uniformsDirty = true;\n  wakeLoop();\n}\n\nexport function withSharedRenderer<T>(fn: (s: SharedRenderer) => T): T {\n  return fn(ensureShared());\n}\n\nexport type { SharedRenderer };\n"
        },
        {
          "path": "components/effects/img-fx/upstream/presets/index.ts",
          "target": "@components/effects/img-fx/upstream/presets/index.ts",
          "type": "registry:component",
          "content": "/**\n * Bundled preset configurations for the img-fx effect.\n *\n * Direct ports of the bundled JSON presets in `presets/`:\n *   • preset-pixels-style-3.json  -> pixels-organic  (Chromium Flow)\n *   • preset-pixels-style-4.json  -> pixels-mechanic (Nebula)\n *   • sweep-gradient defaults     -> sweep-gradient  (Gradient Sweep)\n *\n * Each preset ships a `dark` and `light` mode block; the resolved theme picks\n * the right one at runtime.\n *\n * Note: older dot-based presets were removed from the bundled preset surface\n * to keep the package aligned with the demo and the supported public API.\n */\n\nimport { PIXELS_MECHANIC } from './pixels-mechanic';\nimport { PIXELS_ORGANIC } from './pixels-organic';\nimport { SWEEP_GRADIENT } from './sweep-gradient';\n\nexport type PresetName = 'pixels-organic' | 'pixels-mechanic' | 'sweep-gradient';\nexport type PresetTheme = 'dark' | 'light';\n\n/** Per-cell mosaic configuration for pixel-mode rendering. */\nexport interface MosaicConfig {\n  /** Cell-size 0..1; converted in shader to `floor(6 + cellSize*74)` cells. */\n  cellSize: number;\n  /** Inter-cell spacing 0..1. */\n  gap: number;\n  /** Highlight scale boost 0..1. */\n  hlScale: number;\n  /** Background fill opacity. */\n  fillOpacity: number;\n  /** Edge fade band in CSS px. */\n  edgeFade: number;\n  /** Edge fade strength 0..1. */\n  fadeStr: number;\n}\n\n/** Reveal animation tunings (per-mode). */\nexport interface RevealConfig {\n  /** Duration of the shader-based reveal mask animation (sec). */\n  duration: number;\n  /** Easing key applied during the reveal animation. */\n  easing: EasingKey;\n  /** Mask-shape type (geometric or shader-driven). */\n  maskShape: MaskShape;\n  /** Mask edge softness 0..1. */\n  softness: number;\n  /** Max CSS-px blur applied to the mask canvas during reveal. */\n  blur: number;\n  /** Pixel-cell dissolve duration (sec). */\n  pixDuration: number;\n  /** Easing for the pixel-cell dissolve. */\n  pixEasing: EasingKey;\n}\n\nexport type EasingKey =\n  | 'linear'\n  | 'smoothstep'\n  | 'easeOutCubic'\n  | 'easeOutQuint'\n  | 'easeInOutCubic'\n  | 'easeOutExpo'\n  | 'easeOutBack';\n\nexport type MaskShape =\n  | 'shader'\n  | 'shaderHighlight'\n  | 'shaderColor1'\n  | 'shaderColor2'\n  | 'shaderColor3'\n  | 'shaderColor4'\n  | 'shaderColor5'\n  | 'radialCenter'\n  | 'radialCorner'\n  | 'linearTop'\n  | 'linearBottom'\n  | 'linearLeft'\n  | 'linearRight'\n  | 'diagonalTL'\n  | 'diagonalBR'\n  | 'diamond'\n  | 'blindsH'\n  | 'blindsV'\n  | 'gradientSweep';\n\n/** A single theme-mode block of a preset (mirrors the JSON shape). */\nexport interface PresetMode {\n  theme: PresetTheme;\n  effectIndex: number;\n  colors: [string, string, string, string, string, string, string];\n  alphas: [number, number, number, number, number, number, number];\n  cardBg: string;\n  /** 0 = off (raw shader), 1 = pixels. */\n  dotMode: 0 | 1;\n  pixelConfig: MosaicConfig;\n  /** Drift angle (degrees). */\n  direction: number;\n  speed: number;\n  intensity: number;\n  scale: number;\n  softness: number;\n  distortion: number;\n  /** Gradient sweep cell flicker amplitude 0..1. */\n  flicker?: number;\n  complexity: number;\n  shape: number;\n  blur: number;\n  highlight: number;\n  vignette: number;\n  vigOpacity: number;\n  shaderOpacity: number;\n  /** Gradient sweep movement easing type (0..4). */\n  sweepEase?: number;\n  revealConfig: RevealConfig;\n  /** Human-readable effect name for diagnostics. */\n  effect: string;\n}\n\nexport interface Preset {\n  name: PresetName;\n  modes: Record<PresetTheme, PresetMode>;\n}\n\n/* ============================================================ */\n/* Internal engine-only types                                   */\n/* ============================================================ */\n/* The dot renderer is still wired through the engine in case we\n * ever ship a dot-mode preset again, but no bundled preset since\n * 0.2.0 sets `dotMode: 2`, so the dot fields are not part of the\n * public types. Engine code that needs full access (the unreachable\n * `preset.dotMode === 2` branches in reveal.ts / renderer.ts) casts\n * the public `PresetMode` up to `EnginePresetMode` at the boundary.\n *\n * Mark `@internal` so API Extractor / IDE autocomplete keep them\n * out of consumer-facing surfaces. */\n\n/** @internal Full mosaic shape including disc-render fields. */\nexport interface EngineMosaicConfig extends MosaicConfig {\n  /** Per-cell base opacity (dot mode only). */\n  dotOpacity: number;\n  /** Disc radius 0..1 (dot mode only). */\n  dotSize: number;\n  /** Disc edge softness (dot mode only). */\n  dotSoftness: number;\n}\n\n/** @internal Full reveal shape including dot-mode timing. */\nexport interface EngineRevealConfig extends RevealConfig {\n  /** Dot-mode reveal duration (sec). */\n  dotDuration: number;\n  /** Easing for the dot-mode reveal. */\n  dotEasing: EasingKey;\n}\n\n/** @internal Full preset-mode shape used by the engine. */\nexport interface EnginePresetMode extends Omit<PresetMode, 'dotMode' | 'pixelConfig' | 'revealConfig'> {\n  /** 0 = off (raw shader), 1 = pixels, 2 = dots. */\n  dotMode: 0 | 1 | 2;\n  pixelConfig: EngineMosaicConfig;\n  /** Disc mosaic config (only consulted when `dotMode === 2`). */\n  dotConfig: EngineMosaicConfig;\n  revealConfig: EngineRevealConfig;\n}\n\n/** @internal */\nexport interface EnginePreset {\n  name: PresetName;\n  modes: Record<PresetTheme, EnginePresetMode>;\n}\n\n/* Runtime preset map. The underlying object literals (in\n * `pixels-mechanic.ts` / `pixels-organic.ts`) are typed as\n * `EnginePreset` so they can carry the dot-mode fields without TS\n * errors, but the public `PRESETS` is downcast to the narrower\n * `Preset` shape so consumers don't see them in autocomplete /\n * type-info. The cast is sound: every bundled preset uses\n * `dotMode: 1`, which is in both `0 | 1` and `0 | 1 | 2`. */\nconst _PRESETS_INTERNAL: Record<PresetName, EnginePreset> = {\n  'pixels-organic': PIXELS_ORGANIC,\n  'pixels-mechanic': PIXELS_MECHANIC,\n  'sweep-gradient': SWEEP_GRADIENT\n};\n\nexport const PRESETS = _PRESETS_INTERNAL as unknown as Record<PresetName, Preset>;\n\n/** @internal Engine-only accessor that returns the full preset\n * shape (including the dot-mode fields hidden from the public\n * `PRESETS` map). Lets engine code keep its `preset.dotMode === 2`\n * branches intact without per-call casts. */\nexport function _getEnginePreset(name: PresetName): EnginePreset {\n  return _PRESETS_INTERNAL[name];\n}\n\n/**\n * `#rrggbb` -> normalized [r, g, b] in 0..1.\n *\n * @deprecated Use {@link parseCssColor} instead. `hexToRgb` only handles\n * `#rgb` / `#rrggbb` input — passing anything else (e.g. `rgba(...)`,\n * a colour name, `hsl(...)`) produces `NaN` channels and breaks shader\n * uniforms. Kept exported for backward compatibility; internal callers\n * now route through `parseCssColor`.\n */\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace('#', '');\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n  return [\n    parseInt(h.slice(0, 2), 16) / 255,\n    parseInt(h.slice(2, 4), 16) / 255,\n    parseInt(h.slice(4, 6), 16) / 255\n  ];\n}\n\n/**\n * Cached singleton 2D context. We delegate non-hex parsing to the browser's\n * own CSS colour parser by writing into `ctx.fillStyle` and reading back the\n * canonical form. Allocated once per page, reused for every parse call.\n */\nlet _colorCtx: CanvasRenderingContext2D | null | undefined;\nfunction getColorCtx(): CanvasRenderingContext2D | null {\n  if (_colorCtx !== undefined) return _colorCtx;\n  if (typeof document === 'undefined') {\n    _colorCtx = null;\n    return null;\n  }\n  const c = document.createElement('canvas');\n  c.width = 1;\n  c.height = 1;\n  _colorCtx = c.getContext('2d');\n  return _colorCtx;\n}\n\n/**\n * Parse any CSS colour string to normalised `[r, g, b]` in 0..1.\n *\n * Accepts every value the host browser understands: hex (`#rgb`,\n * `#rrggbb`, `#rrggbbaa`), `rgb()` / `rgba()`, `hsl()` / `hsla()`, named\n * colours (`white`, `crimson`, …), and modern syntaxes like\n * `color(display-p3 …)`.\n *\n * **Alpha is dropped.** The shader's `u_cardBg` uniform is opaque RGB —\n * the renderer has no source for what's behind the card, so it can't\n * composite a translucent background colour correctly. The wrapper's CSS\n * `background` keeps the original string with its alpha intact, so\n * visually the card surface stays translucent; the shader's contrast /\n * proximity logic just uses the underlying opaque tint. If precise shader\n * behaviour matters, pass the opaque colour you actually want the shader\n * to reason against.\n *\n * Hex strings take a synchronous fast path that works in SSR. Everything\n * else needs the browser; if no canvas is available (Node, broken DOM) or\n * the input is unparseable, falls back to `[0, 0, 0]` (black).\n */\nexport function parseCssColor(input: string): [number, number, number] {\n  if (typeof input !== 'string' || input.length === 0) return [0, 0, 0];\n\n  // Hex fast path — synchronous, SSR-friendly, no DOM dependency.\n  if (input[0] === '#') {\n    let h = input.slice(1);\n    if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n    if ((h.length === 6 || h.length === 8) && /^[0-9a-fA-F]+$/.test(h)) {\n      return [\n        parseInt(h.slice(0, 2), 16) / 255,\n        parseInt(h.slice(2, 4), 16) / 255,\n        parseInt(h.slice(4, 6), 16) / 255\n      ];\n    }\n  }\n\n  // Anything else: delegate to the browser. `ctx.fillStyle = badInput`\n  // silently rejects and keeps the previous value, so probe with TWO\n  // distinct sentinels — invalid input will preserve whichever sentinel\n  // was set, while valid input canonicalises to the same string both\n  // times. A single sentinel would give a false rejection whenever the\n  // user's input happened to canonicalise to that same sentinel (e.g.\n  // `'magenta'` -> `'#ff00ff'`).\n  const ctx = getColorCtx();\n  if (!ctx) return [0, 0, 0];\n\n  ctx.fillStyle = '#000000';\n  ctx.fillStyle = input;\n  const after1 = ctx.fillStyle as string;\n  ctx.fillStyle = '#ffffff';\n  ctx.fillStyle = input;\n  const after2 = ctx.fillStyle as string;\n  if (after1 !== after2) {\n    // Input was rejected — readback equals whichever sentinel was set.\n    return [0, 0, 0];\n  }\n  const out = after1;\n\n  if (out[0] === '#') {\n    return [\n      parseInt(out.slice(1, 3), 16) / 255,\n      parseInt(out.slice(3, 5), 16) / 255,\n      parseInt(out.slice(5, 7), 16) / 255\n    ];\n  }\n  const m = out.match(/^rgba?\\(\\s*(-?[\\d.]+)\\s*,\\s*(-?[\\d.]+)\\s*,\\s*(-?[\\d.]+)/);\n  if (m) {\n    const clamp = (n: number): number => Math.max(0, Math.min(255, n)) / 255;\n    return [clamp(parseFloat(m[1])), clamp(parseFloat(m[2])), clamp(parseFloat(m[3]))];\n  }\n  return [0, 0, 0];\n}\n\nexport { PIXELS_ORGANIC, PIXELS_MECHANIC, SWEEP_GRADIENT };\n"
        },
        {
          "path": "components/effects/img-fx/upstream/presets/pixels-mechanic.ts",
          "target": "@components/effects/img-fx/upstream/presets/pixels-mechanic.ts",
          "type": "registry:component",
          "content": "/**\n * Direct port of `presets/preset-pixels-style-4.json`.\n * Pixel renderer + Nebula effect (mechanical / structured pixel mosaic).\n */\nimport type { EnginePreset } from './index';\n\nexport const PIXELS_MECHANIC: EnginePreset = {\n  name: 'pixels-mechanic',\n  modes: {\n    dark: {\n      theme: 'dark',\n      effectIndex: 11,\n      colors: ['#949494', '#2d2d2d', '#333333', '#3a3a3a', '#0b0b0b', '#060606', '#2f2f2f'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      cardBg: '#0f0f0f',\n      dotMode: 1,\n      pixelConfig: {\n        cellSize: 0.22,\n        gap: 0.14,\n        dotOpacity: 0.68,\n        dotSize: 0.8,\n        dotSoftness: 0.1,\n        hlScale: 0.8,\n        fillOpacity: 0.44,\n        edgeFade: 24,\n        fadeStr: 1\n      },\n      dotConfig: {\n        cellSize: 0.58,\n        gap: 0,\n        dotOpacity: 1,\n        dotSize: 0.22,\n        dotSoftness: 0.1,\n        hlScale: 0.26,\n        fillOpacity: 0,\n        edgeFade: 34,\n        fadeStr: 0.34\n      },\n      direction: 0,\n      speed: 0.7,\n      intensity: 1,\n      scale: 1.4,\n      softness: 0.76,\n      distortion: 0.3,\n      flicker: 0.5,\n      complexity: 0.2,\n      shape: 0.52,\n      blur: 1,\n      highlight: 0.32,\n      vignette: 0.26,\n      vigOpacity: 1,\n      shaderOpacity: 1,\n      revealConfig: {\n        duration: 3,\n        easing: 'easeOutCubic',\n        maskShape: 'shaderColor4',\n        softness: 0.5,\n        blur: 0,\n        pixDuration: 2.65,\n        pixEasing: 'easeOutCubic',\n        dotDuration: 2.05,\n        dotEasing: 'easeOutCubic'\n      },\n      effect: 'Nebula'\n    },\n    light: {\n      theme: 'light',\n      effectIndex: 11,\n      colors: ['#e0e0e0', '#fdfdfd', '#f2f2f2', '#0a0a0a', '#dcdcdc', '#f5f5f5', '#f5f5f5'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      cardBg: '#f5f5f5',\n      dotMode: 1,\n      pixelConfig: {\n        cellSize: 0.22,\n        gap: 0.14,\n        dotOpacity: 0.68,\n        dotSize: 0.8,\n        dotSoftness: 0.1,\n        hlScale: 0.8,\n        fillOpacity: 0.18,\n        edgeFade: 20,\n        fadeStr: 1\n      },\n      dotConfig: {\n        cellSize: 0.58,\n        gap: 0,\n        dotOpacity: 1,\n        dotSize: 0.22,\n        dotSoftness: 0.1,\n        hlScale: 0.26,\n        fillOpacity: 0,\n        edgeFade: 34,\n        fadeStr: 0.34\n      },\n      direction: 25,\n      speed: 0.55,\n      intensity: 0.85,\n      scale: 0.9,\n      softness: 0.76,\n      distortion: 0.3,\n      flicker: 0.5,\n      complexity: 0.2,\n      shape: 0.52,\n      blur: 1,\n      highlight: 0.92,\n      vignette: 0,\n      vigOpacity: 0,\n      shaderOpacity: 1,\n      revealConfig: {\n        duration: 3,\n        easing: 'easeOutCubic',\n        maskShape: 'shaderColor3',\n        softness: 0.5,\n        blur: 0,\n        pixDuration: 2.6,\n        pixEasing: 'easeOutCubic',\n        dotDuration: 2.05,\n        dotEasing: 'easeOutCubic'\n      },\n      effect: 'Nebula'\n    }\n  }\n};\n"
        },
        {
          "path": "components/effects/img-fx/upstream/presets/pixels-organic.ts",
          "target": "@components/effects/img-fx/upstream/presets/pixels-organic.ts",
          "type": "registry:component",
          "content": "/**\n * Direct port of `presets/preset-pixels-style-3.json`.\n * Pixel renderer + Chromium Flow effect (organic chrome ridges).\n */\nimport type { EnginePreset } from './index';\n\nexport const PIXELS_ORGANIC: EnginePreset = {\n  name: 'pixels-organic',\n  modes: {\n    dark: {\n      theme: 'dark',\n      effectIndex: 22,\n      colors: ['#0f0f0f', '#4a4949', '#b9b9b9', '#0f0f0f', '#d8d8d8', '#0f0f0f', '#2f2f2f'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      cardBg: '#0f0f0f',\n      dotMode: 1,\n      pixelConfig: {\n        cellSize: 0.22,\n        gap: 0.14,\n        dotOpacity: 0.68,\n        dotSize: 0.8,\n        dotSoftness: 0.1,\n        hlScale: 0.8,\n        fillOpacity: 0.44,\n        edgeFade: 24,\n        fadeStr: 1\n      },\n      dotConfig: {\n        cellSize: 0.58,\n        gap: 0,\n        dotOpacity: 1,\n        dotSize: 0.22,\n        dotSoftness: 0.1,\n        hlScale: 0.26,\n        fillOpacity: 0,\n        edgeFade: 34,\n        fadeStr: 0.34\n      },\n      direction: 0,\n      speed: 0.3,\n      intensity: 1,\n      scale: 1,\n      softness: 0.76,\n      distortion: 0.3,\n      complexity: 0.2,\n      shape: 0.52,\n      blur: 1,\n      highlight: 0.2,\n      vignette: 0.26,\n      vigOpacity: 1,\n      shaderOpacity: 1,\n      revealConfig: {\n        duration: 3,\n        easing: 'easeOutCubic',\n        maskShape: 'shaderColor4',\n        softness: 0.5,\n        blur: 0,\n        pixDuration: 2.65,\n        pixEasing: 'easeOutCubic',\n        dotDuration: 2.05,\n        dotEasing: 'easeOutCubic'\n      },\n      effect: 'Chromium Flow'\n    },\n    light: {\n      theme: 'light',\n      effectIndex: 22,\n      colors: ['#e3e3e3', '#ffffff', '#f5f5f5', '#f5f5f5', '#080808', '#f5f5f5', '#f5f5f5'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      cardBg: '#f5f5f5',\n      dotMode: 1,\n      pixelConfig: {\n        cellSize: 0.22,\n        gap: 0.14,\n        dotOpacity: 0.68,\n        dotSize: 0.8,\n        dotSoftness: 0.1,\n        hlScale: 0.8,\n        fillOpacity: 0.18,\n        edgeFade: 20,\n        fadeStr: 1\n      },\n      dotConfig: {\n        cellSize: 0.58,\n        gap: 0,\n        dotOpacity: 1,\n        dotSize: 0.22,\n        dotSoftness: 0.1,\n        hlScale: 0.26,\n        fillOpacity: 0,\n        edgeFade: 34,\n        fadeStr: 0.34\n      },\n      direction: 25,\n      speed: 0.3,\n      intensity: 0.85,\n      scale: 1,\n      softness: 0.76,\n      distortion: 0.3,\n      complexity: 0.2,\n      shape: 0.52,\n      blur: 1,\n      highlight: 0.7,\n      vignette: 0,\n      vigOpacity: 0,\n      shaderOpacity: 1,\n      revealConfig: {\n        duration: 3,\n        easing: 'easeOutCubic',\n        maskShape: 'shaderColor4',\n        softness: 0.5,\n        blur: 0,\n        pixDuration: 2.55,\n        pixEasing: 'easeOutCubic',\n        dotDuration: 2.05,\n        dotEasing: 'easeOutCubic'\n      },\n      effect: 'Chromium Flow'\n    }\n  }\n};\n"
        },
        {
          "path": "components/effects/img-fx/upstream/presets/sweep-gradient.ts",
          "target": "@components/effects/img-fx/upstream/presets/sweep-gradient.ts",
          "type": "registry:component",
          "content": "import type { EnginePreset } from './index';\n\nexport const SWEEP_GRADIENT: EnginePreset = {\n  name: 'sweep-gradient',\n  modes: {\n    dark: {\n      theme: 'dark',\n      effectIndex: 25,\n      colors: ['#0f0f0f', '#0f0f0f', '#282828', '#3a3a3a', '#525252', '#0f0f0f', '#0f0f0f'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      cardBg: '#0f0f0f',\n      dotMode: 1,\n      pixelConfig: {\n        cellSize: 0.22,\n        gap: 0.14,\n        dotOpacity: 0.68,\n        dotSize: 0.8,\n        dotSoftness: 0.1,\n        hlScale: 0.8,\n        fillOpacity: 0.44,\n        edgeFade: 24,\n        fadeStr: 1\n      },\n      dotConfig: {\n        cellSize: 0.58,\n        gap: 0,\n        dotOpacity: 1,\n        dotSize: 0.22,\n        dotSoftness: 0.1,\n        hlScale: 0.26,\n        fillOpacity: 0,\n        edgeFade: 34,\n        fadeStr: 0.34\n      },\n      direction: 0,\n      speed: 2.65,\n      intensity: 1,\n      scale: 1,\n      softness: 0.76,\n      distortion: 0.3,\n      flicker: 0.5,\n      complexity: 0.2,\n      shape: 0.52,\n      blur: 1,\n      highlight: 0.32,\n      vignette: 0.26,\n      vigOpacity: 1,\n      shaderOpacity: 1,\n      sweepEase: 1,\n      revealConfig: {\n        duration: 3,\n        easing: 'easeOutCubic',\n        maskShape: 'gradientSweep',\n        softness: 0.5,\n        blur: 0,\n        pixDuration: 2.65,\n        pixEasing: 'easeOutCubic',\n        dotDuration: 2.05,\n        dotEasing: 'easeOutCubic'\n      },\n      effect: 'Gradient Sweep'\n    },\n    light: {\n      theme: 'light',\n      effectIndex: 25,\n      colors: ['#f5f5f5', '#f5f5f5', '#ededed', '#eaeaea', '#d2d2d2', '#f5f5f5', '#f5f5f5'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      cardBg: '#f5f5f5',\n      dotMode: 1,\n      pixelConfig: {\n        cellSize: 0.22,\n        gap: 0.14,\n        dotOpacity: 0.68,\n        dotSize: 0.8,\n        dotSoftness: 0.1,\n        hlScale: 0.8,\n        fillOpacity: 0.18,\n        edgeFade: 20,\n        fadeStr: 1\n      },\n      dotConfig: {\n        cellSize: 0.58,\n        gap: 0,\n        dotOpacity: 1,\n        dotSize: 0.22,\n        dotSoftness: 0.1,\n        hlScale: 0.26,\n        fillOpacity: 0,\n        edgeFade: 34,\n        fadeStr: 0.34\n      },\n      direction: 0,\n      speed: 2.65,\n      intensity: 0.85,\n      scale: 1,\n      softness: 0.76,\n      distortion: 0.3,\n      flicker: 0.5,\n      complexity: 0.2,\n      shape: 0.52,\n      blur: 1,\n      highlight: 0.92,\n      vignette: 0,\n      vigOpacity: 0,\n      shaderOpacity: 1,\n      sweepEase: 1,\n      revealConfig: {\n        duration: 3,\n        easing: 'easeOutCubic',\n        maskShape: 'gradientSweep',\n        softness: 0.5,\n        blur: 0,\n        pixDuration: 2.6,\n        pixEasing: 'easeOutCubic',\n        dotDuration: 2.05,\n        dotEasing: 'easeOutCubic'\n      },\n      effect: 'Gradient Sweep'\n    }\n  }\n};\n"
        },
        {
          "path": "components/effects/img-fx/upstream/engine/shaders.ts",
          "target": "@components/effects/img-fx/upstream/engine/shaders.ts",
          "type": "registry:component",
          "content": "/**\n * Vertex + fragment shader sources lifted byte-for-byte from `image.html`\n * (lines 961–1548). All 24 effect branches are kept so future presets can\n * select any of them without re-touching the shader.\n */\n\nexport const VERT_SRC = /* glsl */ `\n  void main() { gl_Position = vec4(position.xy, 0.0, 1.0); }\n`;\n\nexport const FRAG_SRC = /* glsl */ `\n  uniform vec2 u_resolution;\n  uniform float u_dpr;\n  uniform float u_time;\n  uniform vec3 u_color1, u_color2, u_color3, u_color4, u_color5, u_color6, u_color7, u_cardBg;\n  uniform float u_alpha1, u_alpha2, u_alpha3, u_alpha4, u_alpha5, u_alpha6, u_alpha7;\n  uniform float u_speed, u_intensity, u_scale, u_direction;\n  uniform float u_softness, u_distortion, u_complexity, u_shape, u_flicker;\n  uniform float u_vignette, u_vigOpacity, u_blur, u_highlight, u_shaderOpacity;\n  uniform float u_cellSize, u_gap, u_dotSize, u_dotSoftness, u_dotOpacity, u_hlScale, u_fillOpacity, u_edgeFade, u_fadeStr;\n  uniform float u_dotMode;\n  uniform int u_effect;\n  uniform int u_sweepEase;\n\n  // Reference card edge length (CSS px) at which the original preset cellSize\n  // gives the canonical cell count. Cell PIXEL size stays constant across card\n  // sizes by scaling gridSize proportionally to (currentCssDim / REF_DIM).\n  const float REF_DIM = 320.0;\n\n  /** Anisotropic cell count: returns the number of cells along x and y so that\n   *  each cell stays SQUARE in screen space regardless of the card's aspect\n   *  ratio. A 600×300 card gets twice as many cells horizontally as vertically;\n   *  cells stay the same physical size as on a 300×300 card. */\n  vec2 gridCounts(float baseCount) {\n    vec2 cssRes = u_resolution / max(u_dpr, 0.0001);\n    return max(vec2(2.0), floor(baseCount * cssRes / REF_DIM));\n  }\n\n  vec3 mod289(vec3 x) { return x - floor(x * (1.0/289.0)) * 289.0; }\n  vec2 mod289v2(vec2 x) { return x - floor(x * (1.0/289.0)) * 289.0; }\n  vec3 permute(vec3 x) { return mod289((x * 34.0 + 1.0) * x); }\n\n  float snoise(vec2 v) {\n    const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n    vec2 i = floor(v + dot(v, C.yy));\n    vec2 x0 = v - i + dot(i, C.xx);\n    vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n    vec4 x12 = x0.xyxy + C.xxzz;\n    x12.xy -= i1;\n    i = mod289v2(i);\n    vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));\n    vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n    m = m * m; m = m * m;\n    vec3 x_ = 2.0 * fract(p * C.www) - 1.0;\n    vec3 h = abs(x_) - 0.5;\n    vec3 ox = floor(x_ + 0.5);\n    vec3 a0 = x_ - ox;\n    m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);\n    vec3 g;\n    g.x = a0.x * x0.x + h.x * x0.y;\n    g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n    return 130.0 * dot(m, g);\n  }\n\n  float fbm(vec2 p, float oct) {\n    float val = 0.0, amp = 0.5;\n    int n = int(oct);\n    for (int i = 0; i < 4; i++) {\n      if (i >= n) break;\n      val += amp * snoise(p);\n      p *= 2.0;\n      amp *= 0.5;\n    }\n    return val;\n  }\n\n  float nfbm(vec2 p) { return fbm(p, 2.0 + u_complexity * 2.0); }\n\n  vec3 palette(float t) {\n    t = clamp(t, 0.0, 1.0);\n    t = t * t * (3.0 - 2.0 * t);\n    float k = 64.0;\n    float w1 = u_alpha1 * exp(-k * t * t);\n    float w2 = u_alpha2 * exp(-k * (t - 0.25) * (t - 0.25));\n    float w3 = u_alpha3 * exp(-k * (t - 0.5)  * (t - 0.5));\n    float w4 = u_alpha4 * exp(-k * (t - 0.75) * (t - 0.75));\n    float w5 = u_alpha5 * exp(-k * (t - 1.0)  * (t - 1.0));\n    float total = w1 + w2 + w3 + w4 + w5 + 0.0001;\n    return (u_color1*w1 + u_color2*w2 + u_color3*w3 + u_color4*w4 + u_color5*w5) / total;\n  }\n\n  vec3 softBlend(float a, float b, float c) {\n    a = clamp(a, 0.0, 1.0); a *= a;\n    b = clamp(b, 0.0, 1.0); b *= b;\n    c = clamp(c, 0.0, 1.0); c *= c;\n    float d = clamp(a * 0.7 + c * 0.3, 0.0, 1.0); d *= d;\n    float e = clamp(b * 0.5 + c * 0.5, 0.0, 1.0); e *= e;\n    a *= u_alpha1; b *= u_alpha2; c *= u_alpha3; d *= u_alpha4; e *= u_alpha5;\n    float total = a + b + c + d + e;\n    float floorW = max(0.001 - total, 0.0);\n    vec3 fallback = (u_color1 + u_color2 + u_color3 + u_color4 + u_color5) * 0.2;\n    return (u_color1 * a + u_color2 * b + u_color3 * c + u_color4 * d + u_color5 * e + fallback * floorW) / (total + floorW);\n  }\n\n  vec2 warp(vec2 p, float t) {\n    float str = u_distortion * 2.0;\n    return vec2(\n      nfbm(p + vec2(t * 0.1, 0.0)),\n      nfbm(p + vec2(0.0, t * 0.12) + 5.0)\n    ) * str;\n  }\n\n  float sweepEase(float x) {\n    if (u_sweepEase == 1) return x * x * (3.0 - 2.0 * x);\n    if (u_sweepEase == 2) {\n      float p = 1.0 - x;\n      return 1.0 - p * p * p;\n    }\n    if (u_sweepEase == 3) {\n      return x < 0.5 ? 4.0 * x * x * x : 1.0 - pow(-2.0 * x + 2.0, 3.0) * 0.5;\n    }\n    if (u_sweepEase == 4) return 1.0 - pow(2.0, -10.0 * x) * (1.0 - x);\n    return x;\n  }\n\n  float blob(vec2 p, vec2 center, float radius) {\n    float r = radius * (0.5 + u_shape * 0.8);\n    float soft = 0.05 + u_softness * 0.4;\n    return smoothstep(r + soft, r - soft * 0.5, length(p - center));\n  }\n\n  vec3 computeEffect(vec2 uv, float aspect, float t, float dist, float soft, float cpx, float shp) {\n    vec2 p = (uv - 0.5) * u_scale;\n    p.x *= aspect;\n    p += vec2(cos(u_direction), sin(u_direction)) * t * 0.15;\n    vec3 col = vec3(0.0);\n\n    if (u_effect == 0) {\n      float val = sin(p.x * 3.0 + t) * 0.5 + 0.5;\n      val += sin(p.y * 2.0 + t * 0.7) * 0.3;\n      val += sin((p.x + p.y) * (1.0 + cpx * 3.0) - t * 0.5) * 0.2;\n      vec2 w = warp(p, t);\n      val += (w.x + w.y) * 0.15;\n      col = palette(clamp(val * u_intensity, 0.0, 1.0));\n\n    } else if (u_effect == 1) {\n      float freq = 3.0 + cpx * 8.0;\n      float val = 0.0;\n      val += sin(p.x * freq + t);\n      val += sin(p.y * freq + t * 1.3);\n      val += sin((p.x + p.y) * freq * 0.7 + t * 0.7);\n      val += sin(length(p) * freq * 0.8 - t * 1.5);\n      vec2 w = warp(p, t);\n      val += (w.x + w.y) * dist;\n      val = val * 0.2 * u_intensity + 0.5;\n      col = palette(clamp(val, 0.0, 1.0));\n\n    } else if (u_effect == 2) {\n      vec2 q = vec2(nfbm(p + t * 0.3), nfbm(p + vec2(5.2, 1.3) + t * 0.2));\n      float val = nfbm(p + q * (1.0 + dist * 3.0) + t * 0.1);\n      val = val * u_intensity * 0.5 + 0.5;\n      col = palette(clamp(val, 0.0, 1.0));\n\n    } else if (u_effect == 3) {\n      float d = length(p);\n      float val = sin(d * (3.0 + cpx * 6.0) - t * 2.0) * 0.5 + 0.5;\n      val *= exp(-d * (0.3 + shp * 1.0));\n      val += sin(atan(p.y, p.x) * (1.5 + cpx * 2.0) + t) * 0.15;\n      col = palette(clamp(val * u_intensity, 0.0, 1.0));\n\n    } else if (u_effect == 4) {\n      vec2 q = vec2(nfbm(p * (0.5 + shp * 0.6) + vec2(t * 0.12, t * 0.08)), nfbm(p * (0.5 + shp * 0.6) + vec2(t * 0.09, -t * 0.11)));\n      vec2 r = vec2(nfbm(p + q * (1.0 + dist * 2.0) + vec2(1.7, 9.2) + t * 0.06), nfbm(p + q * (1.0 + dist * 2.0) + vec2(8.3, 2.8) - t * 0.08));\n      float val = nfbm(p + r * 2.0);\n      float lo = -0.3 - soft * 0.5;\n      float hi = 0.5 + soft * 0.5;\n      val = smoothstep(lo, hi, val * u_intensity);\n      col = palette(val);\n\n    } else if (u_effect == 5) {\n      float n1 = nfbm(vec2(p.x * 0.5 + t * 0.15, p.y * (1.0 + cpx * 1.5)));\n      float n2 = nfbm(vec2(p.x * 0.3 - t * 0.1, p.y * (0.8 + cpx * 1.0) + 3.0));\n      float band = sin(p.y * 3.0 + n1 * (1.0 + dist * 2.0) + t * 0.3) * 0.5 + 0.5;\n      float shimmer = sin(p.y * 4.0 + n2 * 1.5 - t * 0.2) * 0.5 + 0.5;\n      float w1 = band * (0.5 + 0.5 * sin(p.x * 1.5 + t * 0.2 + n1));\n      float w2 = shimmer * (0.5 + 0.5 * cos(p.x * 1.0 - t * 0.15 + n2));\n      float w3 = nfbm(p * 0.5 + t * 0.05) * 0.5 + 0.5;\n      col = softBlend(w1 * u_intensity, w2 * u_intensity, w3 * 0.6 * u_intensity);\n\n    } else if (u_effect == 6) {\n      vec2 wp = warp(p * 1.2, t);\n      float blobR = 0.15 + shp * 0.2;\n      float b1 = blob(p, vec2(sin(t * 0.3) * 0.3, cos(t * 0.2) * 0.4) + wp * 0.2, blobR);\n      float b2 = blob(p, vec2(cos(t * 0.25) * 0.4, sin(t * 0.35) * 0.3 - 0.2) + wp * 0.15, blobR * 1.2);\n      float b3 = blob(p, vec2(-sin(t * 0.2) * 0.3, -cos(t * 0.3) * 0.35) + wp * 0.18, blobR);\n      float bg = nfbm(p * 0.5 + t * 0.05) * 0.3 + 0.15;\n      col = softBlend((b1 + bg * 0.5) * u_intensity, (b2 + bg * 0.3) * u_intensity, (b3 + bg * 0.4) * u_intensity);\n\n    } else if (u_effect == 7) {\n      float sz = 0.4 + shp * 0.6;\n      float sigma = sz * sz * 2.0;\n      vec2 a1 = vec2(-0.45 + sin(t * 0.07) * 0.06, 0.45 + cos(t * 0.09) * 0.05);\n      vec2 a2 = vec2(0.45 + cos(t * 0.08) * 0.06, 0.45 + sin(t * 0.06) * 0.05);\n      vec2 a3 = vec2(0.0 + sin(t * 0.05) * 0.1, 0.0 + cos(t * 0.07) * 0.1);\n      vec2 a4 = vec2(-0.4 + cos(t * 0.06) * 0.07, -0.3 + sin(t * 0.08) * 0.06);\n      vec2 a5 = vec2(0.4 + sin(t * 0.07) * 0.06, -0.4 + cos(t * 0.05) * 0.06);\n      float g1 = exp(-dot(p - a1, p - a1) / sigma);\n      float g2 = exp(-dot(p - a2, p - a2) / sigma);\n      float g3 = exp(-dot(p - a3, p - a3) / sigma);\n      float g4 = exp(-dot(p - a4, p - a4) / sigma);\n      float g5 = exp(-dot(p - a5, p - a5) / sigma);\n      float nudge = dist > 0.01 ? snoise(p * (0.5 + cpx) + t * 0.04) * dist * 0.08 : 0.0;\n      float w1 = (g1 + g4 + nudge) * u_intensity;\n      float w2 = (g2 + g5 + nudge) * u_intensity;\n      float w3 = (g3 + nudge) * u_intensity;\n      col = softBlend(w1, w2, w3);\n\n    } else if (u_effect == 8) {\n      vec2 w1 = vec2(nfbm(p * (0.7 + cpx * 0.5) + t * 0.1), nfbm(p * (0.7 + cpx * 0.5) + vec2(3.3, 7.7) + t * 0.08));\n      vec2 w2 = vec2(nfbm(p * 0.6 + w1 * (1.0 + dist) + t * 0.06), nfbm(p * 0.6 + w1 * (1.0 + dist) + vec2(1.7, 4.2) - t * 0.07));\n      float f1 = nfbm(p + w2 * 1.5);\n      float f2 = nfbm(p + w2 * 1.5 + vec2(4.1, 2.3));\n      float f3 = nfbm(p + w2 * 1.5 + vec2(7.5, 6.1));\n      col = softBlend((f1 * 0.5 + 0.5) * u_intensity, (f2 * 0.5 + 0.5) * u_intensity, (f3 * 0.5 + 0.5) * u_intensity);\n\n    } else if (u_effect == 9) {\n      vec2 sw = vec2(sin(p.y * 2.0 + t * 0.3) * 0.15 + snoise(p * 1.5 + t * 0.15) * dist * 0.3, cos(p.x * 1.8 + t * 0.25) * 0.15 + snoise(p * 1.5 + vec2(5.0, 0.0) + t * 0.12) * dist * 0.3);\n      vec2 wp = p + sw;\n      float caustic = (snoise(wp * (1.5 + cpx * 2.0) + t * 0.2) * 0.5 + 0.5) + (snoise(wp * (2.0 + cpx * 2.0) - t * 0.15) * 0.5 + 0.5) * 0.5;\n      caustic = caustic / 1.5;\n      float depth = nfbm(vec2(p.x * 0.3, p.y * 0.8) + t * 0.05) * 0.5 + 0.5;\n      col = softBlend(depth * u_intensity, (1.0 - depth) * u_intensity, caustic * u_intensity);\n\n    } else if (u_effect == 10) {\n      float angle = 0.6 + shp * 1.2;\n      float ca = cos(angle), sa = sin(angle);\n      vec2 rp = vec2(p.x * ca - p.y * sa, p.x * sa + p.y * ca);\n      float n1 = nfbm(rp * 0.8 + t * 0.12) * (1.0 + dist * 2.0);\n      float n2 = nfbm(rp * 0.6 + vec2(3.0, 0.0) + t * 0.1) * (1.0 + dist * 1.5);\n      float wave = sin(rp.x * (2.0 + cpx * 2.0) + n1 + t * 0.3);\n      float wave2 = sin(rp.x * (1.5 + cpx * 1.5) + n2 - t * 0.2);\n      float ribbon1 = exp(-2.0 * (rp.y - wave * 0.35) * (rp.y - wave * 0.35)) * u_intensity;\n      float ribbon2 = exp(-2.0 * (rp.y - 0.15 - wave2 * 0.3) * (rp.y - 0.15 - wave2 * 0.3)) * u_intensity;\n      float bg = nfbm(p * 0.4 + t * 0.03) * 0.5 + 0.5;\n      col = softBlend(ribbon1, ribbon2, bg * 0.5 * u_intensity);\n\n    } else if (u_effect == 11) {\n      vec2 q = vec2(nfbm(p * 0.5 + vec2(t * 0.05, 0.0)), nfbm(p * 0.5 + vec2(0.0, t * 0.07)));\n      vec2 r = vec2(nfbm(p * 0.6 + q * (1.0 + dist * 1.5) + vec2(1.7, 9.2) + t * 0.03), nfbm(p * 0.6 + q * (1.0 + dist * 1.5) + vec2(8.3, 2.8) + t * 0.04));\n      float f = nfbm(p + r * 1.5);\n      float f2 = nfbm(p * 0.7 + r + vec2(3.0, 7.0));\n      col = softBlend((f * 0.5 + 0.5) * u_intensity, (f2 * 0.5 + 0.5) * u_intensity, (nfbm(p * 0.4 - t * 0.02) * 0.5 + 0.5) * u_intensity);\n\n    } else if (u_effect == 12) {\n      vec2 w = warp(p * 0.5, t * 0.7);\n      float fold1 = sin(p.x * (1.5 + cpx * 2.0) + w.x * 1.5 + t * 0.2) * 0.5 + 0.5;\n      float fold2 = sin(p.y * (1.2 + cpx * 1.5) + w.y * 1.5 - t * 0.15) * 0.5 + 0.5;\n      float fold3 = sin((p.x - p.y) * (0.8 + cpx * 0.8) + (w.x + w.y) + t * 0.1) * 0.5 + 0.5;\n      col = softBlend(fold1 * u_intensity, fold2 * u_intensity, fold3 * 0.7 * u_intensity);\n\n    } else if (u_effect == 13) {\n      float spread = 0.25 + shp * 0.35;\n      vec2 w = warp(p, t * 0.5);\n      vec2 c1 = vec2(sin(t * 0.08) * spread, cos(t * 0.11) * spread) + w * 0.15;\n      vec2 c2 = vec2(cos(t * 0.09) * spread * 1.3, sin(t * 0.07) * spread) + w * 0.12;\n      vec2 c3 = vec2(-sin(t * 0.1) * spread, -cos(t * 0.08) * spread * 1.2) + w * 0.1;\n      float falloff = 0.3 + soft * 0.7;\n      float d1 = 1.0 - smoothstep(0.0, falloff, length(p - c1 + w * dist * 0.3));\n      float d2 = 1.0 - smoothstep(0.0, falloff, length(p - c2 + w * dist * 0.25));\n      float d3 = 1.0 - smoothstep(0.0, falloff, length(p - c3 + w * dist * 0.2));\n      float detail = nfbm(p * 2.0 + t * 0.05) * cpx * 0.3;\n      col = softBlend((d1 + detail) * u_intensity, (d2 + detail) * u_intensity, (d3 + detail) * u_intensity);\n\n    } else if (u_effect == 14) {\n      vec2 w = warp(p * 0.6, t * 0.6);\n      float angle = atan(p.y + w.y * dist, p.x + w.x * dist);\n      float radius = length(p);\n      float field1 = sin(angle * (2.0 + cpx * 4.0) + radius * (3.0 + cpx * 3.0) + t * 0.4 + nfbm(p + t * 0.1) * dist * 2.0) * 0.5 + 0.5;\n      float field2 = sin(angle * (1.5 + cpx * 2.5) - radius * 2.0 - t * 0.3 + nfbm(p * 0.6 + t * 0.08) * dist * 1.5) * 0.5 + 0.5;\n      float bg = nfbm(p * 0.3 + t * 0.03) * 0.5 + 0.5;\n      col = softBlend(field1 * u_intensity, field2 * u_intensity, bg * 0.5 * u_intensity);\n\n    } else if (u_effect == 15) {\n      vec2 drift = vec2(t * 0.06, t * 0.03);\n      float c1 = nfbm((p + drift) * (0.4 + cpx * 0.5)) * 0.5 + 0.5;\n      float c2 = nfbm((p + drift + vec2(3.7, 1.2)) * (0.35 + cpx * 0.4)) * 0.5 + 0.5;\n      float c3 = nfbm((p + drift + vec2(7.1, 4.5)) * (0.3 + cpx * 0.35)) * 0.5 + 0.5;\n      vec2 w = warp(p * 0.2, t * 0.4);\n      c1 += w.x * dist * 0.3;\n      c2 += w.y * dist * 0.25;\n      col = softBlend(c1 * u_intensity, c2 * u_intensity, c3 * u_intensity);\n\n    } else if (u_effect == 16) {\n      vec2 w = warp(vec2(p.x * 0.3, p.y * 0.6), t * 0.5);\n      float c1 = sin(p.x * (1.5 + cpx * 2.0) + w.x * (1.0 + dist * 2.0) + t * 0.15) * 0.5 + 0.5;\n      float c2 = sin(p.x * (1.0 + cpx * 1.5) + w.y * (1.0 + dist * 1.5) - t * 0.12 + 2.0) * 0.5 + 0.5;\n      float c3 = sin(p.x * (0.8 + cpx * 1.0) + (w.x + w.y) * 0.5 * (1.0 + dist) + t * 0.08 + 4.0) * 0.5 + 0.5;\n      float fade = nfbm(vec2(p.x * 0.3, p.y * 0.5) + t * 0.03) * 0.5 + 0.5;\n      col = softBlend(c1 * fade * u_intensity, c2 * fade * u_intensity, c3 * (1.0 - fade * 0.4) * u_intensity * 0.7);\n\n    } else if (u_effect == 17) {\n      vec2 w = warp(p * 0.8, t * 0.6);\n      vec2 w2 = warp(p * 0.5 + w * 0.4, t * 0.4);\n      float r1 = (snoise((p + w * dist * 0.5) * (1.5 + cpx * 2.0) + t * 0.1) * 0.5 + 0.5) * u_intensity;\n      float r2 = (snoise((p + w2 * dist * 0.4) * (1.2 + cpx * 1.5) + t * 0.08 + 3.0) * 0.5 + 0.5) * u_intensity;\n      float r3 = (snoise((p + (w + w2) * dist * 0.3) * (0.8 + cpx * 1.0) - t * 0.06 + 7.0) * 0.5 + 0.5) * u_intensity;\n      col = softBlend(r1, r2, r3);\n\n    } else if (u_effect == 18) {\n      vec2 w = warp(p * 0.5, t * 0.5);\n      float blobSize = 0.2 + shp * 0.3;\n      float total1 = 0.0, total2 = 0.0;\n      for (int i = 0; i < 5; i++) {\n        float fi = float(i);\n        vec2 c1 = vec2(sin(t * 0.1 + fi * 2.1) * 0.4, cos(t * 0.13 + fi * 1.7) * 0.35) + w * dist * 0.15;\n        vec2 c2 = vec2(cos(t * 0.12 + fi * 1.9) * 0.35, sin(t * 0.09 + fi * 2.3) * 0.4) + w * dist * 0.12;\n        total1 += blobSize * blobSize / (dot(p - c1, p - c1) + 0.02);\n        total2 += blobSize * blobSize / (dot(p - c2, p - c2) + 0.02);\n      }\n      total1 = clamp(total1 * 0.25, 0.0, 1.0);\n      total2 = clamp(total2 * 0.25, 0.0, 1.0);\n      float total3 = nfbm(p + w * dist * 0.3 + t * 0.05) * 0.5 + 0.5;\n      col = softBlend(total1 * u_intensity, total2 * u_intensity, total3 * 0.7 * u_intensity);\n\n    } else if (u_effect == 19) {\n      vec2 w = warp(p * 0.4, t * 0.4);\n      float angle = atan(p.y, p.x);\n      float radius = length(p);\n      float s1 = sin(angle * (1.5 + cpx * 2.0) + radius * (3.0 + cpx * 3.0) + t * 0.3 + w.x * dist * 1.5) * 0.5 + 0.5;\n      float s2 = sin(angle * (1.2 + cpx * 1.5) - radius * (2.5 + cpx * 2.5) - t * 0.25 + w.y * dist * 1.5 + 1.5) * 0.5 + 0.5;\n      float s3 = sin((angle + 3.14) * (0.8 + cpx) + radius * (2.0 + cpx * 2.0) + t * 0.15 + (w.x + w.y) * dist) * 0.5 + 0.5;\n      float fade = exp(-radius * (0.5 - shp * 0.3));\n      col = softBlend(s1 * fade * u_intensity, s2 * fade * u_intensity, s3 * fade * 0.7 * u_intensity);\n\n    } else if (u_effect == 20) {\n      vec2 w = warp(p * 0.5, t * 0.4);\n      vec2 wp = p + w * (0.4 + dist * 0.6);\n      float scale = 0.6 + cpx * 0.8;\n      float h  = nfbm(wp * scale + t * 0.08);\n      float eps = 0.06;\n      float hx = nfbm((wp + vec2(eps, 0.0)) * scale + t * 0.08) - h;\n      float hy = nfbm((wp + vec2(0.0, eps)) * scale + t * 0.08) - h;\n      vec3 n = normalize(vec3(-hx * 6.0, -hy * 6.0, 1.0));\n      vec3 lightDir = normalize(vec3(0.55, 0.65, 0.8));\n      float light = max(dot(n, lightDir), 0.0);\n      float spec = pow(light, 6.0 + shp * 26.0);\n      float diffuse = light * 0.6 + 0.35;\n      float fres = pow(1.0 - max(n.z, 0.0), 2.0);\n      float w1 = (diffuse + spec * 0.5) * u_intensity;\n      float w2 = (h * 0.5 + 0.5 + spec * 0.3 + fres * 0.3) * u_intensity;\n      float w3 = (spec * 1.4 + fres * 0.5) * u_intensity;\n      col = softBlend(w1, w2, w3);\n\n    } else if (u_effect == 21) {\n      vec2 w = warp(p * 0.4, t * 0.3);\n      float angle = 0.2 + shp * 1.3;\n      float ca = cos(angle), sa = sin(angle);\n      vec2 rp = vec2(p.x * ca - p.y * sa, p.x * sa + p.y * ca);\n      float band = sin(rp.y * (3.0 + cpx * 5.0) + w.x * (1.0 + dist * 2.5) + t * 0.35);\n      float ridge = 1.0 - abs(band);\n      ridge = pow(ridge, 5.0 + shp * 10.0);\n      float band2 = sin(rp.y * (2.0 + cpx * 3.0) + w.y * (0.8 + dist * 2.0) - t * 0.22 + 1.4);\n      float ridge2 = 1.0 - abs(band2);\n      ridge2 = pow(ridge2, 3.0 + shp * 8.0);\n      float bg = nfbm(p * 0.45 + t * 0.05) * 0.5 + 0.5;\n      float w1 = (ridge * 1.4 + bg * 0.25) * u_intensity;\n      float w2 = (ridge2 * 1.0 + bg * 0.45) * u_intensity;\n      float w3 = (ridge * 0.5 + ridge2 * 0.5) * u_intensity * 0.8;\n      col = softBlend(w1, w2, w3);\n\n    } else if (u_effect == 22) {\n      vec2 w  = warp(p * 0.7, t * 0.5);\n      vec2 w2 = warp(p * 0.4 + w * 0.3, t * 0.3);\n      vec2 wp = p + w * (0.4 + dist * 0.6);\n      float n1 = snoise(wp * (1.4 + cpx * 1.6) + t * 0.14);\n      float n2 = snoise((wp + w2 * dist * 0.4) * (2.0 + cpx * 2.0) + vec2(3.0, 7.0) - t * 0.1);\n      float ridge1 = 1.0 - abs(n1);\n      ridge1 = pow(ridge1, 5.0 + shp * 12.0);\n      float ridge2 = 1.0 - abs(n2);\n      ridge2 = pow(ridge2, 4.0 + shp * 10.0);\n      float base = (n1 + n2) * 0.25 + 0.5;\n      float w1 = (base * 0.6 + ridge1 * 1.2) * u_intensity;\n      float w2c = ((1.0 - base) * 0.6 + ridge2 * 1.0) * u_intensity;\n      float w3 = (ridge1 * 0.8 + ridge2 * 0.6) * u_intensity;\n      col = softBlend(w1, w2c, w3);\n\n    } else if (u_effect == 23) {\n      float angle = 0.1 + shp * 1.4;\n      float ca = cos(angle), sa = sin(angle);\n      vec2 rp = vec2(p.x * ca - p.y * sa, p.x * sa + p.y * ca);\n      vec2 stretch = vec2(rp.x * (5.0 + cpx * 4.0), rp.y * (0.35 + cpx * 0.3));\n      vec2 sw = warp(stretch * 0.3, t * 0.3) * dist;\n      float n1 = snoise(stretch + sw + t * 0.08);\n      float n2 = snoise(stretch * 1.4 + vec2(2.0, 5.0) + sw - t * 0.06);\n      float streak = 1.0 - abs(n1);\n      streak = pow(streak, 6.0 + shp * 12.0);\n      float streak2 = 1.0 - abs(n2);\n      streak2 = pow(streak2, 4.0 + shp * 8.0);\n      float bg = nfbm(p * 0.4 + t * 0.04) * 0.4 + 0.4;\n      float w1 = (streak * 1.4 + bg * 0.3) * u_intensity;\n      float w2 = (streak2 * 0.9 + bg * 0.5) * u_intensity;\n      float w3 = (streak * 0.7 + streak2 * 0.4) * u_intensity * 0.8;\n      col = softBlend(w1, w2, w3);\n\n    } else if (u_effect == 24) {\n      vec2 w1 = warp(p * 0.55, t * 0.4);\n      vec2 w2 = warp(p * 0.7 + w1 * 0.4, t * 0.3);\n      vec2 wp = p + (w1 + w2) * (0.4 + dist * 0.7);\n\n      float scale = 0.65 + cpx * 0.7;\n      float n1 = nfbm(wp * scale + vec2(0.0, 0.0) + t * 0.10);\n      float n2 = nfbm(wp * scale + vec2(3.7, 5.2) - t * 0.07);\n      float n3 = nfbm(wp * scale + vec2(7.1, 2.3) + t * 0.06);\n      float n4 = nfbm(wp * scale + vec2(1.8, 8.4) - t * 0.08);\n      float n5 = nfbm(wp * scale + vec2(4.9, 1.1) + t * 0.05);\n      float n6 = nfbm(wp * scale + vec2(6.3, 7.8) - t * 0.09);\n      float n7 = nfbm(wp * scale + vec2(2.4, 4.6) + t * 0.04);\n\n      float pw = 2.5 + shp * 5.0;\n      n1 = pow(clamp(n1, 0.0, 1.0), pw);\n      n2 = pow(clamp(n2, 0.0, 1.0), pw);\n      n3 = pow(clamp(n3, 0.0, 1.0), pw);\n      n4 = pow(clamp(n4, 0.0, 1.0), pw);\n      n5 = pow(clamp(n5, 0.0, 1.0), pw);\n      n6 = pow(clamp(n6, 0.0, 1.0), pw);\n      n7 = pow(clamp(n7, 0.0, 1.0), pw);\n\n      float intens = 0.5 + u_intensity * 0.9;\n      float a1 = n1 * u_alpha1 * intens;\n      float a2 = n2 * u_alpha2 * intens;\n      float a3 = n3 * u_alpha3 * intens;\n      float a4 = n4 * u_alpha4 * intens;\n      float a5 = n5 * u_alpha5 * intens;\n      float a6 = n6 * u_alpha6 * intens;\n      float a7 = n7 * u_alpha7 * intens;\n      float total = a1 + a2 + a3 + a4 + a5 + a6 + a7 + 0.001;\n      col = (u_color1 * a1 + u_color2 * a2 + u_color3 * a3 + u_color4 * a4\n           + u_color5 * a5 + u_color6 * a6 + u_color7 * a7) / total;\n\n    } else if (u_effect == 25) {\n      float d = (uv.x + (1.0 - uv.y)) * 0.5;\n      float w = 0.9 / max(u_scale, 0.25);\n      float cyc = t * 0.08;\n      float pA = mix(-w, 1.0 + w, sweepEase(fract(cyc)));\n      float pB = mix(-w, 1.0 + w, sweepEase(fract(cyc + 0.5)));\n      float band = max(\n        clamp(1.0 - abs(d - pA) / w, 0.0, 1.0),\n        clamp(1.0 - abs(d - pB) / w, 0.0, 1.0)\n      );\n      float v = band * u_intensity;\n\n      vec2 ggs = gridCounts(6.0 + u_cellSize * 74.0);\n      if (u_dotMode > 1.5) {\n        ggs = max(vec2(2.0), floor(ggs * (1.0 - u_gap * 0.8)));\n      }\n      vec2 cell = floor(uv * ggs);\n      float clk = t * 1.6;\n      // Wrap the stepped clock to keep sin() arguments small. u_time grows\n      // unbounded over a session; on mediump-float GPUs (older Android, some\n      // iOS) large hash inputs lose precision and the flicker bands/freezes.\n      // mod(x, 1024) keeps the crossfade continuous across the wrap\n      // (step 1023 fades into step 0, whose hash is the next s0).\n      float step0 = mod(floor(clk), 1024.0);\n      float step1 = mod(step0 + 1.0, 1024.0);\n      float fz = smoothstep(0.0, 1.0, fract(clk));\n      float cellSeed = dot(cell, vec2(127.1, 311.7));\n      float r1 = fract(sin(cellSeed + step0 * 17.23) * 43758.5453);\n      float r2 = fract(sin(cellSeed + step1 * 17.23) * 43758.5453);\n      float rnd = mix(r1, r2, fz);\n      v += (rnd - 0.5) * u_flicker * 0.9 * (0.15 + band * 0.85);\n\n      col = palette(clamp(v, 0.0, 1.0));\n    }\n\n    return col;\n  }\n\n  void main() {\n    vec2 uv = gl_FragCoord.xy / u_resolution;\n    float aspect = u_resolution.x / u_resolution.y;\n    float t = u_time * u_speed;\n    float dist = u_distortion;\n    float soft = u_softness;\n    float cpx = u_complexity;\n    float shp = u_shape;\n\n    vec2 sampleUV = uv;\n    if (u_dotMode > 0.5) {\n      vec2 gs = gridCounts(6.0 + u_cellSize * 74.0);\n      if (u_dotMode > 1.5) {\n        gs = max(vec2(2.0), floor(gs * (1.0 - u_gap * 0.8)));\n      }\n      sampleUV = (floor(uv * gs) + vec2(0.5)) / gs;\n    }\n\n    vec3 col;\n    if (u_blur < 0.01) {\n      col = computeEffect(sampleUV, aspect, t, dist, soft, cpx, shp);\n    } else {\n      float r = u_blur * 0.02;\n      col  = computeEffect(sampleUV, aspect, t, dist, soft, cpx, shp) * 0.4;\n      col += computeEffect(sampleUV + vec2( r,  0.0), aspect, t, dist, soft, cpx, shp) * 0.15;\n      col += computeEffect(sampleUV + vec2(-r,  0.0), aspect, t, dist, soft, cpx, shp) * 0.15;\n      col += computeEffect(sampleUV + vec2( 0.0,  r), aspect, t, dist, soft, cpx, shp) * 0.15;\n      col += computeEffect(sampleUV + vec2( 0.0, -r), aspect, t, dist, soft, cpx, shp) * 0.15;\n    }\n\n    vec3 baseCol = col;\n    if (u_dotMode < 0.5) {\n      col = pow(col, vec3(1.3));\n    }\n\n    // CSS-pixel distance to the nearest edge — keeps the vignette / edge-fade\n    // bands a consistent physical width on every side of any aspect ratio.\n    vec2 cssRes = u_resolution / max(u_dpr, 0.0001);\n    vec2 cssCoord = uv * cssRes;\n    float edgeDistPx = min(\n      min(cssCoord.x, cssRes.x - cssCoord.x),\n      min(cssCoord.y, cssRes.y - cssCoord.y)\n    );\n    float vigRangePx = 40.0 * (1.0 + u_vignette * 3.0);\n    float vig = (edgeDistPx * edgeDistPx) / (vigRangePx * vigRangePx);\n    vig = smoothstep(0.0, 1.0, vig);\n    col *= mix(1.0, vig, u_vignette * u_vigOpacity);\n\n    float colorAlpha = (u_alpha1 + u_alpha2 + u_alpha3 + u_alpha4 + u_alpha5) / 5.0;\n    if (colorAlpha < 0.999) {\n      vec3 c1d = col - u_color1, c2d = col - u_color2, c3d = col - u_color3, c4d = col - u_color4, c5d = col - u_color5;\n      float prox1 = exp(-8.0 * dot(c1d, c1d));\n      float prox2 = exp(-8.0 * dot(c2d, c2d));\n      float prox3 = exp(-8.0 * dot(c3d, c3d));\n      float prox4 = exp(-8.0 * dot(c4d, c4d));\n      float prox5 = exp(-8.0 * dot(c5d, c5d));\n      float pTotal = prox1 + prox2 + prox3 + prox4 + prox5 + 0.0001;\n      colorAlpha = (prox1*u_alpha1 + prox2*u_alpha2 + prox3*u_alpha3 + prox4*u_alpha4 + prox5*u_alpha5) / pTotal;\n    }\n    float alpha = colorAlpha;\n\n    if (u_dotMode > 0.5) {\n      vec2 gridSize = gridCounts(6.0 + u_cellSize * 74.0);\n      if (u_dotMode > 1.5) {\n        gridSize = max(vec2(2.0), floor(gridSize * (1.0 - u_gap * 0.8)));\n      }\n      // cellLocal is in [0,1] within each cell. Because gridSize was chosen so\n      // that cell PIXEL size is square, distance / mask math here works in\n      // screen-square units even though we're operating in normalised cell uv.\n      vec2 cellLocal = fract(uv * gridSize);\n\n      float hlFactor = 0.0;\n      if (u_highlight > 0.01 || u_hlScale > 0.01) {\n        vec2 cellCenter = (floor(uv * gridSize) + vec2(0.5)) / gridSize;\n        vec2 cp2 = (cellCenter - 0.5) * u_scale;\n        cp2.x *= aspect;\n        float lw = sin(cp2.x * 3.0 + t * 1.5) * 0.5 + 0.5;\n        lw *= sin(cp2.y * 2.5 - t * 1.1) * 0.5 + 0.5;\n        lw += (snoise(cp2 * 2.0 + t * 0.6) * 0.5 + 0.5) * 0.3;\n        hlFactor = clamp(lw, 0.0, 1.0);\n        hlFactor *= hlFactor;\n      }\n\n      float scaleBoost = 1.0 + smoothstep(0.2, 0.8, hlFactor) * u_hlScale * 1.2;\n\n      float mask = 1.0;\n      if (u_dotMode < 1.5) {\n        float gapW = u_gap * 0.35 / scaleBoost;\n        if (gapW > 0.003) {\n          mask = step(gapW, cellLocal.x) * step(gapW, 1.0 - cellLocal.x)\n               * step(gapW, cellLocal.y) * step(gapW, 1.0 - cellLocal.y);\n        }\n      } else {\n        // Render the circular dot mask in screen-pixel space rather than\n        // cell-local UV. We map the cell-local offset to actual pixels\n        // (cellPx = u_resolution / gridSize), then apply a 1-pixel AA\n        // floor to the smoothstep edge so the dot rim is crisp and\n        // properly anti-aliased even at u_dotSoftness near 0. The user\n        // softness slider still scales linearly on top of the floor.\n        // No fwidth() / GL_OES_standard_derivatives needed - dPx is\n        // already in pixel units, so a fixed 1-px edge IS pixel-perfect.\n        // gridCounts() already keeps cells square in screen space, so\n        // pxOffset traces true circles (not ellipses) on any aspect.\n        vec2 cellPx = u_resolution / gridSize;\n        vec2 pxOffset = (cellLocal - 0.5) * cellPx;\n        float dPx = length(pxOffset);\n        float minCellPx = min(cellPx.x, cellPx.y);\n        float radiusPx = u_dotSize * 0.5 * minCellPx * scaleBoost;\n        // 0.5-px AA floor (1-px total smoothstep ramp) keeps the rim\n        // pixel-perfect at u_dotSoftness=0 while letting the user softness\n        // value dominate at the bundled preset defaults (e.g. softness=0.1\n        // on a ~28-px cell yields softPx=0.56 -> ~1.1-px ramp, matching\n        // the original cell-local behaviour). A larger floor (e.g. 1.0)\n        // would widen low-softness dots and visually lighten dot presets.\n        float aaPx = 0.5;\n        float softPx = u_dotSoftness * 0.2 * minCellPx;\n        float edgePx = max(aaPx, softPx);\n        mask = 1.0 - smoothstep(radiusPx - edgePx, radiusPx + edgePx, dPx);\n      }\n\n      if (u_highlight > 0.01) {\n        float hl = hlFactor * u_highlight;\n        col = col * (1.0 + hl * 2.5) + vec3(hl * hl * 0.3);\n      }\n\n      if (u_edgeFade > 0.5 && u_fadeStr > 0.005) {\n        float ef = smoothstep(0.0, u_edgeFade, edgeDistPx);\n        mask *= mix(1.0, ef, u_fadeStr);\n      }\n\n      float baseOpacity = (u_dotMode < 1.5) ? u_fillOpacity : 0.0;\n      alpha = colorAlpha * mix(baseOpacity, u_dotOpacity, mask);\n\n      float bgLum  = dot(u_cardBg, vec3(0.299, 0.587, 0.114));\n      float colLum = dot(baseCol, vec3(0.299, 0.587, 0.114));\n      alpha *= smoothstep(0.0, 0.33, abs(colLum - bgLum));\n    }\n\n    gl_FragColor = vec4(col, alpha * u_shaderOpacity);\n  }\n`;\n\n/** Names of every uniform sampled by the fragment shader. */\nexport const UNIFORM_NAMES: readonly string[] = [\n  'u_resolution', 'u_dpr', 'u_time',\n  'u_color1', 'u_color2', 'u_color3', 'u_color4', 'u_color5', 'u_color6', 'u_color7', 'u_cardBg',\n  'u_alpha1', 'u_alpha2', 'u_alpha3', 'u_alpha4', 'u_alpha5', 'u_alpha6', 'u_alpha7',\n  'u_speed', 'u_intensity', 'u_scale', 'u_direction',\n  'u_softness', 'u_distortion', 'u_complexity', 'u_shape', 'u_flicker',\n  'u_vignette', 'u_vigOpacity', 'u_blur', 'u_highlight', 'u_shaderOpacity',\n  'u_cellSize', 'u_gap', 'u_dotSize', 'u_dotSoftness', 'u_dotOpacity', 'u_hlScale',\n  'u_fillOpacity', 'u_edgeFade', 'u_fadeStr', 'u_dotMode', 'u_effect', 'u_sweepEase'\n];\n"
        },
        {
          "path": "components/effects/img-fx/upstream/engine/reveal.ts",
          "target": "@components/effects/img-fx/upstream/engine/reveal.ts",
          "type": "registry:component",
          "content": "/**\n * Per-instance reveal pipeline.\n *\n * Direct port of image.html `drawMaskedImage` (lines 2481–2703) and the\n * `getMaskValue` geometric mask helper (line 2367), reorganised so each\n * <ImageGeneration> card has its own private scratch canvases and overlay\n * state. The reveal canvas sits on top of the shader canvas and is gradually\n * filled with the source image; the shader canvas underneath fades to 0 over\n * the same duration, producing the same crossfade as the original demo.\n *\n * The shader luminance / shader-color sampling renders the live shader into a\n * small `MASK_SIZE` × `MASK_SIZE` buffer (image.html's `MASK_SIZE` was 100; we\n * use 64 — visually indistinguishable after the upscale-with-smoothing step\n * but ~60% cheaper to allocate and iterate). The dotMode is temporarily\n * forced to 0 / 1 so the mask reads from the raw / pixel-rendered shader\n * colour field rather than the dot mosaic.\n */\nimport { parseCssColor, type EnginePresetMode, type MaskShape } from '../presets';\nimport { ease } from './tween';\nimport {\n  effectiveCardBg,\n  effectiveCellSize,\n  effectivePaletteColor,\n  type Instance,\n  type SharedRenderer\n} from './renderer';\n\n/** Side length of the square buffer used to evaluate the reveal mask shape\n *  (and to sample the live shader field for the `shaderColor*` / `shaderHighlight`\n *  mask shapes). The buffer is upscaled to the visible canvas size with\n *  image-smoothing on, so dropping below ~50 still produces a clean edge.\n *  64 (vs the original 100) cuts the per-frame JS pixel loop and the\n *  `getImageData` allocation by ~59% with no perceptible visual change. */\nconst MASK_SIZE = 64;\nconst DOT_MASK_SIZE = 96;\n/** Reference card edge length (CSS px) used by the shader's `gridCounts` for\n *  scale-invariant cell sizing. The pixel-mode reveal dissolve mirrors that\n *  same constant so its chunky cells line up visually with the shader's. */\nconst REVEAL_REF_DIM = 320;\n\n/** Fraction of the source rect trimmed off every edge before drawing. Guards\n *  against a 1–3px solid border row baked into the source image (extremely\n *  common in screenshots, which capture a black window-chrome / letterbox edge)\n *  landing flush against the card edge and reading as a thin dark line. Cover\n *  already crops the overflow axis, so trimming an extra ~0.6% is an\n *  imperceptible zoom on the fit axis while reliably clearing typical borders. */\nconst COVER_EDGE_INSET_FRAC = 0.006;\n\n/** Source rect for a cover-fit draw of `img` into a target of `targetW × targetH`.\n *  Mirrors CSS `object-fit: cover`: image aspect is preserved, the overflowing\n *  axis is centre-cropped. Never squashes / stretches. */\nfunction computeCoverSourceRect(\n  img: HTMLImageElement,\n  targetW: number,\n  targetH: number\n): { sx: number; sy: number; sw: number; sh: number } {\n  const targetAspect = targetW / Math.max(1, targetH);\n  const imgAspect = img.width / Math.max(1, img.height);\n  let sx = 0;\n  let sy = 0;\n  let sw = img.width;\n  let sh = img.height;\n  if (imgAspect > targetAspect) {\n    // Image is wider than target — crop left/right.\n    sw = img.height * targetAspect;\n    sx = (img.width - sw) / 2;\n  } else {\n    // Image is taller than target — crop top/bottom.\n    sh = img.width / targetAspect;\n    sy = (img.height - sh) / 2;\n  }\n  // Trim a thin margin off all four edges so a solid border row baked into the\n  // source never sits flush at the card edge. Clamped so it can never invert\n  // the rect for tiny source images.\n  const inset = Math.min(sw, sh) * COVER_EDGE_INSET_FRAC;\n  if (sw - 2 * inset > 1 && sh - 2 * inset > 1) {\n    sx += inset;\n    sy += inset;\n    sw -= 2 * inset;\n    sh -= 2 * inset;\n  }\n  return { sx, sy, sw, sh };\n}\n\n/** Cache decoded <img> elements globally so repeat URLs only decode once. */\nconst IMAGE_CACHE = new Map<string, Promise<HTMLImageElement>>();\n\n/**\n * Load (and cache) an image. Resolves once the bitmap is decoded and ready.\n *\n * Note: we do NOT set `img.crossOrigin` — for same-origin assets that would\n * trigger an unnecessary CORS preflight that most static dev servers don't\n * satisfy. Drawing images into a 2D canvas does not taint the canvas if the\n * image is same-origin. Consumers serving cross-origin images should set\n * proper CORS headers on their CDN.\n */\nexport function loadImage(src: string): Promise<HTMLImageElement> {\n  let entry = IMAGE_CACHE.get(src);\n  if (entry) return entry;\n  entry = new Promise<HTMLImageElement>((resolve, reject) => {\n    const img = new Image();\n    const done = (): void => resolve(img);\n    img.onerror = (e) => {\n      IMAGE_CACHE.delete(src);\n      reject(e);\n    };\n    // Prefer `decode()`: it resolves once the bitmap is decoded off the main\n    // thread. With plain `onload` the first `drawImage` of a multi-megapixel\n    // photo triggers a synchronous decode on the main thread (tens to\n    // hundreds of ms per image) — one visible hitch per new image, on every\n    // card, which read as the page \"freezing\" during auto-cycles.\n    if (typeof img.decode === 'function') {\n      img.src = src;\n      img.decode().then(done, () => {\n        // `decode()` can reject for reasons other than a load failure (e.g.\n        // the browser dropped the decoded bitmap under memory pressure). Fall\n        // back to the classic onload path; a real load failure still rejects\n        // via `onerror` above.\n        if (img.complete && img.naturalWidth > 0) done();\n        else img.onload = done;\n      });\n    } else {\n      img.onload = done;\n      img.src = src;\n    }\n  });\n  IMAGE_CACHE.set(src, entry);\n  return entry;\n}\n\nexport interface RevealStartOptions {\n  /** Image to reveal. */\n  image: HTMLImageElement;\n  /** Output canvas size (CSS px). Reveal canvas matches the shader canvas. */\n  cssWidth: number;\n  cssHeight: number;\n  /** Phase scheduler hooks. */\n  onRevealComplete?: () => void;\n}\n\nexport interface RevealState {\n  /** The DOM canvas painted on top of the shader canvas. */\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  /** Per-frame hook invoked after the shader has rendered. Decides what to do\n   *  with the overlay this frame (paint mask, hold, fade out, idle). */\n  afterShaderFrame: (s: SharedRenderer, inst: Instance, nowMs: number) => void;\n  /** Begin a new reveal animation. */\n  startReveal: (opts: RevealStartOptions) => void;\n  /** Begin the fade-out (hide) phase. */\n  startHide: (durationMs?: number) => void;\n  /**\n   * Dissolve the currently held image into a sustained \"generating\" state:\n   * the image is broken into the effect's pixel-cell grid and the cells churn\n   * (pop in/out with the preset's flicker clock) indefinitely while the\n   * shader effect plays through the gaps. No-op unless an image is currently\n   * revealed/held. Ends when `startReveal` (next image) or `startHide` runs.\n   */\n  startBoil: () => void;\n  /** Force-clear the overlay back to idle. */\n  clear: () => void;\n  /** True while a reveal/hold/hide is in progress. */\n  isActive: () => boolean;\n  dispose: () => void;\n}\n\ninterface RevealInternals {\n  // Animation state\n  active: boolean;\n  phase: 'idle' | 'reveal' | 'hold' | 'hide' | 'boil';\n  revealStartMs: number;\n  hideStartMs: number;\n  hideDurationMs: number;\n  /** When the boil (sustained pixel-churn) phase started. */\n  boilStartMs: number;\n  /** Persistent per-cell random thresholds for the boil churn. Unlike\n   *  `pixDropPattern` (reseeded per reveal) this survives for the whole boil\n   *  so settled cells stay settled and only edge cells flicker. */\n  boilPattern: Float32Array | null;\n  boilPatternW: number;\n  boilPatternH: number;\n  /** Pooled per-cell shader-field luminance for the boil (drives which image\n   *  cells drop, so the churn follows the live img-fx animation). */\n  boilField: Float32Array | null;\n  /** When a reveal was requested during a boil: starts the BLEND → RESOLVE\n   *  handoff (see paintBoilFrame) — the churning cells morph their colours\n   *  to the incoming image, then the smooth photo fades in while the chunky\n   *  cells melt into it in parallel. No hard cut from churn to reveal. */\n  boilHandoffStartMs: number;\n  pendingReveal: RevealStartOptions | null;\n  image: HTMLImageElement | null;\n  onRevealComplete?: () => void;\n\n  // Output dims (CSS px)\n  cssWidth: number;\n  cssHeight: number;\n\n  // Mask scratch (geometric / shader-luminance)\n  sampleCanvas: HTMLCanvasElement | null;\n  sampleCtx: CanvasRenderingContext2D | null;\n  /** Pooled image-data for `getImageData` reads from `sampleCanvas`. Allocated\n   *  once and reused every frame — without this the reveal hot path allocates\n   *  a fresh Uint8ClampedArray per frame per active card, putting heavy\n   *  GC pressure on Chrome over long sessions. */\n  sampleImgData: ImageData | null;\n  /** Last-read sample buffer (the `.data` view of `sampleImgData`). Cached\n   *  so we can skip the expensive `renderer.render()` + `getImageData`\n   *  round-trip on every other reveal frame — the shader colour field drifts\n   *  slowly enough (~0.3-0.9 rad/s) that a 1-frame-stale sample is\n   *  imperceptible at the soft-banded mask threshold. */\n  sampleDataCache: Uint8ClampedArray | null;\n  /** Monotonically increasing reveal-frame counter used to decide when to\n   *  re-sample. Even values trigger a fresh sample, odd values reuse the\n   *  cache. Reset to 0 on every new `startReveal()`. */\n  sampleFrameCounter: number;\n  maskGrad: HTMLCanvasElement | null;\n  maskGradCtx: CanvasRenderingContext2D | null;\n  /** Pooled image-data for the mask gradient. Allocated lazily on first paint\n   *  and reused thereafter; MASK_SIZE is a compile-time constant so the\n   *  buffer dimensions never need to change. */\n  maskImgData: ImageData | null;\n  /** Pooled per-cell flicker offsets for the gradientSweep mask. Recomputed\n   *  every frame (values change with the flicker clock) but only reallocated\n   *  when the cell grid size changes. */\n  gsFlickerTable: Float32Array | null;\n\n  // Pixel-mode + dot-mode pixelation scratch. The same canvases are reused\n  // by both code paths because `preset.dotMode` is fixed per-instance, so\n  // only one of the two ever runs against a given reveal state. The drop\n  // pattern is the per-cell random threshold used to gradually transition\n  // cells from chunky-pixelated to smooth as `fadeT` increases.\n  pixCanvas: HTMLCanvasElement | null;\n  pixCtx: CanvasRenderingContext2D | null;\n  pixDrop: HTMLCanvasElement | null;\n  pixDropCtx: CanvasRenderingContext2D | null;\n  pixDropImgData: ImageData | null;\n  pixDropPattern: Float32Array | null;\n  pixDropPatternW: number;\n  pixDropPatternH: number;\n  pixDropRevealStart: number;\n\n  /** Cover-fit copies of the reveal image(s) at the output canvas size,\n   *  resampled ONCE (high quality) per image × size instead of on every\n   *  frame. Every per-frame `drawImage` of the photo now reads from one of\n   *  these instead of the multi-megapixel source, so the browser's\n   *  multi-pass \"high\" downsample runs once per reveal, not 10×/s × 2-3\n   *  draws × cards. Slot `a` is the current image, slot `b` the incoming\n   *  (pending) image during a boil handoff. */\n  coverA: CoverBitmap | null;\n  coverB: CoverBitmap | null;\n  /** What the `hold` phase last painted, so the fully-revealed image is\n   *  drawn once and then left alone (it was repainted every tick). */\n  holdPaintedImg: HTMLImageElement | null;\n  holdPaintedW: number;\n  holdPaintedH: number;\n  /** GPU-backed maskSize×maskSize intermediate for the shader sample: the\n   *  WebGL frame is downscaled into this (stays on the GPU) and only this\n   *  small canvas is read back into the CPU-side `sampleCanvas`. Drawing the\n   *  GL canvas straight into a `willReadFrequently` (CPU) canvas forced a\n   *  full iw×ih GPU→CPU readback per sample. */\n  sampleGpuCanvas: HTMLCanvasElement | null;\n  sampleGpuCtx: CanvasRenderingContext2D | null;\n}\n\ninterface CoverBitmap {\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  img: HTMLImageElement | null;\n  w: number;\n  h: number;\n}\n\n/** Return `img` cover-fitted into a `w × h` canvas, resampling only when the\n *  image or the size changed since the last call for that slot. */\nfunction getCoverBitmap(\n  state: RevealInternals,\n  slot: 'a' | 'b',\n  img: HTMLImageElement,\n  w: number,\n  h: number\n): HTMLCanvasElement {\n  let cb = slot === 'a' ? state.coverA : state.coverB;\n  if (!cb) {\n    const canvas = document.createElement('canvas');\n    const c = canvas.getContext('2d');\n    if (!c) throw new Error('img-fx: 2D context unavailable for cover bitmap');\n    cb = { canvas, ctx: c, img: null, w: 0, h: 0 };\n    if (slot === 'a') state.coverA = cb;\n    else state.coverB = cb;\n  }\n  if (cb.img !== img || cb.w !== w || cb.h !== h) {\n    cb.canvas.width = w;\n    cb.canvas.height = h;\n    cb.w = w;\n    cb.h = h;\n    cb.img = img;\n    const { sx, sy, sw, sh } = computeCoverSourceRect(img, w, h);\n    cb.ctx.clearRect(0, 0, w, h);\n    cb.ctx.imageSmoothingEnabled = true;\n    cb.ctx.imageSmoothingQuality = 'high';\n    cb.ctx.drawImage(img, sx, sy, sw, sh, 0, 0, w, h);\n  }\n  return cb.canvas;\n}\n\nfunction getMaskSize(p: EnginePresetMode): number {\n  return p.dotMode === 2 ? DOT_MASK_SIZE : MASK_SIZE;\n}\n\nfunction getActiveRevealTiming(\n  p: EnginePresetMode\n): { duration: number; easingKey: EnginePresetMode['revealConfig']['easing'] } {\n  // Mode-aware: dot uses dotDuration/dotEasing, everything else uses duration/easing.\n  // Mirrors image.html `getActiveRevealTiming` (line 2353).\n  const r = p.revealConfig;\n  if (p.dotMode === 2) {\n    return { duration: Math.max(0.05, r.dotDuration), easingKey: r.dotEasing };\n  }\n  return { duration: Math.max(0.05, r.duration), easingKey: r.easing };\n}\n\nfunction getMaskValue(shape: MaskShape, r: number, c: number, size: number): number {\n  const nx = c / (size - 1);\n  const ny = r / (size - 1);\n  const cx = nx - 0.5;\n  const cy = ny - 0.5;\n  switch (shape) {\n    case 'radialCenter':\n      return 1 - Math.sqrt(cx * cx + cy * cy) * 2;\n    case 'radialCorner':\n      return 1 - Math.sqrt(nx * nx + ny * ny) / 1.414;\n    case 'linearTop':\n      return 1 - ny;\n    case 'linearBottom':\n      return ny;\n    case 'linearLeft':\n      return 1 - nx;\n    case 'linearRight':\n      return nx;\n    case 'diagonalTL':\n      return 1 - (nx + ny) / 2;\n    case 'diagonalBR':\n      return (nx + ny) / 2;\n    case 'diamond':\n      return 1 - (Math.abs(cx) + Math.abs(cy));\n    case 'blindsH':\n      return 1 - ((ny * 8) % 1);\n    case 'blindsV':\n      return 1 - ((nx * 8) % 1);\n    default:\n      return -1;\n  }\n}\n\n/** Sample the current shader frame into an N×N RGBA buffer for the reveal\n *  mask. Mirrors the original `image.html` (line 2530) sampling rule so each\n *  preset gets its authentic mask character:\n *\n *    presetDotMode === 1 (PIXELS) → sample at u_dotMode = 0 (RAW smooth\n *      shader field), so the reveal silhouette never inherits the chunky\n *      pixel cells from the foreground render. The pixel-cell dissolve is\n *      a separate effect handled in paintPixelMasked().\n *\n *    presetDotMode === 2 (DOTS)  → sample at u_dotMode = 1 (PIXEL-rendered\n *      shader field). The dot foreground would leave huge gaps if sampled\n *      directly; pixel-rendered sampling produces a solid, cell-stepped\n *      field whose chunks line up with the shader's mosaic grid, giving the\n *      dots presets their distinctive cell-quantised mask edge.\n *\n *  Restores the original dotMode / fillOpacity before returning so the\n *  next regular tick is unaffected.\n */\nfunction sampleShaderField(\n  state: RevealInternals,\n  s: SharedRenderer,\n  inst: Instance,\n  scratchCtx: CanvasRenderingContext2D,\n  maskSize: number\n): Uint8ClampedArray {\n  const origDotMode = s.uniforms.u_dotMode.value as number;\n  const origFillOpacity = s.uniforms.u_fillOpacity.value as number;\n  const presetDotMode = inst.preset.dotMode;\n  const sampleDotMode = presetDotMode < 1.5 ? 0 : 1;\n  s.uniforms.u_dotMode.value = sampleDotMode;\n  // When sampling as pixel-rendering (dots presets), preserve the active\n  // mosaic's fillOpacity so colour-target masks (`shaderColorN`) read the\n  // same colour distribution the user sees. When sampling raw (pixels\n  // presets), zero it out so pixel fills don't bleed into the mask field.\n  s.uniforms.u_fillOpacity.value =\n    sampleDotMode > 0.5\n      ? presetDotMode === 1\n        ? inst.preset.pixelConfig.fillOpacity\n        : inst.preset.dotConfig.fillOpacity\n      : 0;\n  s.renderer.render(s.scene, s.camera);\n\n  // The instance's pixels live in the BOTTOM-LEFT iw×ih sub-rect of the\n  // shared GL canvas (paintInstance sets the viewport accordingly). In\n  // image-space coords (top-left origin used by drawImage source rects) that\n  // sub-rect starts at y = glCanvas.height - ih.\n  const iw = Math.max(1, Math.floor(inst.cssWidth * inst.dpr));\n  const ih = Math.max(1, Math.floor(inst.cssHeight * inst.dpr));\n  const sy = Math.max(0, s.glCanvas.height - ih);\n  // Two-stage copy: GL → small GPU-backed canvas (stays on the GPU), then\n  // that maskSize² canvas → the CPU-side scratch. Only the tiny intermediate\n  // is read back, instead of the full iw×ih framebuffer sub-rect.\n  if (!state.sampleGpuCanvas) {\n    state.sampleGpuCanvas = document.createElement('canvas');\n    state.sampleGpuCtx = state.sampleGpuCanvas.getContext('2d');\n  }\n  const gpuCanvas = state.sampleGpuCanvas;\n  const gpuCtx = state.sampleGpuCtx as CanvasRenderingContext2D;\n  if (gpuCanvas.width !== maskSize || gpuCanvas.height !== maskSize) {\n    gpuCanvas.width = maskSize;\n    gpuCanvas.height = maskSize;\n  }\n  gpuCtx.clearRect(0, 0, maskSize, maskSize);\n  gpuCtx.drawImage(s.glCanvas, 0, sy, iw, ih, 0, 0, maskSize, maskSize);\n  scratchCtx.clearRect(0, 0, maskSize, maskSize);\n  scratchCtx.drawImage(gpuCanvas, 0, 0);\n  // Restore uniforms; the next instance / tick re-uploads its own values\n  // before rendering so we don't need to re-render the GL canvas here.\n  s.uniforms.u_dotMode.value = origDotMode;\n  s.uniforms.u_fillOpacity.value = origFillOpacity;\n  // Hold the latest ImageData on the state so the typed array isn't\n  // immediately collected — keeps the buffer alive for the rest of the\n  // current frame's mask paint without depending on JS engine GC timing.\n  // (Canvas 2D's `getImageData` has no zero-alloc variant, so we can't\n  // truly pool here; this just minimises pressure for the active call.)\n  state.sampleImgData = scratchCtx.getImageData(0, 0, maskSize, maskSize);\n  state.sampleDataCache = state.sampleImgData.data;\n  return state.sampleDataCache;\n}\n\nfunction ensureScratch(state: RevealInternals, maskSize: number): void {\n  if (!state.sampleCanvas) {\n    state.sampleCanvas = document.createElement('canvas');\n    state.sampleCtx = state.sampleCanvas.getContext('2d', { willReadFrequently: true });\n  }\n  if (state.sampleCanvas.width !== maskSize || state.sampleCanvas.height !== maskSize) {\n    state.sampleCanvas.width = maskSize;\n    state.sampleCanvas.height = maskSize;\n    state.sampleImgData = null;\n    state.sampleDataCache = null;\n    state.sampleFrameCounter = 0;\n  }\n  if (!state.maskGrad) {\n    state.maskGrad = document.createElement('canvas');\n    state.maskGradCtx = state.maskGrad.getContext('2d');\n  }\n  if (state.maskGrad.width !== maskSize || state.maskGrad.height !== maskSize) {\n    state.maskGrad.width = maskSize;\n    state.maskGrad.height = maskSize;\n    state.maskImgData = null;\n  }\n  if (!state.maskImgData && state.maskGradCtx) {\n    // Pool the mask-gradient buffer and only resize when mask resolution changes.\n    // The original code called `createImageData(MASK_SIZE, MASK_SIZE)` every frame,\n    // allocating 40 KB per card per frame.\n    state.maskImgData = state.maskGradCtx.createImageData(maskSize, maskSize);\n  }\n}\n\nfunction paintMaskedFrame(\n  state: RevealInternals,\n  s: SharedRenderer,\n  inst: Instance,\n  ctx: CanvasRenderingContext2D\n): void {\n  if (!state.image) return;\n  const preset = inst.preset;\n  // Resize visible canvas to match shader canvas pixel size.\n  const targetW = inst.canvas.width;\n  const targetH = inst.canvas.height;\n  if (ctx.canvas.width !== targetW || ctx.canvas.height !== targetH) {\n    ctx.canvas.width = targetW;\n    ctx.canvas.height = targetH;\n  }\n  ctx.clearRect(0, 0, targetW, targetH);\n\n  const { duration, easingKey } = getActiveRevealTiming(preset);\n  const elapsed = (performance.now() - state.revealStartMs) / 1000;\n  const progress = Math.min(elapsed / duration, 1);\n  const eased = ease(easingKey, progress);\n\n  // Cover-fit crop (CSS object-fit: cover) — preserves image aspect ratio,\n  // centre-crops the overflowing axis. Never squashes the image.\n  const img = state.image;\n  const { sx, sy, sw, sh } = computeCoverSourceRect(img, targetW, targetH);\n\n  // CSS blur fade\n  const maxBlur = preset.revealConfig.blur;\n  if (progress < 1 && maxBlur > 0) {\n    const b = maxBlur * (1 - eased);\n    ctx.canvas.style.filter = b > 0.1 ? `blur(${b.toFixed(1)}px)` : 'none';\n  } else {\n    ctx.canvas.style.filter = 'none';\n  }\n\n  if (progress >= 1) {\n    ctx.imageSmoothingEnabled = true;\n    ctx.imageSmoothingQuality = 'high';\n    ctx.drawImage(getCoverBitmap(state, 'a', img, targetW, targetH), 0, 0);\n    return;\n  }\n\n  const maskSize = getMaskSize(preset);\n  ensureScratch(state, maskSize);\n  const sampleCtx = state.sampleCtx as CanvasRenderingContext2D;\n  const maskGrad = state.maskGrad as HTMLCanvasElement;\n  const maskGradCtx = state.maskGradCtx as CanvasRenderingContext2D;\n\n  const maskShape = preset.revealConfig.maskShape;\n  const softBand = preset.revealConfig.softness;\n  const useShader = maskShape.startsWith('shader');\n\n  let sampleData: Uint8ClampedArray | null = null;\n  let targetColor: [number, number, number] | null = null;\n  let highlightColors: Array<[number, number, number]> | null = null;\n\n  if (useShader) {\n    // Throttle the shader re-sample to every 2nd reveal frame. The shader's\n    // colour field drifts at speed 0.3-0.9 rad/s and the mask's soft-band\n    // threshold (~0.07) easily absorbs a 100-200 ms staleness in the sample\n    // — far below the perceptual flicker threshold — while halving both the\n    // extra `renderer.render()` calls and the `getImageData` allocations.\n    // Frame 0 always samples so the very first reveal frame is fresh.\n    const counter = state.sampleFrameCounter++;\n    const shouldSample = state.sampleDataCache == null || (counter & 1) === 0;\n    if (shouldSample) {\n      sampleData = sampleShaderField(state, s, inst, sampleCtx, maskSize);\n    } else {\n      sampleData = state.sampleDataCache;\n    }\n    const colorMap: Record<string, number> = {\n      shaderColor1: 0,\n      shaderColor2: 1,\n      shaderColor3: 2,\n      shaderColor4: 3,\n      shaderColor5: 4\n    };\n    if (colorMap[maskShape] != null) {\n      targetColor = effectivePaletteColor(inst, colorMap[maskShape]);\n    }\n    if (maskShape === 'shaderHighlight') {\n      // `effectiveCardBg` may return any CSS colour the consumer passed via\n      // the `cardBg` prop (rgba, hsl, named, …). parseCssColor handles all\n      // of it; alpha is dropped so the proximity test below stays in RGB\n      // space against the same opaque tint the shader uniform sees.\n      const bg = parseCssColor(effectiveCardBg(inst));\n      highlightColors = [];\n      for (let i = 0; i < 5; i++) {\n        // Use the effective (card-linked-remapped) colour so any swatch that\n        // followed an overridden card bg is correctly excluded here (it now\n        // equals the bg, so distC ≈ 0) instead of lingering as a highlight.\n        const c = effectivePaletteColor(inst, i);\n        const dr = c[0] - bg[0];\n        const dg = c[1] - bg[1];\n        const db = c[2] - bg[2];\n        const distC = Math.sqrt(dr * dr + dg * dg + db * db);\n        if (distC > 0.15) highlightColors.push(c);\n      }\n      if (highlightColors.length === 0) highlightColors = [effectivePaletteColor(inst, 0)];\n    }\n  }\n\n  const threshold = 1 - eased * (1 + softBand);\n  const isGradientSweep = maskShape === 'gradientSweep';\n  let gsW = 0;\n  let gsPos = 0;\n  let gsGrid = 2;\n  // Per-cell flicker on the mask's transition edge: cells mid-transition pop\n  // in and out with the shader's flicker clock/hash, so the image\n  // materializes cell-by-cell instead of wiping in cleanly. Shared by EVERY\n  // mask shape (gradientSweep band or shader-sampled masks like the pixel\n  // presets') and driven by `preset.flicker`.\n  const gsAmp = preset.flicker ?? 0;\n  let gsTable: Float32Array | null = null;\n  // Also exposed for the pixel-dissolve flicker below (paintPixelMasked),\n  // which indexes cells by its own anisotropic grid rather than `gsTable`.\n  let gsHashFn: ((i: number, s: number) => number) | null = null;\n  let gsStep = 0;\n  let gsStep1 = 0;\n  let gsFz = 0;\n  if (gsAmp > 0.003) {\n    gsGrid = Math.max(2, Math.floor(6 + effectiveCellSize(preset.pixelConfig.cellSize, inst.pixelScale) * 74));\n    // Clamp the flicker clock to at least the Sweep Gradient preset's\n    // cadence (speed ~2) so slower presets like Pixel Mechanic (speed ~0.6)\n    // still re-roll their cells fast enough to read as \"generating\".\n    const gsT = inst.accumulatedTime * Math.max(preset.speed, 2) * 1.6;\n    // Wrap the stepped clock (mirrors the shader's mod-1024 wrap) so the\n    // hash inputs stay small however long the session has been running,\n    // and so the mask flicker stays phase-aligned with the shader's.\n    const rawStep = Math.floor(gsT);\n    gsStep = rawStep % 1024;\n    gsStep1 = (gsStep + 1) % 1024;\n    gsFz = gsT - rawStep;\n    gsFz = gsFz * gsFz * (3 - 2 * gsFz);\n    const gsHash = (i: number, s: number): number => {\n      const x = Math.sin(i * 127.1 + s * 17.23) * 43758.5453;\n      return x - Math.floor(x);\n    };\n    gsHashFn = gsHash;\n    // Precompute the per-cell flicker offsets ONCE per frame (gsGrid² cells,\n    // typically ~500) instead of hashing per mask pixel (maskSize² pixels ×\n    // 2 sin calls ≈ 8k/frame). The pixel loop just indexes this table and\n    // scales by its edge factor — output is bit-identical to the inline\n    // version. The buffer is pooled on the reveal state and only\n    // reallocated when the cell grid size changes.\n    const cellCount = gsGrid * gsGrid;\n    if (!state.gsFlickerTable || state.gsFlickerTable.length !== cellCount) {\n      state.gsFlickerTable = new Float32Array(cellCount);\n    }\n    gsTable = state.gsFlickerTable;\n    for (let i = 0; i < cellCount; i++) {\n      const rnd = gsHash(i, gsStep) * (1 - gsFz) + gsHash(i, gsStep1) * gsFz;\n      gsTable[i] = (rnd - 0.5) * gsAmp * 1.6;\n    }\n  }\n  if (isGradientSweep) {\n    gsW = 0.9 / Math.max(preset.scale, 0.25);\n    gsPos = -gsW + eased * (1 + 2 * gsW);\n  }\n\n  // Reuse the pooled buffer initialised by ensureScratch above.\n  const maskImgData = state.maskImgData as ImageData;\n  const md = maskImgData.data;\n  for (let r = 0; r < maskSize; r++) {\n    for (let c = 0; c < maskSize; c++) {\n      let val: number;\n      if (useShader && sampleData) {\n        const i = (r * maskSize + c) * 4;\n        const pr = sampleData[i] / 255;\n        const pg = sampleData[i + 1] / 255;\n        const pb = sampleData[i + 2] / 255;\n        if (highlightColors) {\n          let maxProx = 0;\n          for (const hc of highlightColors) {\n            const dr = pr - hc[0];\n            const dg = pg - hc[1];\n            const db = pb - hc[2];\n            const prox = Math.exp(-10 * (dr * dr + dg * dg + db * db));\n            if (prox > maxProx) maxProx = prox;\n          }\n          val = maxProx;\n        } else if (targetColor) {\n          const dr = pr - targetColor[0];\n          const dg = pg - targetColor[1];\n          const db = pb - targetColor[2];\n          val = Math.exp(-8 * (dr * dr + dg * dg + db * db));\n        } else {\n          val = (sampleData[i] * 0.299 + sampleData[i + 1] * 0.587 + sampleData[i + 2] * 0.114) / 255;\n        }\n      } else if (!isGradientSweep) {\n        val = getMaskValue(maskShape, r, c, maskSize);\n      } else {\n        val = 0;\n      }\n      let a: number;\n      if (isGradientSweep) {\n        const nx = c / (maskSize - 1);\n        const ny = r / (maskSize - 1);\n        const dd = (nx + ny) * 0.5;\n        a = (gsPos + gsW - dd) / (2 * gsW);\n      } else {\n        a = (val - threshold) / softBand;\n      }\n      if (gsTable && a > -0.5 && a < 1.5) {\n        // Edge-localized jitter: strongest mid-transition, zero in fully\n        // hidden/revealed areas so the settled image never flickers.\n        const at = a < 0 ? 0 : a > 1 ? 1 : a;\n        const edge = at * (1 - at) * 4;\n        if (edge > 0.001) {\n          const nx = c / (maskSize - 1);\n          const ny = r / (maskSize - 1);\n          const ci = Math.floor(ny * gsGrid) * gsGrid + Math.floor(nx * gsGrid);\n          a += gsTable[ci] * edge;\n        }\n      }\n      if (a < 0) a = 0;\n      else if (a > 1) a = 1;\n      a = a * a * (3 - 2 * a);\n      const idx = (r * maskSize + c) * 4;\n      md[idx] = 255;\n      md[idx + 1] = 255;\n      md[idx + 2] = 255;\n      md[idx + 3] = (a * 255 + 0.5) | 0;\n    }\n  }\n  maskGradCtx.putImageData(maskImgData, 0, 0);\n\n  if (preset.dotMode === 1) {\n    paintPixelMasked(\n      state,\n      ctx,\n      img,\n      sx,\n      sy,\n      sw,\n      sh,\n      preset,\n      elapsed,\n      targetW,\n      targetH,\n      inst,\n      // The gradientSweep mask already flickers along its band edge (via\n      // gsTable above); skip the dissolve flicker there to avoid doubling up\n      // and keep that preset's approved look unchanged.\n      isGradientSweep ? 0 : gsAmp,\n      gsHashFn,\n      gsStep,\n      gsStep1,\n      gsFz\n    );\n  } else {\n    if (preset.dotMode === 2) {\n      // Dot presets reveal the image through TWO independent layers:\n      //   1. A pixel-mode-style per-cell dropout: every cell starts as a\n      //      chunky pixel (downsampled image) and individually transitions\n      //      to smooth photo as `fadeT` crosses its random per-cell\n      //      threshold. Driven by `pixDuration` / `pixEasing` so it feels\n      //      identical to the pixel presets the user is familiar with.\n      //   2. The shader-luminance mask (applied below) which gates which\n      //      AREAS of the card are visible at all at any given moment —\n      //      so the chunky pixels only appear inside the area the shader\n      //      mask has currently uncovered, not across the whole card.\n      //\n      // Composite order inside this branch: smooth base + pixelated/dropped\n      // overlay. The shader mask is applied via destination-in AFTER this\n      // branch (see further down), cutting the combined image down to the\n      // revealed area.\n      //\n      // PERF: this matches `paintPixelMasked` exactly — same per-frame\n      // downsample to a small ~38x38 grid (browser-accelerated, ~0.3 ms),\n      // same cached random drop pattern (one `Float32Array` per reveal),\n      // same pooled `pixDropImgData` for the per-frame alpha update. Total\n      // per-frame overhead is in line with pixel-mode presets, which we\n      // already validated at ~4.4% CPU in the prior perf pass.\n      // Cell size is sourced from `pixelConfig.cellSize` (NOT `dotConfig`)\n      // so it matches the pixel-mode pipeline byte-for-byte and produces\n      // visibly chunky blocks. dot-mode presets' `pixelConfig` is otherwise\n      // unused by the shader (which switches to `dotConfig` when\n      // `dotMode === 2` — see `renderer.ts` mosaic switch), so the preset\n      // is free to tune this field purely for the reveal look.\n      paintPixelatedDropLayer(state, ctx, img, sx, sy, sw, sh, effectiveCellSize(preset.pixelConfig.cellSize, inst.pixelScale), elapsed, preset.revealConfig.pixDuration, preset.revealConfig.pixEasing, inst, targetW, targetH);\n    } else {\n      // Non-dot, non-pixel modes (custom presets) keep the original smooth\n      // photo for the revealed region.\n      ctx.imageSmoothingEnabled = true;\n      ctx.imageSmoothingQuality = 'high';\n      ctx.drawImage(getCoverBitmap(state, 'a', img, targetW, targetH), 0, 0);\n    }\n    ctx.globalCompositeOperation = 'destination-in';\n    // Mask upscale strategy depends on the sampling source:\n    //   - Dots presets (dotMode === 2) sample from the PIXEL-RENDERED shader,\n    //     so `maskGrad` is naturally cell-stepped. Upscaling 64 -> ~280 with\n    //     smoothing on blurs those cells into a mushy gradient (the very\n    //     issue introduced when MASK_SIZE shrank from 100 to 64 in the perf\n    //     pass). Switch to nearest-neighbour so the cells stay crisp — that\n    //     also matches the dotty character of these presets.\n    //   - Pixel presets (dotMode === 1) take the paintPixelMasked branch above.\n    //   - Geometric masks (useShader === false) compute analytical smooth\n    //     values, so smoothing stays on for them even in dot mode.\n    const sharpMask = preset.dotMode === 2 && useShader;\n    if (sharpMask) ctx.imageSmoothingEnabled = false;\n    ctx.drawImage(maskGrad, 0, 0, targetW, targetH);\n    if (sharpMask) ctx.imageSmoothingEnabled = true;\n    ctx.globalCompositeOperation = 'source-over';\n  }\n}\n\n/** Paints the pixel-mode-style \"downsampled image with per-cell random\n *  drop-out\" effect at an arbitrary cell-size scale, then leaves the\n *  caller to compose any additional masks on top. Used by dot-mode\n *  reveal so the gradual pixel-to-smooth transition matches the pixel\n *  presets — but at the dot grid's denser cell count, and with the shader\n *  mask applied AFTER this function returns to gate visible areas.\n *\n *  Shares scratch state (`pixCanvas`, `pixDrop`, `pixDropPattern`) with\n *  `paintPixelMasked`; safe because `preset.dotMode` is fixed per-instance,\n *  so only one of the two paths ever touches these for a given reveal state. */\nfunction paintPixelatedDropLayer(\n  state: RevealInternals,\n  ctx: CanvasRenderingContext2D,\n  img: HTMLImageElement,\n  sx: number,\n  sy: number,\n  sw: number,\n  sh: number,\n  cellSize: number,\n  elapsed: number,\n  pixDuration: number,\n  pixEasing: EnginePresetMode['revealConfig']['pixEasing'],\n  inst: Instance,\n  targetW: number,\n  targetH: number\n): void {\n  const baseCount = 6 + cellSize * 74;\n  const cssW = Math.max(1, inst.cssWidth);\n  const cssH = Math.max(1, inst.cssHeight);\n  const gridX = Math.max(2, Math.floor((baseCount * cssW) / REVEAL_REF_DIM));\n  const gridY = Math.max(2, Math.floor((baseCount * cssH) / REVEAL_REF_DIM));\n  const cellCount = gridX * gridY;\n\n  const pixDur = Math.max(0.05, pixDuration);\n  const fadeRaw = Math.max(0, Math.min(1, elapsed / pixDur));\n  const fadeT = ease(pixEasing, fadeRaw);\n\n  if (!state.pixCanvas) {\n    state.pixCanvas = document.createElement('canvas');\n    state.pixCtx = state.pixCanvas.getContext('2d');\n  }\n  const pixCanvas = state.pixCanvas as HTMLCanvasElement;\n  const pixCtx = state.pixCtx as CanvasRenderingContext2D;\n  if (pixCanvas.width !== gridX || pixCanvas.height !== gridY) {\n    pixCanvas.width = gridX;\n    pixCanvas.height = gridY;\n  }\n\n  if (!state.pixDrop) {\n    state.pixDrop = document.createElement('canvas');\n    state.pixDropCtx = state.pixDrop.getContext('2d');\n  }\n  const pixDrop = state.pixDrop as HTMLCanvasElement;\n  const pixDropCtx = state.pixDropCtx as CanvasRenderingContext2D;\n  if (pixDrop.width !== gridX || pixDrop.height !== gridY) {\n    pixDrop.width = gridX;\n    pixDrop.height = gridY;\n    state.pixDropImgData = pixDropCtx.createImageData(gridX, gridY);\n    const dd0 = state.pixDropImgData.data;\n    for (let i = 0; i < dd0.length; i += 4) {\n      dd0[i] = 255;\n      dd0[i + 1] = 255;\n      dd0[i + 2] = 255;\n    }\n  }\n\n  // Per-cell random drop thresholds — one Float32Array per reveal, reused\n  // every frame. Keeps GC pressure flat over long auto-cycle sessions.\n  const softBand = 0.07;\n  const invBand2 = 1 / (2 * softBand);\n  if (\n    !state.pixDropPattern ||\n    state.pixDropPatternW !== gridX ||\n    state.pixDropPatternH !== gridY ||\n    state.pixDropRevealStart !== state.revealStartMs\n  ) {\n    state.pixDropPattern = new Float32Array(cellCount);\n    const lo = softBand;\n    const span = 1 - 2 * softBand;\n    for (let i = 0; i < state.pixDropPattern.length; i++) {\n      state.pixDropPattern[i] = lo + Math.random() * span;\n    }\n    state.pixDropPatternW = gridX;\n    state.pixDropPatternH = gridY;\n    state.pixDropRevealStart = state.revealStartMs;\n  }\n  const dd = (state.pixDropImgData as ImageData).data;\n  const pattern = state.pixDropPattern;\n  for (let i = 0; i < pattern.length; i++) {\n    const dt = pattern[i];\n    let a = 0.5 + (dt - fadeT) * invBand2;\n    if (a < 0) a = 0;\n    else if (a > 1) a = 1;\n    dd[i * 4 + 3] = (a * 255 + 0.5) | 0;\n  }\n  pixDropCtx.putImageData(state.pixDropImgData as ImageData, 0, 0);\n\n  // 1. Downsample the source image into the pixelated grid (per frame —\n  //    the drop mask below is destructive, so we can't cache between frames\n  //    without an extra work canvas. The downsample is GPU-accelerated on\n  //    a ~38x38 target so the cost is in the 0.1-0.3 ms range).\n  pixCtx.globalCompositeOperation = 'source-over';\n  pixCtx.clearRect(0, 0, gridX, gridY);\n  pixCtx.imageSmoothingEnabled = true;\n  pixCtx.imageSmoothingQuality = 'high';\n  pixCtx.drawImage(getCoverBitmap(state, 'a', img, targetW, targetH), 0, 0, targetW, targetH, 0, 0, gridX, gridY);\n  // 2. Drop cells whose random threshold has fallen below `fadeT` — those\n  //    cells go transparent and the smooth base painted at step 3 shows\n  //    through.\n  pixCtx.globalCompositeOperation = 'destination-in';\n  pixCtx.imageSmoothingEnabled = false;\n  pixCtx.drawImage(pixDrop, 0, 0);\n  pixCtx.globalCompositeOperation = 'source-over';\n\n  // 3. Smooth full-res image as the base layer — visible wherever a cell\n  //    has already dropped out.\n  ctx.imageSmoothingEnabled = true;\n  ctx.imageSmoothingQuality = 'high';\n  ctx.drawImage(getCoverBitmap(state, 'a', img, targetW, targetH), 0, 0);\n  // 4. Chunky pixelated cells (with drops applied) composited on top.\n  //    Nearest-neighbour upscale keeps the dot grid blocks crisp.\n  ctx.imageSmoothingEnabled = false;\n  ctx.drawImage(pixCanvas, 0, 0, gridX, gridY, 0, 0, targetW, targetH);\n  ctx.imageSmoothingEnabled = true;\n}\n\nfunction paintPixelMasked(\n  state: RevealInternals,\n  ctx: CanvasRenderingContext2D,\n  img: HTMLImageElement,\n  sx: number,\n  sy: number,\n  sw: number,\n  sh: number,\n  preset: EnginePresetMode,\n  elapsed: number,\n  targetW: number,\n  targetH: number,\n  inst: Instance,\n  flickerAmp: number,\n  flickerHash: ((i: number, s: number) => number) | null,\n  flickerStep: number,\n  flickerStep1: number,\n  flickerFz: number\n): void {\n  // Per-cell random dissolve mask (port of image.html lines 2598-2695), with\n  // an anisotropic grid so cells are SQUARE in screen space — matches the\n  // shader's `gridCounts(...)` so the pixel-mode dissolve and the underlying\n  // pixel mosaic share the same cell grid.\n  const cellSize = effectiveCellSize(preset.pixelConfig.cellSize, inst.pixelScale);\n  const baseCount = 6 + cellSize * 74;\n  const cssW = Math.max(1, inst.cssWidth);\n  const cssH = Math.max(1, inst.cssHeight);\n  const gridX = Math.max(2, Math.floor((baseCount * cssW) / REVEAL_REF_DIM));\n  const gridY = Math.max(2, Math.floor((baseCount * cssH) / REVEAL_REF_DIM));\n  const cellCount = gridX * gridY;\n\n  const pixDur = Math.max(0.05, preset.revealConfig.pixDuration);\n  const fadeRaw = Math.max(0, Math.min(1, elapsed / pixDur));\n  const fadeT = ease(preset.revealConfig.pixEasing, fadeRaw);\n\n  if (!state.pixCanvas) {\n    state.pixCanvas = document.createElement('canvas');\n    state.pixCtx = state.pixCanvas.getContext('2d');\n  }\n  const pixCanvas = state.pixCanvas as HTMLCanvasElement;\n  const pixCtx = state.pixCtx as CanvasRenderingContext2D;\n  if (pixCanvas.width !== gridX || pixCanvas.height !== gridY) {\n    pixCanvas.width = gridX;\n    pixCanvas.height = gridY;\n  }\n  if (!state.pixDrop) {\n    state.pixDrop = document.createElement('canvas');\n    state.pixDropCtx = state.pixDrop.getContext('2d');\n  }\n  const pixDrop = state.pixDrop as HTMLCanvasElement;\n  const pixDropCtx = state.pixDropCtx as CanvasRenderingContext2D;\n  if (pixDrop.width !== gridX || pixDrop.height !== gridY) {\n    pixDrop.width = gridX;\n    pixDrop.height = gridY;\n    state.pixDropImgData = pixDropCtx.createImageData(gridX, gridY);\n    const dd0 = state.pixDropImgData.data;\n    for (let i = 0; i < dd0.length; i += 4) {\n      dd0[i] = 255;\n      dd0[i + 1] = 255;\n      dd0[i + 2] = 255;\n    }\n  }\n\n  const softBand = 0.07;\n  const invBand2 = 1 / (2 * softBand);\n  if (\n    !state.pixDropPattern ||\n    state.pixDropPatternW !== gridX ||\n    state.pixDropPatternH !== gridY ||\n    state.pixDropRevealStart !== state.revealStartMs\n  ) {\n    state.pixDropPattern = new Float32Array(cellCount);\n    const lo = softBand;\n    const span = 1 - 2 * softBand;\n    for (let i = 0; i < state.pixDropPattern.length; i++) {\n      state.pixDropPattern[i] = lo + Math.random() * span;\n    }\n    state.pixDropPatternW = gridX;\n    state.pixDropPatternH = gridY;\n    state.pixDropRevealStart = state.revealStartMs;\n  }\n  const dd = (state.pixDropImgData as ImageData).data;\n  const pattern = state.pixDropPattern;\n  const useFlicker = flickerAmp > 0.003 && flickerHash != null;\n  for (let i = 0; i < pattern.length; i++) {\n    const dt = pattern[i];\n    let a = 0.5 + (dt - fadeT) * invBand2;\n    if (a < 0) a = 0;\n    else if (a > 1) a = 1;\n    // Same flicker as the Gradient Sweep reveal mask: cells whose drop time\n    // is near the current dissolve position pop in and out (driven by\n    // `preset.flicker`) instead of fading monotonically, so pixel presets\n    // get the \"generating\" look during the reveal too.\n    if (useFlicker) {\n      const prox = 1 - Math.abs(fadeT - dt) * 6.25;\n      if (prox > 0) {\n        const rnd = flickerHash!(i, flickerStep) * (1 - flickerFz) + flickerHash!(i, flickerStep1) * flickerFz;\n        a += (rnd - 0.5) * flickerAmp * 1.6 * prox;\n        if (a < 0) a = 0;\n        else if (a > 1) a = 1;\n      }\n    }\n    dd[i * 4 + 3] = (a * 255 + 0.5) | 0;\n  }\n  pixDropCtx.putImageData(state.pixDropImgData as ImageData, 0, 0);\n\n  // 1. Downsample image into pixCanvas at the anisotropic grid (cover-fit\n  //    crop already chosen by caller, aspect preserved).\n  //    Mirrors image.html step 1 (line 2667).\n  pixCtx.globalCompositeOperation = 'source-over';\n  pixCtx.clearRect(0, 0, gridX, gridY);\n  pixCtx.imageSmoothingEnabled = true;\n  pixCtx.imageSmoothingQuality = 'high';\n  pixCtx.drawImage(getCoverBitmap(state, 'a', img, targetW, targetH), 0, 0, targetW, targetH, 0, 0, gridX, gridY);\n  // 2. Apply per-cell drop mask so dropped cells go transparent.\n  //    Mirrors image.html step 2 (line 2671).\n  pixCtx.globalCompositeOperation = 'destination-in';\n  pixCtx.imageSmoothingEnabled = false;\n  pixCtx.drawImage(pixDrop, 0, 0);\n  pixCtx.globalCompositeOperation = 'source-over';\n\n  // 3. Draw smooth image as the base layer — shows through any cell that\n  //    has already dropped out.\n  //    Mirrors image.html step 3 (line 2678).\n  ctx.imageSmoothingEnabled = true;\n  ctx.imageSmoothingQuality = 'high';\n  ctx.drawImage(getCoverBitmap(state, 'a', img, targetW, targetH), 0, 0);\n  // 4. Composite the still-present pixelated cells on top with crisp blocks\n  //    (nearest-neighbour upscale → chunky cells).\n  //    Mirrors image.html step 4 (line 2681).\n  ctx.imageSmoothingEnabled = false;\n  ctx.drawImage(pixCanvas, 0, 0, gridX, gridY, 0, 0, targetW, targetH);\n  ctx.imageSmoothingEnabled = true;\n\n  // 5. Quantise the reveal mask to the same anisotropic gridX×gridY so the\n  //    mask shape's edge follows the cell boundaries — i.e. the reveal\n  //    silhouette is cell-stepped, aligned with the shader's pixel mosaic.\n  //    This is what gives the pixel presets (Chromium Flow / Nebula) their\n  //    distinctive blocky reveal edge in image.html (step 5, lines 2686-2695).\n  //    The pixCanvas scratch is reused: it currently holds the per-cell\n  //    dissolved image from steps 1-2, but we overwrite it with the\n  //    downsampled maskGrad here before using it as a destination-in clip.\n  pixCtx.globalCompositeOperation = 'source-over';\n  pixCtx.clearRect(0, 0, gridX, gridY);\n  pixCtx.imageSmoothingEnabled = true;\n  pixCtx.imageSmoothingQuality = 'high';\n  pixCtx.drawImage(state.maskGrad as HTMLCanvasElement, 0, 0, gridX, gridY);\n  ctx.imageSmoothingEnabled = false;\n  ctx.globalCompositeOperation = 'destination-in';\n  ctx.drawImage(pixCanvas, 0, 0, gridX, gridY, 0, 0, targetW, targetH);\n  ctx.imageSmoothingEnabled = true;\n  ctx.globalCompositeOperation = 'source-over';\n}\n\n/** Boil (\"regenerating\") tuning. The boil opens with PIXELATE-IN: the sharp\n *  held image turns chunky cell-by-cell (each cell pops to its mosaic block\n *  with the flicker clock, over the smooth photo base) — no instant snap.\n *  Then the churn ramps in over BOIL_RAMP_S seconds, settling at BOIL_LEVEL\n *  dropped fraction. Which cells drop is driven primarily by the LIVE\n *  shader colour field, so the churn moves in the same organic waves as the\n *  img-fx animation. */\nconst BOIL_PIX_IN_MS = 800;\n/** How early the churn ramp starts before PIXELATE-IN completes — the tail\n *  of the image pixelation overlaps the head of the shader churn, so the\n *  two pixelation phases read as one continuous motion. */\nconst BOIL_PIX_OVERLAP_MS = 300;\nconst BOIL_RAMP_S = 1.0;\nconst BOIL_LEVEL = 0.5;\n/** Half-width of the alpha soft band — small so cells read as chunky\n *  blocks that flip on/off rather than a translucent blend. */\nconst BOIL_BAND = 0.03;\n/** How much of each cell's keep/drop threshold comes from the animated\n *  shader field vs. the persistent random pattern. The field contributes the\n *  organic wave structure; the flicker jitter (below) contributes the\n *  per-cell popping — mirroring how the shader itself pairs its slow noise\n *  field with u_flicker's cell jitter. */\nconst BOIL_FIELD_W = 0.6;\n/** Reveal handoff out of the boil (~2 s total), one continuous pipeline:\n *    1. BLEND   — the churning cells smoothly morph their colours from the\n *                 outgoing image to the incoming one (the mosaic downsample\n *                 cross-fades the two sources) while the churn keeps moving.\n *    2. RESOLVE — runs the reveal and the de-pixelation IN PARALLEL: the\n *                 smooth new image fades in underneath (through the churn\n *                 gaps) while the chunky cells melt into it with the pixel\n *                 reveal's per-cell dropout + flicker.\n *  No mask reset, no coverage jump — every stage starts where the previous\n *  one ended. */\nconst BOIL_BLEND_MS = 800;\n/** Smooth-image base fade-in at the start of RESOLVE. */\nconst BOIL_BASE_MS = 400;\n/** Per-cell chunky-to-smooth melt duration (whole RESOLVE stage). */\nconst BOIL_SHARPEN_MS = 1200;\n\n/** Sustained \"generating\" churn (phase `boil`): the held image is broken\n *  into the SAME anisotropic cell grid as the pixel reveal dissolve. Each\n *  cell's keep/drop threshold blends the LIVE shader field luminance at the\n *  cell (re-sampled every other frame, so the churn tracks the img-fx\n *  animation's moving waves) with a persistent random pattern, plus the\n *  reveal mask's flicker-clock jitter for the popping cadence. Dropped\n *  cells are fully transparent so the shader plays through the gaps.\n *  When a reveal is pending, runs the BLEND → RESOLVE handoff above and\n *  finishes by switching the state to `hold` + firing onRevealComplete. */\nfunction paintBoilFrame(\n  state: RevealInternals,\n  s: SharedRenderer,\n  inst: Instance,\n  ctx: CanvasRenderingContext2D,\n  shaderCanvas: HTMLCanvasElement,\n  nowMs: number\n): void {\n  const img = state.image;\n  if (!img) return;\n  const preset = inst.preset;\n  const targetW = inst.canvas.width;\n  const targetH = inst.canvas.height;\n  if (ctx.canvas.width !== targetW || ctx.canvas.height !== targetH) {\n    ctx.canvas.width = targetW;\n    ctx.canvas.height = targetH;\n  }\n  ctx.canvas.style.filter = 'none';\n\n  // Same grid math as paintPixelMasked so boil cells align with the shader\n  // mosaic and the reveal dissolve.\n  const cellSize = effectiveCellSize(preset.pixelConfig.cellSize, inst.pixelScale);\n  const baseCount = 6 + cellSize * 74;\n  const cssW = Math.max(1, inst.cssWidth);\n  const cssH = Math.max(1, inst.cssHeight);\n  const gridX = Math.max(2, Math.floor((baseCount * cssW) / REVEAL_REF_DIM));\n  const gridY = Math.max(2, Math.floor((baseCount * cssH) / REVEAL_REF_DIM));\n  const cellCount = gridX * gridY;\n\n  // Handoff timeline (only ticks once a reveal is pending).\n  const pending = state.pendingReveal;\n  const hand = pending && state.boilHandoffStartMs > 0 ? nowMs - state.boilHandoffStartMs : -1;\n  const smooth = (t: number): number => t * t * (3 - 2 * t);\n  const blendT = hand < 0 ? 0 : smooth(Math.min(1, hand / BOIL_BLEND_MS));\n  // RESOLVE stage clock: smooth base fades in over BOIL_BASE_MS while the\n  // per-cell melt runs the full BOIL_SHARPEN_MS — in parallel, so the\n  // de-pixelation starts the moment the new image begins to show.\n  const rt = hand < 0 ? -1 : hand - BOIL_BLEND_MS;\n  const baseT = rt <= 0 ? 0 : smooth(Math.min(1, rt / BOIL_BASE_MS));\n  const sharpRaw = rt <= 0 ? 0 : Math.min(1, rt / BOIL_SHARPEN_MS);\n  const resolving = pending != null && rt > 0;\n\n  // PIXELATE-IN: over the first BOIL_PIX_IN_MS the sharp image turns chunky\n  // cell-by-cell (flicker-clocked), drawn over the smooth photo base — so\n  // the pixelation materialises instead of snapping in one frame. The churn\n  // ramp starts only after it, when the mosaic fully covers the card.\n  const sinceStart = nowMs - state.boilStartMs;\n  const inRaw = Math.min(1, sinceStart / BOIL_PIX_IN_MS);\n  const inT = inRaw * inRaw * (3 - 2 * inRaw);\n  const pixelatingIn = inRaw < 1;\n  // The smooth-photo base fades out across the overlap window, so churn\n  // holes opening during the overlap cross-fade from photo to shader\n  // instead of popping when the base is dropped.\n  const baseOutRaw = Math.min(\n    1,\n    Math.max(0, sinceStart - (BOIL_PIX_IN_MS - BOIL_PIX_OVERLAP_MS)) / BOIL_PIX_OVERLAP_MS\n  );\n  const pixInBaseAlpha = 1 - baseOutRaw * baseOutRaw * (3 - 2 * baseOutRaw);\n\n  // Ramp-in: the pixelated image dissolves into the churn while the shader\n  // fades up through the dropped cells. Starts BOIL_PIX_OVERLAP_MS before\n  // pixelate-in ends so the two phases overlap. During RESOLVE the shader\n  // stays put — the smooth base drawn into the overlay at `baseT` alpha is\n  // what cross-fades it away.\n  const rampRaw = Math.min(\n    1,\n    Math.max(0, sinceStart - (BOIL_PIX_IN_MS - BOIL_PIX_OVERLAP_MS)) / (BOIL_RAMP_S * 1000)\n  );\n  const ramp = rampRaw * rampRaw * (3 - 2 * rampRaw);\n  const boilT = ramp * BOIL_LEVEL;\n  shaderCanvas.style.opacity = String(ramp);\n\n  // Shared scratch with the reveal pixel path (safe: only one phase runs at\n  // a time per reveal state).\n  if (!state.pixCanvas) {\n    state.pixCanvas = document.createElement('canvas');\n    state.pixCtx = state.pixCanvas.getContext('2d');\n  }\n  const pixCanvas = state.pixCanvas as HTMLCanvasElement;\n  const pixCtx = state.pixCtx as CanvasRenderingContext2D;\n  if (pixCanvas.width !== gridX || pixCanvas.height !== gridY) {\n    pixCanvas.width = gridX;\n    pixCanvas.height = gridY;\n  }\n  if (!state.pixDrop) {\n    state.pixDrop = document.createElement('canvas');\n    state.pixDropCtx = state.pixDrop.getContext('2d');\n  }\n  const pixDrop = state.pixDrop as HTMLCanvasElement;\n  const pixDropCtx = state.pixDropCtx as CanvasRenderingContext2D;\n  if (pixDrop.width !== gridX || pixDrop.height !== gridY || !state.pixDropImgData) {\n    pixDrop.width = gridX;\n    pixDrop.height = gridY;\n    state.pixDropImgData = pixDropCtx.createImageData(gridX, gridY);\n    const dd0 = state.pixDropImgData.data;\n    for (let i = 0; i < dd0.length; i += 4) {\n      dd0[i] = 255;\n      dd0[i + 1] = 255;\n      dd0[i + 2] = 255;\n    }\n  }\n\n  // Persistent per-cell thresholds: seeded once per boil so settled cells\n  // stay settled and only band cells churn.\n  if (!state.boilPattern || state.boilPatternW !== gridX || state.boilPatternH !== gridY) {\n    state.boilPattern = new Float32Array(cellCount);\n    for (let i = 0; i < cellCount; i++) state.boilPattern[i] = Math.random();\n    state.boilPatternW = gridX;\n    state.boilPatternH = gridY;\n  }\n\n  // Same flicker clock/hash as the reveal mask; clamped like there so slow\n  // presets still churn at a \"generating\" cadence. A floor on the amplitude\n  // keeps the boil alive even for presets authored with flicker: 0.\n  const amp = Math.max(preset.flicker ?? 0, 0.5);\n  const gsT = inst.accumulatedTime * Math.max(preset.speed, 2) * 1.6;\n  const rawStep = Math.floor(gsT);\n  const step = rawStep % 1024;\n  const step1 = (step + 1) % 1024;\n  let fz = gsT - rawStep;\n  fz = fz * fz * (3 - 2 * fz);\n  const hash = (i: number, st: number): number => {\n    const x = Math.sin(i * 127.1 + st * 17.23) * 43758.5453;\n    return x - Math.floor(x);\n  };\n\n  const dd = (state.pixDropImgData as ImageData).data;\n  const pattern = state.boilPattern;\n\n  // Live shader field, sampled into the small mask buffer exactly like the\n  // reveal's shader-driven masks. Per-cell luminance of this field is what\n  // makes the churn follow the effect's animation instead of reading as\n  // static. Throttled to every 3rd frame (vs every 2nd for reveal masks):\n  // profiling shows the GPU→CPU `getImageData` readback is the boil's\n  // dominant JS cost, and the churn tolerates a slightly staler field than\n  // a reveal mask edge — the per-frame flicker jitter (below) keeps the\n  // popping cadence at full rate, while the wave structure drifts slowly\n  // (speed 0.3–2 rad/s), so a ~300 ms-stale field is imperceptible.\n  const maskSize = getMaskSize(preset);\n  ensureScratch(state, maskSize);\n  const counter = state.sampleFrameCounter++;\n  const shouldSample = state.sampleDataCache == null || counter % 3 === 0;\n  const fieldStale = !state.boilField || state.boilField.length !== cellCount;\n  const sampleData = shouldSample\n    ? sampleShaderField(state, s, inst, state.sampleCtx as CanvasRenderingContext2D, maskSize)\n    : (state.sampleDataCache as Uint8ClampedArray);\n\n  // Per-cell field luminance is derived from the sample buffer, so it only\n  // changes when a fresh sample was taken (or the grid was resized). Values\n  // are stored PRE-NORMALISED (0..1 across the frame's min/max) so the\n  // per-frame threshold loop below is a plain array read. Normalising keeps\n  // every preset's field spanning the full threshold range — otherwise\n  // mostly-bright/mostly-dark palettes would pin the churn.\n  if (shouldSample || fieldStale) {\n    if (fieldStale) state.boilField = new Float32Array(cellCount);\n    const f = state.boilField as Float32Array;\n    let fMin = 1;\n    let fMax = 0;\n    for (let cy = 0; cy < gridY; cy++) {\n      const my = Math.min(maskSize - 1, ((cy + 0.5) * maskSize / gridY) | 0);\n      for (let cx = 0; cx < gridX; cx++) {\n        const mx = Math.min(maskSize - 1, ((cx + 0.5) * maskSize / gridX) | 0);\n        const si = (my * maskSize + mx) * 4;\n        const lum =\n          (sampleData[si] * 0.299 + sampleData[si + 1] * 0.587 + sampleData[si + 2] * 0.114) / 255;\n        f[cy * gridX + cx] = lum;\n        if (lum < fMin) fMin = lum;\n        if (lum > fMax) fMax = lum;\n      }\n    }\n    const fSpan = fMax - fMin > 0.001 ? 1 / (fMax - fMin) : 0;\n    for (let i = 0; i < cellCount; i++) {\n      f[i] = fSpan > 0 ? (f[i] - fMin) * fSpan : 0.5;\n    }\n  }\n  const field = state.boilField as Float32Array;\n\n  const invBand2 = 1 / (2 * BOIL_BAND);\n  // Flicker jitter span on top of the field: the raw field sample excludes\n  // the shader's own u_flicker cell jitter (it samples dotMode 0), so this\n  // reinstates that popping cadence — cells along the field's wave edges\n  // flip crisply on every flicker-clock step. Damped as the melt progresses\n  // so the resolving image settles.\n  const churn = amp * 0.6 * (1 - sharpRaw);\n  const patW = 1 - BOIL_FIELD_W;\n  // RESOLVE melt: per-cell chunky-to-smooth dropout, same mechanics as\n  // paintPixelMasked, reusing the boil pattern as the drop order. Runs in\n  // parallel with the churn — a cell is visible only while BOTH keep it.\n  const fadeT = resolving ? ease(preset.revealConfig.pixEasing, sharpRaw) : 0;\n  const softBand = 0.07;\n  const invBandS = 1 / (2 * softBand);\n  const sAmp = preset.flicker ?? 0;\n  for (let i = 0; i < cellCount; i++) {\n    const rnd = hash(i, step) * (1 - fz) + hash(i, step1) * fz;\n    // Threshold = animated field (waves) + stable random grain + flicker pop.\n    const dtEff = field[i] * BOIL_FIELD_W + pattern[i] * patW + (rnd - 0.5) * churn;\n    let a = 0.5 + (dtEff - boilT) * invBand2;\n    if (a < 0) a = 0;\n    else if (a > 1) a = 1;\n    if (pixelatingIn) {\n      // PIXELATE-IN appear mask: a cell turns chunky once `inT` passes its\n      // threshold; cells riding the edge pop in/out with the flicker clock,\n      // flashing between the smooth base and their mosaic block. Reverse of\n      // the RESOLVE melt below, same soft band and jitter mechanics.\n      const dt = pattern[i];\n      let aIn = 0.5 + (inT - dt) * invBandS;\n      if (aIn < 0) aIn = 0;\n      else if (aIn > 1) aIn = 1;\n      const prox = 1 - Math.abs(inT - dt) * 6.25;\n      if (prox > 0) {\n        aIn += (rnd - 0.5) * amp * 1.6 * prox;\n        if (aIn < 0) aIn = 0;\n        else if (aIn > 1) aIn = 1;\n      }\n      if (aIn < a) a = aIn;\n    }\n    if (resolving) {\n      const dt = pattern[i];\n      let a2 = 0.5 + (dt - fadeT) * invBandS;\n      if (a2 < 0) a2 = 0;\n      else if (a2 > 1) a2 = 1;\n      if (sAmp > 0.003) {\n        const prox = 1 - Math.abs(fadeT - dt) * 6.25;\n        if (prox > 0) {\n          a2 += (rnd - 0.5) * sAmp * 1.6 * prox;\n          if (a2 < 0) a2 = 0;\n          else if (a2 > 1) a2 = 1;\n        }\n      }\n      if (a2 < a) a = a2;\n    }\n    dd[i * 4 + 3] = (a * 255 + 0.5) | 0;\n  }\n  pixDropCtx.putImageData(state.pixDropImgData as ImageData, 0, 0);\n\n  // Mosaic source: the outgoing image, cross-faded toward the incoming one\n  // during BLEND. The blend happens in the downsampled grid BEFORE the\n  // nearest-neighbour upscale, so each chunky cell's colour morphs smoothly\n  // to the new image's colour at that spot. No smooth base during the churn\n  // stages — dropped cells stay transparent so the shader shows through.\n  pixCtx.globalCompositeOperation = 'source-over';\n  pixCtx.clearRect(0, 0, gridX, gridY);\n  pixCtx.imageSmoothingEnabled = true;\n  pixCtx.imageSmoothingQuality = 'high';\n  if (blendT < 1) {\n    pixCtx.drawImage(getCoverBitmap(state, 'a', img, targetW, targetH), 0, 0, targetW, targetH, 0, 0, gridX, gridY);\n  }\n  if (pending && blendT > 0) {\n    pixCtx.globalAlpha = blendT;\n    pixCtx.drawImage(getCoverBitmap(state, 'b', pending.image, targetW, targetH), 0, 0, targetW, targetH, 0, 0, gridX, gridY);\n    pixCtx.globalAlpha = 1;\n  }\n  pixCtx.globalCompositeOperation = 'destination-in';\n  pixCtx.imageSmoothingEnabled = false;\n  pixCtx.drawImage(pixDrop, 0, 0);\n  pixCtx.globalCompositeOperation = 'source-over';\n\n  ctx.clearRect(0, 0, targetW, targetH);\n  if (pixelatingIn && pixInBaseAlpha > 0) {\n    // PIXELATE-IN base: the sharp outgoing photo stays underneath while the\n    // chunky cells pop in over it — cells not yet (or flicker-momentarily\n    // not) pixelated show the smooth image, so the transition materialises\n    // instead of snapping. Fades out over the churn-overlap window so holes\n    // opened by the early churn cross-fade from photo to shader.\n    ctx.imageSmoothingEnabled = true;\n    ctx.imageSmoothingQuality = 'high';\n    ctx.globalAlpha = pixInBaseAlpha;\n    ctx.drawImage(getCoverBitmap(state, 'a', img, targetW, targetH), 0, 0);\n    ctx.globalAlpha = 1;\n  } else if (resolving && pending && baseT > 0) {\n    // Smooth base of the incoming image fades in underneath — visible\n    // immediately through the churn gaps (cross-fading the shader away) and\n    // wherever a chunky cell has already melted.\n    ctx.imageSmoothingEnabled = true;\n    ctx.imageSmoothingQuality = 'high';\n    ctx.globalAlpha = baseT;\n    ctx.drawImage(getCoverBitmap(state, 'b', pending.image, targetW, targetH), 0, 0);\n    ctx.globalAlpha = 1;\n  }\n  ctx.imageSmoothingEnabled = false;\n  ctx.drawImage(pixCanvas, 0, 0, gridX, gridY, 0, 0, targetW, targetH);\n  ctx.imageSmoothingEnabled = true;\n\n  // Handoff complete: the new image is fully sharp. Settle into `hold`\n  // exactly like a finished reveal.\n  if (resolving && pending && sharpRaw >= 1 && baseT >= 1) {\n    state.image = pending.image;\n    state.pendingReveal = null;\n    state.boilHandoffStartMs = 0;\n    state.holdPaintedImg = null;\n    state.phase = 'hold';\n    shaderCanvas.style.opacity = '0';\n    state.onRevealComplete?.();\n  }\n}\n\nexport interface CreateRevealOptions {\n  /** The DOM canvas overlay (sibling of the shader canvas). */\n  canvas: HTMLCanvasElement;\n  cssWidth: number;\n  cssHeight: number;\n  /** Shader canvas — its opacity is driven by the reveal so the image\n   *  cross-fades over it. */\n  shaderCanvas: HTMLCanvasElement;\n}\n\nexport function createReveal(opts: CreateRevealOptions): RevealState {\n  const ctx = opts.canvas.getContext('2d');\n  if (!ctx) throw new Error('img-fx: 2D context unavailable for reveal canvas');\n\n  const state: RevealInternals = {\n    active: false,\n    phase: 'idle',\n    revealStartMs: 0,\n    hideStartMs: 0,\n    hideDurationMs: 300,\n    boilStartMs: 0,\n    boilPattern: null,\n    boilPatternW: 0,\n    boilPatternH: 0,\n    boilField: null,\n    boilHandoffStartMs: 0,\n    pendingReveal: null,\n    image: null,\n    cssWidth: opts.cssWidth,\n    cssHeight: opts.cssHeight,\n    sampleCanvas: null,\n    sampleCtx: null,\n    sampleImgData: null,\n    sampleDataCache: null,\n    sampleFrameCounter: 0,\n    maskGrad: null,\n    maskGradCtx: null,\n    maskImgData: null,\n    gsFlickerTable: null,\n    pixCanvas: null,\n    pixCtx: null,\n    pixDrop: null,\n    pixDropCtx: null,\n    pixDropImgData: null,\n    pixDropPattern: null,\n    pixDropPatternW: 0,\n    pixDropPatternH: 0,\n    pixDropRevealStart: -1,\n    coverA: null,\n    coverB: null,\n    holdPaintedImg: null,\n    holdPaintedW: 0,\n    holdPaintedH: 0,\n    sampleGpuCanvas: null,\n    sampleGpuCtx: null\n  };\n\n  const shaderCanvas = opts.shaderCanvas;\n\n  /** Shared by `startReveal` and the boil-out completion path. */\n  function beginReveal(revealOpts: RevealStartOptions): void {\n    state.image = revealOpts.image;\n    state.cssWidth = revealOpts.cssWidth;\n    state.cssHeight = revealOpts.cssHeight;\n    state.onRevealComplete = revealOpts.onRevealComplete;\n    state.revealStartMs = performance.now();\n    state.phase = 'reveal';\n    state.active = true;\n    state.boilHandoffStartMs = 0;\n    state.pendingReveal = null;\n    // Reset the sample throttle so the very first frame of this reveal\n    // always does a fresh shader read; the cached buffer (if any) is from\n    // a previous reveal/boil and would be visually misaligned.\n    state.sampleFrameCounter = 0;\n    state.sampleDataCache = null;\n    state.holdPaintedImg = null;\n    ctx!.canvas.style.opacity = '1';\n  }\n\n  const handle: RevealState = {\n    canvas: opts.canvas,\n    ctx,\n    afterShaderFrame(s, inst, nowMs) {\n      // Keep canvas dims in sync with the dynamic CSS dims.\n      state.cssWidth = inst.cssWidth;\n      state.cssHeight = inst.cssHeight;\n\n      if (!state.active) {\n        // Idle - nothing to paint, leave overlay clear.\n        ctx.canvas.style.filter = 'none';\n        return;\n      }\n\n      const { duration, easingKey } = getActiveRevealTiming(inst.preset);\n\n      if (state.phase === 'reveal' && state.image) {\n        const elapsed = (nowMs - state.revealStartMs) / 1000;\n        const t = Math.min(elapsed / duration, 1);\n        const eased = ease(easingKey, t);\n        // Cross-fade: shader opacity drops as overlay fills in.\n        shaderCanvas.style.opacity = String(1 - eased);\n        paintMaskedFrame(state, s, inst, ctx);\n        if (t >= 1) {\n          state.phase = 'hold';\n          shaderCanvas.style.opacity = '0';\n          state.onRevealComplete?.();\n        }\n      } else if (state.phase === 'hold' && state.image) {\n        // Image fully visible. Re-paint a final stable frame so resizes are\n        // honored without re-running the dissolve.\n        ctx.canvas.style.filter = 'none';\n        const img = state.image;\n        const w = inst.canvas.width;\n        const h = inst.canvas.height;\n        if (ctx.canvas.width !== w || ctx.canvas.height !== h) {\n          ctx.canvas.width = w;\n          ctx.canvas.height = h;\n          state.holdPaintedImg = null;\n        }\n        // Paint once per image × size; the held frame is static, so\n        // repainting it every tick was pure waste (a full-canvas\n        // high-quality resample per card, 10×/s, for the whole hold).\n        if (state.holdPaintedImg !== img || state.holdPaintedW !== w || state.holdPaintedH !== h) {\n          ctx.clearRect(0, 0, w, h);\n          ctx.globalCompositeOperation = 'source-over';\n          ctx.globalAlpha = 1;\n          ctx.imageSmoothingEnabled = true;\n          ctx.imageSmoothingQuality = 'high';\n          ctx.drawImage(getCoverBitmap(state, 'a', img, w, h), 0, 0);\n          state.holdPaintedImg = img;\n          state.holdPaintedW = w;\n          state.holdPaintedH = h;\n        }\n        shaderCanvas.style.opacity = '0';\n      } else if (state.phase === 'boil' && state.image) {\n        // Handles the whole regeneration lifecycle including the pending\n        // reveal handoff (BLEND → RESOLVE) — transitions itself to\n        // `hold` and fires onRevealComplete when the new image is sharp.\n        paintBoilFrame(state, s, inst, ctx, shaderCanvas, nowMs);\n      } else if (state.phase === 'hide') {\n        const elapsed = nowMs - state.hideStartMs;\n        const t = Math.min(elapsed / Math.max(1, state.hideDurationMs), 1);\n        const overlayAlpha = 1 - t;\n        ctx.canvas.style.opacity = String(overlayAlpha);\n        shaderCanvas.style.opacity = String(t);\n        if (t >= 1) {\n          // Done - reset.\n          state.active = false;\n          state.phase = 'idle';\n          ctx.canvas.style.opacity = '1';\n          ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n          shaderCanvas.style.opacity = '1';\n          state.image = null;\n        }\n      }\n    },\n    startReveal(opts) {\n      if (state.phase === 'boil' && state.active) {\n        // Don't cut the churn off — hand the incoming image to the boil,\n        // which morphs the churning cells' colours to it, closes the mosaic,\n        // and sharpens (see paintBoilFrame). It fires onRevealComplete and\n        // settles into `hold` itself, exactly like a regular reveal.\n        state.pendingReveal = opts;\n        state.onRevealComplete = opts.onRevealComplete;\n        state.cssWidth = opts.cssWidth;\n        state.cssHeight = opts.cssHeight;\n        if (state.boilHandoffStartMs === 0) state.boilHandoffStartMs = performance.now();\n        return;\n      }\n      beginReveal(opts);\n    },\n    startHide(durationMs = 300) {\n      if (!state.active || state.phase === 'hide') return;\n      state.phase = 'hide';\n      state.hideStartMs = performance.now();\n      state.hideDurationMs = durationMs;\n    },\n    startBoil() {\n      // Needs a held/revealing image to churn; no-op otherwise.\n      if (!state.active || !state.image) return;\n      if (state.phase !== 'hold' && state.phase !== 'reveal') return;\n      state.phase = 'boil';\n      state.boilStartMs = performance.now();\n      state.boilHandoffStartMs = 0;\n      state.pendingReveal = null;\n      // Reseed so every regeneration churns a fresh cell pattern, and force\n      // a fresh shader-field sample on the first boil frame.\n      state.boilPattern = null;\n      state.sampleFrameCounter = 0;\n      state.sampleDataCache = null;\n      state.holdPaintedImg = null;\n      ctx.canvas.style.opacity = '1';\n    },\n    clear() {\n      // Only undo the cross-fade styles if a reveal actually touched them.\n      // `cycle.stop()` calls clear() even when nothing ever ran (e.g. the\n      // autoReveal=false effect on mount), and unconditionally forcing the\n      // shader canvas back to opacity 1 would stomp the consumer's\n      // `strength`-driven opacity set moments earlier.\n      const wasActive = state.active;\n      state.active = false;\n      state.phase = 'idle';\n      state.image = null;\n      state.boilHandoffStartMs = 0;\n      state.pendingReveal = null;\n      state.holdPaintedImg = null;\n      ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n      if (wasActive) {\n        ctx.canvas.style.filter = 'none';\n        ctx.canvas.style.opacity = '1';\n        shaderCanvas.style.opacity = '1';\n      }\n    },\n    isActive() {\n      return state.active;\n    },\n    dispose() {\n      state.image = null;\n      state.sampleCanvas = null;\n      state.sampleCtx = null;\n      state.sampleImgData = null;\n      state.sampleDataCache = null;\n      state.sampleFrameCounter = 0;\n      state.maskGrad = null;\n      state.maskGradCtx = null;\n      state.maskImgData = null;\n      state.gsFlickerTable = null;\n      state.pixCanvas = null;\n      state.pixCtx = null;\n      state.pixDrop = null;\n      state.pixDropCtx = null;\n      state.pixDropImgData = null;\n      state.pixDropPattern = null;\n      state.boilPattern = null;\n      state.boilField = null;\n      state.pendingReveal = null;\n      state.coverA = null;\n      state.coverB = null;\n      state.holdPaintedImg = null;\n      state.sampleGpuCanvas = null;\n      state.sampleGpuCtx = null;\n    }\n  };\n\n  return handle;\n}\n\n/** Pull a random image from `pool`, never repeating the previous index. */\nexport function pickRandomImage(pool: string[], lastIdx: number): { src: string; idx: number } | null {\n  if (pool.length === 0) return null;\n  if (pool.length === 1) return { src: pool[0], idx: 0 };\n  let idx: number;\n  do {\n    idx = Math.floor(Math.random() * pool.length);\n  } while (idx === lastIdx);\n  return { src: pool[idx], idx };\n}\n"
        },
        {
          "path": "components/effects/img-fx/upstream/engine/tween.ts",
          "target": "@components/effects/img-fx/upstream/engine/tween.ts",
          "type": "registry:component",
          "content": "/**\n * Easing function table — keys match the `EasingKey` type in `presets/index.ts`\n * and the dropdown options in `image.html` (lines 2343-2351).\n */\nimport type { EasingKey } from '../presets';\n\nexport type EaseFn = (t: number) => number;\n\nexport const EASING_FNS: Record<EasingKey, EaseFn> = {\n  linear: (t) => t,\n  smoothstep: (t) => t * t * (3 - 2 * t),\n  easeOutCubic: (t) => 1 - Math.pow(1 - t, 3),\n  easeOutQuint: (t) => 1 - Math.pow(1 - t, 5),\n  easeInOutCubic: (t) => (t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2),\n  easeOutExpo: (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)),\n  easeOutBack: (t) => {\n    const c = 1.70158;\n    return 1 + (c + 1) * Math.pow(t - 1, 3) + c * Math.pow(t - 1, 2);\n  }\n};\n\nexport function ease(key: EasingKey, t: number): number {\n  const fn = EASING_FNS[key] ?? EASING_FNS.smoothstep;\n  return fn(Math.max(0, Math.min(1, t)));\n}\n"
        },
        {
          "path": "components/effects/img-fx/upstream/engine/cycle.ts",
          "target": "@components/effects/img-fx/upstream/engine/cycle.ts",
          "type": "registry:component",
          "content": "/**\n * Auto-loop reveal scheduler.\n *\n * Each <ImageGeneration autoReveal> mounts a Cycle that drives the four\n * phases:\n *\n *   idle    -> wait random(min..max) seconds (just shader running)\n *   reveal  -> trigger reveal animation in reveal.ts (preset.revealConfig.duration)\n *   visible -> hold image visible for `revealHoldMs`\n *   hide    -> 300 ms cross-fade back to shader\n *   -> idle\n *\n * `paused` clears the pending timer; resuming re-enters the same phase with a\n * fresh delay. `onCycle` fires on every phase change so consumers can wire\n * analytics or sync external state.\n */\nimport { loadImage, pickRandomImage, type RevealState } from './reveal';\n\nexport type CyclePhase = 'idle' | 'reveal' | 'visible' | 'hide';\n\nexport interface CycleEvent {\n  phase: CyclePhase;\n  src: string | null;\n}\n\nexport interface CycleOptions {\n  reveal: RevealState;\n  /** Image pool. Random pick per cycle, never same as previous. */\n  images: string[];\n  /** Random seconds in `idle` phase (shader-only). */\n  delayRange: [number, number];\n  /**\n   * Time the image stays visible after the reveal completes.\n   * - `number` — fixed ms.\n   * - `[min, max]` — random ms per cycle, re-rolled each reveal.\n   */\n  holdMs: number | [number, number];\n  /** ms cross-fade back to shader. */\n  fadeOutMs: number;\n  /** Random initial delay seed so multiple cycles don't sync. */\n  initialDelayMs?: number;\n  /** Cycle event hook. */\n  onPhase?: (event: CycleEvent) => void;\n  /**\n   * Optional callback invoked just before each pick that returns a list of\n   * src strings the cycle MUST avoid this round (in addition to its own\n   * \"no immediate repeat\" rule). Use this to coordinate multiple cycles so\n   * they never display the same image at the same time. If every candidate\n   * is excluded the cycle falls back to the standard random pick.\n   */\n  excludeSrcs?: () => string[] | Set<string> | null | undefined;\n}\n\nexport interface Cycle {\n  start: () => void;\n  stop: () => void;\n  /** Replace the `excludeSrcs` callback (or clear it by passing `null`). */\n  setExcludeSrcs: (fn: CycleOptions['excludeSrcs'] | null) => void;\n  /**\n   * Fire a single reveal pass *now*, regardless of whether the cycle is\n   * currently auto-running. No-op if a reveal is already in progress\n   * (`reveal`/`visible`/`hide` phases).\n   *\n   * `hold: 'auto'` (default) — runs reveal -> hold (`holdMs`) -> hide\n   * automatically. When auto-running this re-enters the auto-loop afterwards;\n   * otherwise the cycle returns to a stopped idle state.\n   *\n   * `hold: 'manual'` — runs reveal then stays in the `visible` phase\n   * indefinitely. Call `triggerHide()` to fade out.\n   */\n  triggerOnce: (opts?: { hold?: 'auto' | 'manual' }) => void;\n  /**\n   * Manually trigger the hide fade if currently in `reveal` or `visible`\n   * phase. No-op otherwise. Useful for \"Hide image\" buttons that complement\n   * a `triggerOnce({ hold: 'manual' })` call.\n   */\n  triggerHide: () => void;\n  /**\n   * Dissolve the currently revealed image into a sustained \"regenerating\"\n   * pixel churn: the image breaks into the effect's cell grid, cells pop\n   * in/out with the preset's flicker clock, and the shader plays through the\n   * gaps (see `RevealState.startBoil`). The cycle returns to a stopped\n   * `idle` state so the consumer can end the churn with `triggerOnce()`\n   * (reveals the next image over it) or `stop()`. No-op unless currently in\n   * `reveal`/`visible`.\n   *\n   * `autoRevealAfterMs` — when set, the churn ends by itself: after that many\n   * ms the cycle fires `triggerOnce({ hold: 'manual' })`, dissolving the next\n   * image in over the churn. Any manual `triggerOnce()` / `stop()` before the\n   * timer fires cancels it.\n   */\n  triggerBoil: (opts?: { autoRevealAfterMs?: number }) => void;\n  /** Current phase of the cycle. Useful for syncing UI button state. */\n  getPhase: () => CyclePhase;\n  setPaused: (paused: boolean) => void;\n  setImages: (images: string[]) => void;\n  setOptions: (opts: Partial<Pick<CycleOptions, 'delayRange' | 'holdMs' | 'fadeOutMs' | 'onPhase'>>) => void;\n  isRunning: () => boolean;\n  dispose: () => void;\n}\n\nexport function createCycle(opts: CycleOptions): Cycle {\n  let images = opts.images.slice();\n  let delayRange = opts.delayRange;\n  let holdMs = opts.holdMs;\n  let fadeOutMs = opts.fadeOutMs;\n  let onPhase = opts.onPhase;\n  let excludeSrcs = opts.excludeSrcs;\n\n  let phase: CyclePhase = 'idle';\n  let timer: ReturnType<typeof setTimeout> | null = null;\n  let lastIdx = -1;\n  let running = false;\n  let paused = false;\n  let currentSrc: string | null = null;\n  // Captured at the start of each reveal so that the hide tail can decide\n  // whether to re-enter the auto-loop (`scheduleIdle()`) or come to a stopped\n  // idle. Avoids needing to inspect mutable state at the moment of hide.\n  let activeReschedule = false;\n  // Hold mode for the currently-active reveal. `manual` means we stay in the\n  // `visible` phase indefinitely until `triggerHide()` is called — so resume\n  // from pause must NOT re-arm the auto-hide timer.\n  let activeHoldMode: 'auto' | 'manual' = 'auto';\n\n  function emit(p: CyclePhase): void {\n    phase = p;\n    onPhase?.({ phase: p, src: currentSrc });\n  }\n\n  function clearTimer(): void {\n    if (timer != null) {\n      clearTimeout(timer);\n      timer = null;\n    }\n  }\n\n  /** Resolve `holdMs` to a concrete millisecond value. Tuples re-roll on\n   *  every reveal so consecutive cycles never hold for the same duration. */\n  function pickHoldMs(): number {\n    if (typeof holdMs === 'number') return Math.max(0, holdMs);\n    const [min, max] = holdMs;\n    const lo = Math.max(0, Math.min(min, max));\n    const hi = Math.max(0, Math.max(min, max));\n    return lo + Math.random() * (hi - lo);\n  }\n\n  function scheduleIdle(initialMs?: number): void {\n    if (!running || paused) return;\n    emit('idle');\n    const [min, max] = delayRange;\n    const delaySec = min + Math.random() * Math.max(0, max - min);\n    const ms = initialMs ?? delaySec * 1000;\n    clearTimer();\n    timer = setTimeout(() => {\n      timer = null;\n      runReveal(true, 'auto');\n    }, ms);\n  }\n\n  function performHide(): void {\n    if (paused) return;\n    emit('hide');\n    opts.reveal.startHide(fadeOutMs);\n    clearTimer();\n    timer = setTimeout(() => {\n      timer = null;\n      if (paused) return;\n      currentSrc = null;\n      if (activeReschedule) {\n        scheduleIdle();\n      } else {\n        running = false;\n        emit('idle');\n      }\n    }, fadeOutMs);\n  }\n\n  function pickAvoidingExcluded(): { src: string; idx: number } | null {\n    if (images.length === 0) return null;\n    const raw = excludeSrcs?.();\n    const exclSet =\n      raw == null\n        ? null\n        : raw instanceof Set\n          ? raw\n          : new Set(raw);\n    if (!exclSet || exclSet.size === 0) {\n      return pickRandomImage(images, lastIdx);\n    }\n    // Build a candidate list: exclude srcs in `exclSet` AND the immediately\n    // previous pick (so the same card never repeats consecutively either).\n    const lastSrc = lastIdx >= 0 && lastIdx < images.length ? images[lastIdx] : null;\n    const candidates: number[] = [];\n    for (let i = 0; i < images.length; i++) {\n      const src = images[i];\n      if (exclSet.has(src)) continue;\n      if (src === lastSrc && images.length > exclSet.size + 1) continue;\n      candidates.push(i);\n    }\n    if (candidates.length === 0) {\n      // Pool fully exhausted by exclusions — fall back to a regular random\n      // pick so we never deadlock the auto-loop.\n      return pickRandomImage(images, lastIdx);\n    }\n    const idx = candidates[Math.floor(Math.random() * candidates.length)];\n    return { src: images[idx], idx };\n  }\n\n  function runReveal(reschedule: boolean, holdMode: 'auto' | 'manual'): void {\n    if (!running || paused) return;\n    if (images.length === 0) {\n      if (reschedule) scheduleIdle(500);\n      else running = false;\n      return;\n    }\n    const pick = pickAvoidingExcluded();\n    if (!pick) {\n      if (reschedule) scheduleIdle(500);\n      else running = false;\n      return;\n    }\n    lastIdx = pick.idx;\n    currentSrc = pick.src;\n    activeReschedule = reschedule;\n    activeHoldMode = holdMode;\n    loadImage(pick.src)\n      .then((img) => {\n        if (!running || paused) return;\n        emit('reveal');\n        opts.reveal.startReveal({\n          image: img,\n          cssWidth: opts.reveal.canvas.clientWidth || opts.reveal.canvas.width,\n          cssHeight: opts.reveal.canvas.clientHeight || opts.reveal.canvas.height,\n          onRevealComplete: () => {\n            if (!running || paused) return;\n            emit('visible');\n            if (holdMode === 'manual') {\n              // Stay in `visible` indefinitely; consumer will call triggerHide()\n              // to fade back to the shader.\n              clearTimer();\n              return;\n            }\n            clearTimer();\n            const thisHoldMs = pickHoldMs();\n            timer = setTimeout(() => {\n              timer = null;\n              if (!running || paused) return;\n              performHide();\n            }, thisHoldMs);\n          }\n        });\n      })\n      .catch(() => {\n        currentSrc = null;\n        if (reschedule) scheduleIdle(500);\n        else running = false;\n      });\n  }\n\n  function triggerOnceImpl(triggerOpts?: { hold?: 'auto' | 'manual' }): void {\n    if (paused) return;\n    // Don't interrupt an in-flight reveal/hold/hide.\n    if (phase === 'reveal' || phase === 'visible' || phase === 'hide') return;\n    const wasRunning = running;\n    clearTimer();\n    if (!wasRunning) {\n      // Spin up just enough state for runReveal to proceed; mark as running\n      // so the bail guards inside runReveal pass. `reschedule=false` makes\n      // runReveal return us to a stopped idle state once hide completes.\n      running = true;\n    }\n    runReveal(wasRunning, triggerOpts?.hold ?? 'auto');\n  }\n\n  return {\n    start() {\n      if (running) return;\n      running = true;\n      paused = false;\n      const initial = opts.initialDelayMs ?? Math.random() * 1500;\n      scheduleIdle(initial);\n    },\n    stop() {\n      running = false;\n      clearTimer();\n      opts.reveal.clear();\n      currentSrc = null;\n      phase = 'idle';\n    },\n    triggerOnce(triggerOpts) {\n      triggerOnceImpl(triggerOpts);\n    },\n    triggerHide() {\n      if (paused) return;\n      if (phase !== 'reveal' && phase !== 'visible') return;\n      performHide();\n    },\n    triggerBoil(boilOpts) {\n      if (paused) return;\n      if (phase !== 'reveal' && phase !== 'visible') return;\n      clearTimer();\n      opts.reveal.startBoil();\n      currentSrc = null;\n      // Come to a stopped idle (like a completed manual hide) so a later\n      // triggerOnce() runs a single non-rescheduling reveal over the churn.\n      running = false;\n      emit('idle');\n      // Optional self-ending churn: reveal the next image over the boil\n      // after the requested duration. Uses the shared timer slot, so any\n      // manual triggerOnce()/stop() in the meantime cancels it.\n      const afterMs = boilOpts?.autoRevealAfterMs;\n      if (afterMs != null && Number.isFinite(afterMs)) {\n        timer = setTimeout(() => {\n          timer = null;\n          triggerOnceImpl({ hold: 'manual' });\n        }, Math.max(0, afterMs));\n      }\n    },\n    getPhase() {\n      return phase;\n    },\n    setPaused(p) {\n      if (paused === p) return;\n      paused = p;\n      if (paused) {\n        clearTimer();\n      } else if (running) {\n        // Resume — re-enter idle with a small randomised delay so we don't\n        // immediately fire a reveal mid-hold/hide.\n        if (phase === 'visible') {\n          if (activeHoldMode === 'manual') {\n            // Manual hold: stay visible indefinitely; `triggerHide()` will\n            // fade it out on demand. Don't re-arm any auto-hide timer.\n            return;\n          }\n          // Re-arm hold timer with a short cap (max 500 ms) so a resume\n          // doesn't tack a fresh full hold onto whatever was already shown.\n          clearTimer();\n          timer = setTimeout(() => {\n            timer = null;\n            performHide();\n          }, Math.min(pickHoldMs(), 500));\n        } else if (phase === 'hide') {\n          // Already animating; let it complete.\n          clearTimer();\n          timer = setTimeout(() => {\n            timer = null;\n            currentSrc = null;\n            scheduleIdle();\n          }, fadeOutMs);\n        } else {\n          scheduleIdle();\n        }\n      }\n    },\n    setImages(next) {\n      images = next.slice();\n      lastIdx = -1;\n    },\n    setExcludeSrcs(fn) {\n      excludeSrcs = fn ?? undefined;\n    },\n    setOptions(next) {\n      if (next.delayRange) delayRange = next.delayRange;\n      if (next.holdMs != null) holdMs = next.holdMs;\n      if (next.fadeOutMs != null) fadeOutMs = next.fadeOutMs;\n      if (next.onPhase) onPhase = next.onPhase;\n    },\n    isRunning() {\n      return running && !paused;\n    },\n    dispose() {\n      running = false;\n      clearTimer();\n    }\n  };\n}\n"
        },
        {
          "path": "components/effects/img-fx/upstream/engine/palette.ts",
          "target": "@components/effects/img-fx/upstream/engine/palette.ts",
          "type": "registry:component",
          "content": "/**\n * Image-palette sampling for the regenerate flow.\n *\n * `samplePaletteFromCanvas` averages the source canvas down to a small grid,\n * sorts its pixels by luminance, and replaces each of the preset's 7 palette\n * slots with the image color at the same luminance RANK the slot has inside\n * the preset palette. The effect keeps its authored contrast structure (which\n * slots read dark / light) but wears the image's colors — same cells, same\n * animation, image-born pixelation.\n */\nimport { parseCssColor } from '../presets';\n\nexport interface SampledPalette {\n  /** One CSS hex color per shader palette slot (7 entries). */\n  colors: string[];\n  /** Average image color — used as the card surface behind the effect. */\n  cardBg: string;\n}\n\nconst lum = (r: number, g: number, b: number): number => 0.299 * r + 0.587 * g + 0.114 * b;\nconst hex = (r: number, g: number, b: number): string =>\n  `#${[r, g, b].map((v) => Math.round(v).toString(16).padStart(2, '0')).join('')}`;\n\n/** Downsample grid edge. 24x24 = 576 samples — plenty for a 7-color palette. */\nconst GRID = 24;\n\n// One shared scratch canvas for all instances/calls (sampling is synchronous\n// and single-threaded, so reuse is safe and avoids per-call allocations).\nlet scratch: HTMLCanvasElement | null = null;\nlet scratchCtx: CanvasRenderingContext2D | null = null;\n\nfunction getScratchCtx(): CanvasRenderingContext2D | null {\n  if (scratchCtx) return scratchCtx;\n  if (typeof document === 'undefined') return null;\n  scratch = document.createElement('canvas');\n  scratch.width = GRID;\n  scratch.height = GRID;\n  scratchCtx = scratch.getContext('2d', { willReadFrequently: true });\n  return scratchCtx;\n}\n\n/**\n * Sample an image-derived recolor for the running effect from `src` (any\n * drawable canvas — typically the reveal overlay showing the current image).\n *\n * `presetColors` is the active preset mode's 7-slot palette; the returned\n * `colors` array maps image colors onto those slots by luminance rank.\n * Returns null when sampling isn't possible (SSR, empty canvas).\n */\nexport function samplePaletteFromCanvas(\n  src: HTMLCanvasElement,\n  presetColors: readonly string[]\n): SampledPalette | null {\n  if (src.width === 0 || src.height === 0) return null;\n  const ctx = getScratchCtx();\n  if (!ctx) return null;\n  ctx.imageSmoothingEnabled = true;\n  ctx.clearRect(0, 0, GRID, GRID);\n  ctx.drawImage(src, 0, 0, GRID, GRID);\n\n  let data: Uint8ClampedArray;\n  try {\n    data = ctx.getImageData(0, 0, GRID, GRID).data;\n  } catch {\n    // Tainted canvas (cross-origin image without CORS) — can't sample.\n    return null;\n  }\n\n  const px: Array<{ r: number; g: number; b: number; lum: number }> = [];\n  let ar = 0;\n  let ag = 0;\n  let ab = 0;\n  for (let i = 0; i < data.length; i += 4) {\n    if (data[i + 3] < 8) continue; // skip fully-transparent corners (radius)\n    const r = data[i];\n    const g = data[i + 1];\n    const b = data[i + 2];\n    px.push({ r, g, b, lum: lum(r, g, b) });\n    ar += r;\n    ag += g;\n    ab += b;\n  }\n  if (px.length === 0) return null;\n  px.sort((a, b) => a.lum - b.lum);\n  const cardBg = hex(ar / px.length, ag / px.length, ab / px.length);\n\n  // Preset slots ranked by luminance -> image luminance quantile per rank.\n  const ranked = presetColors\n    .map((color, slot) => {\n      const [r, g, b] = parseCssColor(color);\n      return { slot, lum: lum(r, g, b) };\n    })\n    .sort((a, b) => a.lum - b.lum);\n  const colors: string[] = new Array(ranked.length);\n  for (let rank = 0; rank < ranked.length; rank++) {\n    // Spread ranks across the image's luminance range (5th..95th percentile).\n    const q = 0.05 + (0.9 * rank) / Math.max(1, ranked.length - 1);\n    const p = px[Math.min(px.length - 1, Math.round(q * (px.length - 1)))];\n    colors[ranked[rank].slot] = hex(p.r, p.g, p.b);\n  }\n  return { colors, cardBg };\n}\n"
        },
        {
          "path": "components/effects/img-fx/upstream/styles.ts",
          "target": "@components/effects/img-fx/upstream/styles.ts",
          "type": "registry:component",
          "content": "/** Singleton CSS injection — one <style> tag per page, no matter how many\n *  <ImageGeneration> instances are mounted. */\n\nconst STYLE_ID = 'img-fx-styles';\n\nconst CSS = /* css */ `\n.image-gen-root {\n  position: relative;\n  display: inline-block;\n  isolation: isolate;\n  overflow: hidden;\n  vertical-align: top;\n  line-height: 0;\n  flex: 0 0 auto;\n}\n\n.image-gen-root > .image-gen-shader,\n.image-gen-root > .image-gen-overlay {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: none;\n  border-radius: inherit;\n  display: block;\n}\n\n.image-gen-root > .image-gen-shader {\n  z-index: 1;\n}\n\n.image-gen-root > .image-gen-overlay {\n  z-index: 2;\n}\n\n.image-gen-root > .image-gen-child {\n  position: relative;\n  z-index: 0;\n  display: block;\n  line-height: normal;\n}\n`;\n\nlet injected = false;\n\nexport function ensureStylesInjected(): void {\n  if (typeof document === 'undefined') return;\n  if (injected) return;\n  if (document.getElementById(STYLE_ID)) {\n    injected = true;\n    return;\n  }\n  const styleEl = document.createElement('style');\n  styleEl.id = STYLE_ID;\n  styleEl.textContent = CSS;\n  document.head.appendChild(styleEl);\n  injected = true;\n}\n"
        },
        {
          "path": "components/effects/img-fx/upstream/types.ts",
          "target": "@components/effects/img-fx/upstream/types.ts",
          "type": "registry:component",
          "content": "import type { CSSProperties, HTMLAttributes, ReactNode } from 'react';\nimport type { CycleEvent } from './engine';\nimport type { PresetName } from './presets';\n\n/**\n * Theme mode for the img-fx effect.\n *\n * - `auto` (default): walks a small priority chain and updates live on any\n *   change:\n *     1. `<html data-theme=\"dark|light\">`             — shadcn / SSR apps\n *     2. `<html class=\"dark\">` / `class=\"light\">`     — Tailwind v3 darkMode\n *     3. `<html style=\"color-scheme: dark|light\">`    — CSS-only toggles\n *     4. `matchMedia('(prefers-color-scheme: dark)')` — OS preference\n *     5. `'dark'` fallback (SSR-safe; re-resolves on hydration)\n *   A MutationObserver on `<html>` re-resolves whenever class / style /\n *   data-theme changes, so JS theme toggles propagate without a remount.\n * - `dark` / `light`: pin to a specific mode regardless of system / app\n *   preference.\n */\nexport type ImageGenerationTheme = 'auto' | 'dark' | 'light';\n\n/** Bundled preset names. Each preset ships both a dark and light tunings block. */\nexport type ImageGenerationPreset = PresetName;\n\n/** Phase event emitted by the auto-reveal scheduler. */\nexport type ImageGenerationCycleEvent = CycleEvent;\n\n/**\n * Imperative handle exposed via `ref` on `<ImageGeneration>`. Lets callers\n * trigger a single reveal from a button click or other user action without\n * enabling `autoReveal`.\n *\n * The wrapper element itself is also reachable via `handle.element`.\n */\nexport interface ImageGenerationHandle {\n  /** The wrapper `<div>` element. */\n  element: HTMLDivElement | null;\n  /**\n   * Run a reveal pass now.\n   *\n   * - No-op if a reveal is already in progress (currently revealing, holding\n   *   the image visible, or fading back to the shader).\n   * - `hold: 'auto'` (default) — runs reveal -> hold (`revealHoldMs`) -> hide\n   *   automatically, mirroring the auto-loop's pass.\n   * - `hold: 'manual'` — runs reveal then stays in the visible phase until\n   *   `triggerHide()` is called. Use this for \"Reveal / Hide\" toggle buttons.\n   *\n   * Requires a non-empty `images` prop; otherwise it's a silent no-op.\n   */\n  triggerReveal: (opts?: { hold?: 'auto' | 'manual' }) => void;\n  /**\n   * Manually trigger the hide fade if an image is currently revealed (in\n   * `reveal` or `visible` phase). No-op otherwise.\n   */\n  triggerHide: () => void;\n  /**\n   * Regenerate the currently revealed image in place: the image breaks into\n   * the effect's pixel-cell grid, the cells churn (pop in/out with the\n   * preset's flicker clock) while the shader plays through the gaps, and\n   * after `durationMs` the next image from the pool dissolves in over the\n   * churn (held like `triggerReveal({ hold: 'manual' })`).\n   *\n   * By default the effect is also recolored from the outgoing image — its\n   * palette is sampled from the visible pixels and mapped onto the preset's\n   * palette slots by luminance rank, so the churn reads as pixelation born\n   * from that image rather than the preset's stock colors. The preset\n   * palette (or the `colors` prop, when set) is restored automatically once\n   * the new image is fully visible.\n   *\n   * The churn always runs on a pixel-mosaic preset (`pixels-mechanic` /\n   * `pixels-organic`). When the active preset is `sweep-gradient`, the effect\n   * temporarily switches to a randomly-picked pixel preset for the churn and\n   * restores the authored preset once the new image is fully visible.\n   *\n   * Options:\n   * - `durationMs` — churn length before the next image auto-reveals.\n   *   @default 4000\n   * - `tintFromImage` — recolor the effect from the outgoing image.\n   *   @default true\n   * - `autoReveal` — set to `false` to churn indefinitely instead; end it\n   *   manually with `triggerReveal()` (next image dissolves in over the\n   *   churn) or `triggerHide()`.\n   *   @default true\n   *\n   * No-op unless an image is currently revealed (`reveal` or `visible`\n   * phase). Emits an `idle` cycle event when the churn starts.\n   */\n  triggerRegenerate: (opts?: {\n    durationMs?: number;\n    tintFromImage?: boolean;\n    autoReveal?: boolean;\n  }) => void;\n  /**\n   * Returns true while an image is showing on top of the shader (any of the\n   * `reveal`, `visible`, or `hide` phases). Useful for driving the label /\n   * icon of a Reveal/Hide toggle button.\n   */\n  isImageActive: () => boolean;\n}\n\nexport interface ImageGenerationProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n  /**\n   * Single host element to wrap. The wrapper sizes itself to the child; the\n   * shader paints inside the wrapper at full size, clipped to the child's\n   * border-radius.\n   */\n  children: ReactNode;\n\n  /**\n   * Selects which bundled preset to render.\n   *\n   * - `pixels-organic` - Chromium Flow rendered as a pixel mosaic.\n   * - `pixels-mechanic`- Nebula rendered as a pixel mosaic.\n   * - `sweep-gradient` - Gradient Sweep rendered as a pixel mosaic.\n   *\n   * @default 'pixels-organic'\n   */\n  preset?: ImageGenerationPreset;\n\n  /**\n   * Theme mode. `'auto'` resolves via `matchMedia('(prefers-color-scheme: dark)')`\n   * and switches live when the OS theme changes.\n   * @default 'auto'\n   */\n  theme?: ImageGenerationTheme;\n\n  /**\n   * Effect strength (0..2). In 0..1 it multiplies the shader canvas opacity\n   * (the shader keeps animating at full intensity; only the rendered alpha\n   * is scaled down) — exactly the historical behavior. Above 1 the canvas\n   * stays fully opaque and the shader's palette intensity is boosted\n   * instead, making the effect markedly more prominent.\n   * @default 1\n   */\n  strength?: number;\n\n  /**\n   * Animation speed multiplier on top of the preset's baked tempo. Scales\n   * the effect's whole clock — drift, churn and flicker together — so the\n   * character of the motion is preserved. `1` (default) is the preset\n   * tempo; `0.5` half speed, `2` double.\n   */\n  speed?: number;\n\n  /**\n   * Pixel-cell size multiplier for the mosaic effect. Scales the on-screen\n   * size of each pixel cell (and the matching reveal dissolve) without\n   * touching the preset:\n   *\n   *   - `1` (default) — the preset's authored cell size.\n   *   - `0.5` — cells at half size (finer grid, effect reads as \"zoomed out\").\n   *   - `2` — cells at double size (chunkier grid, \"zoomed in\").\n   *\n   * Implemented by dividing the shader grid's base cell count by this value,\n   * so the shader mosaic and the reveal pixel dissolve stay in lockstep. The\n   * grid always keeps a floor of 2 cells, so extreme values are safe.\n   * @default 1\n   */\n  pixelScale?: number;\n\n  /**\n   * Card background colour. Accepts any CSS colour string the browser can\n   * parse — hex (`#rgb` / `#rrggbb` / `#rrggbbaa`), `rgb()` / `rgba()`,\n   * `hsl()` / `hsla()`, named colours, modern `color(...)` syntax — and is\n   * applied two ways:\n   *\n   *   1. Verbatim as the wrapper element's CSS `background`, so the\n   *      original alpha is preserved visually.\n   *   2. Parsed to an opaque RGB triple for the shader's `u_cardBg`\n   *      uniform, which drives colour-proximity / contrast logic so any\n   *      shader colours that match the card background get faded out and\n   *      the effect stays visually balanced.\n   *\n   * Alpha is intentionally dropped when feeding the shader — the renderer\n   * has no source for what's behind a translucent card and can't composite\n   * correctly. If precise shader behaviour matters under a translucent\n   * surface, pass the opaque colour you want the shader to reason against.\n   *\n   * Useful for keeping colours in sync when the host card surface changes\n   * (e.g. dark-mode card swatch). When omitted, the preset's bundled\n   * `cardBg` (always opaque hex) is used.\n   */\n  cardBg?: string;\n\n  /**\n   * Optional palette override for the running effect (up to 7 CSS colors,\n   * one per shader palette slot). A slot with a value replaces the preset\n   * color verbatim; `null` / `undefined` slots keep the preset color. Pass\n   * `undefined` (or omit) to use the preset palette.\n   *\n   * Useful for re-tinting the effect from external data — e.g. colors\n   * sampled from the image being regenerated — while keeping the exact same\n   * animation and cell grid.\n   */\n  colors?: (string | null | undefined)[];\n\n  /**\n   * Image pool used by the reveal animation. Pass a single string to reveal\n   * the same image every cycle, or an array for random pick (never\n   * repeating the previous index).\n   * @default []\n   */\n  images?: string | string[];\n\n  /**\n   * When true, runs the auto-reveal scheduler:\n   *   shader (random delay) -> reveal -> hold -> hide -> repeat.\n   * @default false\n   */\n  autoReveal?: boolean;\n\n  /**\n   * Random shader-only delay range in seconds between reveals.\n   * @default [2, 4]\n   */\n  revealDelayRange?: [number, number];\n\n  /**\n   * One-time delay applied before the very first reveal (after `autoReveal`\n   * is enabled or `triggerReveal` runs the first cycle). Subsequent reveals\n   * follow `revealDelayRange`.\n   *\n   * - `number`: exact seconds.\n   * - `[min, max]`: seconds range, randomised once at cycle creation.\n   * - `undefined` (default): library picks a small jitter (0-1.5 s) so\n   *   multiple instances on the same page don't tick in lockstep.\n   *\n   * Useful for staggering hero cards (e.g. card #2 = `[1, 3]`, card #3 =\n   * `[1, 3]`) so they don't all reveal at once.\n   */\n  revealInitialDelay?: number | [number, number];\n\n  /**\n   * Time the image stays fully visible after the reveal animation completes,\n   * before the hide cross-fade kicks in.\n   *\n   * - `number` — fixed milliseconds.\n   * - `[min, max]` — random milliseconds per cycle, picked fresh each reveal.\n   *\n   * @default 2000\n   */\n  revealHoldMs?: number | [number, number];\n\n  /** ms cross-fade back to the shader. @default 300 */\n  revealFadeOutMs?: number;\n\n  /**\n   * Optional explicit corner radius (CSS px). When omitted, reads the\n   * computed `border-radius` of the wrapped child each resize.\n   */\n  borderRadius?: number;\n\n  /** Freezes the shader and the auto-reveal scheduler. @default false */\n  paused?: boolean;\n\n  /**\n   * Escape hatch: a replacement fragment shader (GLSL 1.00 syntax, as the\n   * bundled one — `gl_FragColor`, `texture2D`). Every uniform the engine\n   * uploads keeps its name; the shader is free to interpret them however it\n   * likes. The material is shared, so this applies page-wide while set.\n   */\n  fragmentShader?: string;\n\n  /** Phase event hook for the auto-reveal cycle. */\n  onCycle?: (event: ImageGenerationCycleEvent) => void;\n\n  /**\n   * Optional callback invoked just before each image pick that returns a list\n   * of src strings the cycle MUST avoid this round. Use this to coordinate\n   * multiple `<ImageGeneration>` instances that share an image pool so they\n   * never display the same image at the same time.\n   *\n   * The callback runs on every pick (including manual `triggerReveal()`) so\n   * it can read live state. If every candidate is excluded, the cycle falls\n   * back to a normal random pick so it never gets stuck.\n   */\n  excludeSrcs?: () => string[] | Set<string> | null | undefined;\n\n  /** Forwarded class name for the wrapper element. */\n  className?: string;\n\n  /** Forwarded inline styles for the wrapper element. */\n  style?: CSSProperties;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/effects/img-fx/LICENSE",
          "target": "@components/effects/img-fx/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Jakub Antalik\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/effects/img-fx/SOURCE.json",
          "target": "@components/effects/img-fx/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"img-fx\",\n  \"repository\": \"https://github.com/Jakubantalik/Libraries.dev\",\n  \"revision\": \"422180dd7a5ac646c85deedc65500c4a74339127\",\n  \"packageVersion\": \"0.5.1\",\n  \"license\": \"MIT\",\n  \"copiedPath\": \"upstream/\",\n  \"sourcePath\": \"packages/img-fx/src/\",\n  \"copiedFiles\": [\"src/**\"],\n  \"relationship\": \"Source-faithful copy of the pinned public React package. The top-level client facade re-exports its complete API.\"\n}\n"
        }
      ],
      "categories": [
        "Libraries.dev"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "liquid-gooey",
      "type": "registry:block",
      "title": "Liquid Gooey",
      "description": "liquid gooey",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/effects/liquid-gooey.tsx",
          "target": "@components/effects/liquid-gooey.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nexport * from \"./liquid-gooey/upstream/index\"\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/index.ts",
          "target": "@components/effects/liquid-gooey/upstream/index.ts",
          "type": "registry:component",
          "content": "import { GooeyRoot } from './Gooey'\nimport { LiquidItem } from './LiquidItem'\n\n/** The liquid group: renders the merged silhouette (goo + real shadows) behind\n *  your crisp content. Put `Liquid.Item`s inside. */\nexport const Liquid = Object.assign(GooeyRoot, { Item: LiquidItem })\n\nexport type { GooeyProps as LiquidProps } from './Gooey'\nexport type {\n  BendTuning,\n  LiquidEffect,\n  LiquidItemProps,\n  MorphTuning,\n  MoveTuning,\n} from './LiquidItem'\nexport { IMAGE_MELT_DEFAULTS } from './imageMelt'\nexport type { ImageMeltOptions } from './imageMelt'\n\n// ---- advanced escape hatch (raw engine options + defaults) ----\nexport type { DissolveOptions } from './GooeyItem'\nexport { EVOLVE_DEFAULTS, MOVE_DEFAULTS } from './observer'\nexport type { EvolveOptions, MoveOptions } from './observer'\nexport { easingFunction, presets } from './spring'\nexport type { SpringConfig, Transition, TransitionPreset } from './spring'\nexport type { CornerRadii } from './geometry'\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/Gooey.tsx",
          "target": "@components/effects/liquid-gooey/upstream/Gooey.tsx",
          "type": "registry:component",
          "content": "import {\n  forwardRef,\n  useCallback,\n  useEffect,\n  useId,\n  useMemo,\n  useRef,\n  useState,\n  type HTMLAttributes,\n  type Ref,\n} from 'react'\nimport { GooeyContext, type GooeyContextValue } from './context'\nimport { GooFilterPrimitives } from './filter'\nimport { ImageMeltLayer, createImageMeltRegistry } from './imageMelt'\nimport { useIsoLayoutEffect } from './hooks'\nimport { ObserveEngine } from './observer'\nimport { parseShadow } from './shadow'\n\nexport interface GooeyProps extends HTMLAttributes<HTMLDivElement> {\n  /** Goo blur sigma in px — how far apart pieces start bridging. Default 6. */\n  blur?: number\n  /** Alpha-contrast slope — how sharp the liquid edge is. Default 18. */\n  contrast?: number\n  /** Fill of the liquid surface. Any CSS color, `var()` welcome. Default '#fff'. */\n  fill?: string\n  /** `box-shadow` syntax; rendered on the MERGED silhouette. `inset` layers\n   *  paint inside the liquid edge (inner rings / top highlights). */\n  shadow?: string\n  /** Extra filter-region slack in px for blobs travelling outside the group box. Default 24. */\n  filterPadding?: number\n  /** Max px the liquid boundary undulates — the silhouette (and its shadows)\n   *  run through a gentle noise displacement, so edges read as fluid instead\n   *  of geometric. 0 (default) keeps the calm edge. */\n  waviness?: number\n  /** Noise frequency of the undulation; lower = longer, lazier waves. */\n  wavinessFreq?: number\n  /** Escape hatch: raw SVG filter primitives that REPLACE the goo chain\n   *  (`blur`, `contrast`, `waviness` and the SVG half of `shadow` are then\n   *  yours to reproduce). The input is `SourceGraphic`; the last primitive's\n   *  output is what paints. Inset and spread shadows normally read a\n   *  binarised `shape` result — keep that name if you keep them. */\n  filter?: string\n}\n\n/** Gooey group: renders the silhouette SVG layer (goo filter + shadow chain)\n *  behind its children. Children stay crisp; <Gooey.Item> mirrors each piece's\n *  geometry into the liquid layer.\n *\n *  Filters run on SVG content — not CSS url() filters on HTML — because that\n *  is the one variant WebKit renders correctly and promotes properly. */\nexport const GooeyRoot = forwardRef<HTMLDivElement, GooeyProps>(function Gooey(\n  {\n    blur = 6,\n    contrast = 18,\n    fill = '#fff',\n    shadow,\n    filterPadding = 24,\n    waviness = 0,\n    wavinessFreq = 0.018,\n    filter: customFilter,\n    className,\n    style,\n    children,\n    ...rest\n  },\n  fwd: Ref<HTMLDivElement>,\n) {\n  const groupRef = useRef<HTMLDivElement | null>(null)\n  const [portal, setPortal] = useState<SVGGElement | null>(null)\n  const [meltPortal, setMeltPortal] = useState<SVGGElement | null>(null)\n  const [size, setSize] = useState({ w: 0, h: 0 })\n\n  const setRefs = useCallback(\n    (node: HTMLDivElement | null) => {\n      groupRef.current = node\n      if (typeof fwd === 'function') fwd(node)\n      else if (fwd) (fwd as { current: HTMLDivElement | null }).current = node\n    },\n    [fwd],\n  )\n\n  const filterId = `gooey-${useId().replace(/[^a-zA-Z0-9_-]/g, '')}`\n  const shadows = useMemo(() => parseShadow(shadow), [shadow])\n\n  useIsoLayoutEffect(() => {\n    const el = groupRef.current\n    if (!el) return\n    const measure = () =>\n      setSize(prev =>\n        prev.w === el.offsetWidth && prev.h === el.offsetHeight\n          ? prev\n          : { w: el.offsetWidth, h: el.offsetHeight },\n      )\n    measure()\n    const ro = new ResizeObserver(measure)\n    ro.observe(el)\n    return () => ro.disconnect()\n  }, [])\n\n  const engine = useMemo(() => new ObserveEngine(() => groupRef.current), [])\n  const imageMelt = useMemo(() => createImageMeltRegistry(), [])\n  useEffect(() => () => engine.dispose(), [engine])\n  useEffect(() => {\n    engine.gooBlur = blur\n  }, [engine, blur])\n\n  const ctx = useMemo<GooeyContextValue>(\n    () => ({ portal, meltPortal, fill, getGroup: () => groupRef.current, engine, imageMelt }),\n    [portal, meltPortal, fill, engine, imageMelt],\n  )\n\n  // The filter raster is the whole performance story on WebKit, which runs\n  // SVG filters on the CPU at full device scale — measured at 9fps for a\n  // drag on an iPhone-class 3x screen. The heavy layers are the BLURRED\n  // outer shadows: a 42px-blur pass re-rasterises the entire padded region\n  // every animated frame. CSS drop-shadow() is mathematically the same\n  // operation (blur-radius = 2σ, exactly box-shadow's convention, exactly\n  // the stdDeviation = blur/2 the SVG pass used) — but a CSS filter list on\n  // the element runs on the COMPOSITOR, GPU-accelerated in both WebKit and\n  // Chromium. So the stack is split:\n  //   - blurred/offset outer shadows  -> drop-shadow() on the svg element\n  //   - spread rings and inset layers -> SVG passes (not expressible in\n  //     CSS, but they are morphology/offset ops with no big blurs — cheap)\n  //   - the goo chain itself          -> SVG, as before\n  // One spec'd difference: chained drop-shadows each see the previous\n  // result, so a later shadow also shadows an earlier one's pixels — at the\n  // 5-25% alphas shadows use, that cross-term is under 1% alpha, invisible.\n  // The filter pad also shrinks to what the REMAINING svg layers reach,\n  // which cuts the rasterised area again.\n  const svgShadows = shadows.filter(s => s.inset || s.spread !== 0)\n  const cssShadowFilter = shadows\n    .filter(s => !s.inset && s.spread === 0)\n    // box-shadow lists paint the FIRST layer on top; drop-shadow chains\n    // paint later filters behind earlier output, so document order already\n    // matches.\n    .map(s => `drop-shadow(${s.x}px ${s.y}px ${s.blur}px ${s.color})`)\n    .join(' ')\n  const shadowExtent = svgShadows.reduce(\n    (m, s) => Math.max(m, Math.max(Math.abs(s.x), Math.abs(s.y)) + s.blur * 1.5 + Math.max(0, s.spread)),\n    0,\n  )\n  const pad = Math.ceil(blur * 3 + shadowExtent + filterPadding)\n\n  return (\n    <div\n      {...rest}\n      ref={setRefs}\n      className={className}\n      style={{ position: 'relative', isolation: 'isolate', ...style }}\n    >\n      {/* zIndex -1 inside the isolated group: the liquid paints above the\n          group's own background but below every child, positioned or not. */}\n      <svg\n        aria-hidden=\"true\"\n        focusable=\"false\"\n        data-gooey-svg=\"\"\n        style={{\n          position: 'absolute',\n          inset: 0,\n          width: '100%',\n          height: '100%',\n          overflow: 'visible',\n          pointerEvents: 'none',\n          zIndex: -1,\n          // The GPU half of the shadow stack (see above).\n          filter: cssShadowFilter || undefined,\n          // Promote the filtered layer: WebKit otherwise repaints the goo a\n          // frame or two behind the plain-DOM content.\n          willChange: 'filter, transform',\n        }}\n      >\n        <defs>\n          {customFilter ? (\n            <filter\n              id={filterId}\n              filterUnits=\"userSpaceOnUse\"\n              x={-pad}\n              y={-pad}\n              width={size.w + pad * 2}\n              height={size.h + pad * 2}\n              colorInterpolationFilters=\"sRGB\"\n              dangerouslySetInnerHTML={{ __html: customFilter }}\n            />\n          ) : (\n            <filter\n              id={filterId}\n              filterUnits=\"userSpaceOnUse\"\n              x={-pad}\n              y={-pad}\n              width={size.w + pad * 2}\n              height={size.h + pad * 2}\n              colorInterpolationFilters=\"sRGB\"\n            >\n              <GooFilterPrimitives\n                blur={blur}\n                contrast={contrast}\n                shadows={svgShadows}\n                waviness={waviness}\n                wavinessFreq={wavinessFreq}\n              />\n            </filter>\n          )}\n        </defs>\n        <g id={`${filterId}-sil`} ref={setPortal} filter={`url(#${filterId})`} style={{ fill }} />\n      </svg>\n      {/* Melt overlay: warped-image copies render here, ABOVE the content\n          layer. SVG content so displacement/blur filters work in WebKit. */}\n      <svg\n        aria-hidden=\"true\"\n        focusable=\"false\"\n        data-gooey-overlay=\"\"\n        style={{\n          position: 'absolute',\n          inset: 0,\n          width: '100%',\n          height: '100%',\n          overflow: 'visible',\n          pointerEvents: 'none',\n          // Above the content layer by design, and high enough that an app's\n          // own stacking (e.g. a dragged item raised over its neighbours)\n          // can't slip in front and hide the melt. Scoped: the group is an\n          // isolated stacking context, so this can't escape it.\n          zIndex: 9999,\n        }}\n      >\n        <defs>\n          {/* The melt may only paint where LIQUID exists: the mask re-renders\n              the goo-filtered silhouette (same document, <use> across the two\n              svgs), so the warped copies are clipped to the merged surface —\n              without this the smear bled past the liquid edge onto the page\n              background. Luminance mask: the white silhouette passes, the\n              faint shadow layers (≤6% alpha) are negligible. */}\n          <mask\n            id={`${filterId}-meltmask`}\n            maskUnits=\"userSpaceOnUse\"\n            x={-pad}\n            y={-pad}\n            width={size.w + pad * 2}\n            height={size.h + pad * 2}\n          >\n            <use href={`#${filterId}-sil`} />\n          </mask>\n        </defs>\n        <g mask={`url(#${filterId}-meltmask)`}>\n          <g ref={setMeltPortal} />\n        </g>\n      </svg>\n      <GooeyContext.Provider value={ctx}>\n        {children}\n        <ImageMeltLayer registry={imageMelt} />\n      </GooeyContext.Provider>\n    </div>\n  )\n})\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/context.ts",
          "target": "@components/effects/liquid-gooey/upstream/context.ts",
          "type": "registry:component",
          "content": "import { createContext, useContext } from 'react'\nimport type { ImageMeltRegistry } from './imageMelt'\nimport type { ObserveEngine } from './observer'\n\nexport interface GooeyContextValue {\n  portal: SVGGElement | null\n  /** Portal target inside the melt-overlay svg (above the content layer). */\n  meltPortal: SVGGElement | null\n  /** The group's liquid fill — default colour of the intruding mix liquid. */\n  fill: string\n  getGroup: () => HTMLDivElement | null\n  engine: ObserveEngine\n  /** Pairwise image-melt items (effect=\"melt\") register here. */\n  imageMelt: ImageMeltRegistry\n}\n\nexport const GooeyContext = createContext<GooeyContextValue | null>(null)\n\nexport function useGooeyContext(): GooeyContextValue {\n  const ctx = useContext(GooeyContext)\n  if (!ctx) throw new Error('<Gooey.Item> must be rendered inside a <Gooey> group.')\n  return ctx\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/imageMelt.tsx",
          "target": "@components/effects/liquid-gooey/upstream/imageMelt.tsx",
          "type": "registry:component",
          "content": "import { useEffect, useId, useRef, useState } from 'react'\nimport { useGooeyContext } from './context'\n\n/** Image melt (the v2 \"melt lab\" effect, engine-free): two image-filled\n *  cards whose surfaces run molten where they touch — colours averaged\n *  through the goo, the crisp faces dissolving at the seam, and a marbling\n *  pass folding the two palettes into streaks in the touch area.\n *\n *  Architecture: the participating items' DOM stays interactive but paints\n *  nothing (opacity 0); an SVG layer in the group re-renders their imagery\n *  as pattern-filled rounded rects through the melt's filter stack,\n *  following the live rects each frame. Pairwise by design — the first two\n *  melt items in a group form the pair; the seam maths is two-body. */\n\nexport interface ImageMeltOptions {\n  /** Goo sigma: how far the bodies reach for each other AND how wide the\n   *  colour averaging runs. Default 7. */\n  blur?: number\n  /** Alpha-contrast slope of the liquid boundary. Default 40. */\n  contrast?: number\n  /** How far each crisp face dissolves back before the neighbour, as a\n   *  factor of the half-diagonal. Default 0.8. */\n  reach?: number\n  /** Softness of that dissolve (mask blur sigma). Default 17. */\n  fade?: number\n  /** Turbulence displacement of the molten layer, px. Default 0. */\n  warp?: number\n  /** 0..1 two-liquid marbling strength in the touch area. Default 1. */\n  mix?: number\n  /** Blur of the marble pass's source colours. Default 8. */\n  mixBlur?: number\n  /** How deep the marble zone reaches into each card. Default 1.9. */\n  gravity?: number\n  /** Wavelength control of the warp noise. Default 12. */\n  waviness?: number\n}\n\nexport const IMAGE_MELT_DEFAULTS: Required<ImageMeltOptions> = {\n  blur: 7,\n  contrast: 40,\n  reach: 0.8,\n  fade: 17,\n  warp: 0,\n  mix: 1,\n  mixBlur: 8,\n  gravity: 1.9,\n  waviness: 12,\n}\n\nexport interface ImageMeltEntry {\n  el: HTMLElement\n  src: string\n  opts: Required<ImageMeltOptions>\n}\n\n/** Registry lives on the Gooey group via context. */\nexport interface ImageMeltRegistry {\n  register(entry: ImageMeltEntry): () => void\n  subscribe(fn: () => void): () => void\n  entries(): ImageMeltEntry[]\n}\n\nexport function createImageMeltRegistry(): ImageMeltRegistry {\n  const set = new Set<ImageMeltEntry>()\n  const subs = new Set<() => void>()\n  const notify = () => subs.forEach(f => f())\n  return {\n    register(entry) {\n      set.add(entry)\n      notify()\n      return () => {\n        set.delete(entry)\n        notify()\n      }\n    },\n    subscribe(fn) {\n      subs.add(fn)\n      return () => subs.delete(fn)\n    },\n    entries: () => [...set],\n  }\n}\n\ninterface CardGeom {\n  x: number\n  y: number\n  w: number\n  h: number\n  r: number\n}\n\nfunction readGeom(group: HTMLElement, el: HTMLElement): CardGeom {\n  const gr = group.getBoundingClientRect()\n  const r = el.getBoundingClientRect()\n  const cs = getComputedStyle(el)\n  const rad = parseFloat(cs.borderTopLeftRadius) || 0\n  return {\n    x: r.left - gr.left,\n    y: r.top - gr.top,\n    w: r.width,\n    h: r.height,\n    r: Math.min(rad, r.width / 2, r.height / 2),\n  }\n}\n\nconst geomKey = (g: CardGeom) =>\n  `${Math.round(g.x * 2)},${Math.round(g.y * 2)},${Math.round(g.w)},${Math.round(g.h)},${Math.round(g.r)}`\n\n/** Exponential chase toward a target — the eased proximity that keeps the\n *  melt growing in over ~200ms instead of popping at the goo threshold. */\nfunction useEasedValue(target: number, rate = 14): number {\n  const [value, setValue] = useState(target)\n  const st = useRef({ value: target, target, raf: 0, last: 0 })\n  useEffect(() => {\n    const s = st.current\n    s.target = target\n    if (s.raf) return\n    s.last = performance.now()\n    const tick = (now: number) => {\n      const dt = Math.min(0.05, (now - s.last) / 1000)\n      s.last = now\n      const k = 1 - Math.exp(-rate * dt)\n      s.value += (s.target - s.value) * k\n      if (Math.abs(s.value - s.target) < 0.004) s.value = s.target\n      setValue(s.value)\n      s.raf = s.value === s.target ? 0 : requestAnimationFrame(tick)\n    }\n    s.raf = requestAnimationFrame(tick)\n    return () => {\n      if (s.raf) cancelAnimationFrame(s.raf)\n      s.raf = 0\n    }\n  }, [target, rate])\n  return value\n}\n\n/** The melt SVG for one pair, rendered into the group. Pure function of the\n *  two geometries + sources + tuning; ids namespaced per instance. */\nfunction MeltPair({\n  a,\n  b,\n  srcA,\n  srcB,\n  opts,\n  width,\n  height,\n}: {\n  a: CardGeom\n  b: CardGeom\n  srcA: string\n  srcB: string\n  opts: Required<ImageMeltOptions>\n  width: number\n  height: number\n}) {\n  const uid = `lgm-${useId().replace(/[^a-zA-Z0-9_-]/g, '')}`\n  const { blur: gooBlur, contrast, reach, fade, warp, mix, mixBlur, gravity, waviness } = opts\n\n  const ca = { x: a.x + a.w / 2, y: a.y + a.h / 2 }\n  const cb = { x: b.x + b.w / 2, y: b.y + b.h / 2 }\n  const gap = Math.max(\n    0,\n    Math.hypot(\n      Math.max(Math.abs(ca.x - cb.x) - (a.w + b.w) / 2, 0),\n      Math.max(Math.abs(ca.y - cb.y) - (a.h + b.h) / 2, 0),\n    ),\n  )\n  const near = Math.max(0, Math.min(1, 1 - gap / Math.max(8, gooBlur * 2.6)))\n  const proxTarget = near * near * (3 - 2 * near)\n  const prox = useEasedValue(proxTarget)\n\n  const intercept = Math.round((0.5 - contrast * (5 / 12)) * 100) / 100\n  const rA = (Math.hypot(a.w, a.h) / 2) * reach * prox\n  const rB = (Math.hypot(b.w, b.h) / 2) * reach * prox\n  const seam = { x: (ca.x + cb.x) / 2, y: (ca.y + cb.y) / 2 }\n  const dxc = cb.x - ca.x\n  const dyc = cb.y - ca.y\n  const dc = Math.max(1e-3, Math.hypot(dxc, dyc))\n  const tx = -dyc / dc\n  const ty = dxc / dc\n  const ovx = Math.max(0, (a.w + b.w) / 2 - Math.abs(dxc))\n  const ovy = Math.max(0, (a.h + b.h) / 2 - Math.abs(dyc))\n  const tanHalf = 0.5 * (ovx * Math.abs(tx) + ovy * Math.abs(ty)) * prox\n  const seamDeg = Math.round((Math.atan2(ty, tx) * 180) / Math.PI)\n  const mixAmt = Math.round(mix * prox * 100) / 100\n  const blurEff = Math.round((2 + (gooBlur - 2) * prox) * 10) / 10\n  const warpEff = Math.round(warp * prox * 10) / 10\n  const colorBlur = Math.round(blurEff * 2.5 * 10) / 10\n  const edgeSoft = Math.round((0.4 + (2 + gooBlur * 0.8) * prox) * 10) / 10\n\n  const gA = `translate(${a.x}, ${a.y})`\n  const gB = `translate(${b.x}, ${b.y})`\n\n  return (\n    <svg\n      aria-hidden=\"true\"\n      focusable=\"false\"\n      data-gooey-imagemelt=\"\"\n      width={width}\n      height={height}\n      viewBox={`0 0 ${width} ${height}`}\n      style={{\n        position: 'absolute',\n        inset: 0,\n        overflow: 'visible',\n        pointerEvents: 'none',\n      }}\n    >\n      <defs>\n        {/* No x/y: the rects referencing these patterns already sit inside a\n            translated <g>, and userSpaceOnUse resolves in that transformed\n            space — an origin here shifted the tile a second time, so the\n            image repeated instead of filling the card once. */}\n        <pattern id={`${uid}-pa`} patternUnits=\"userSpaceOnUse\" width={a.w} height={a.h}>\n          <image href={srcA} width={a.w} height={a.h} preserveAspectRatio=\"xMidYMid slice\" />\n        </pattern>\n        <pattern id={`${uid}-pb`} patternUnits=\"userSpaceOnUse\" width={b.w} height={b.h}>\n          <image href={srcB} width={b.w} height={b.h} preserveAspectRatio=\"xMidYMid slice\" />\n        </pattern>\n        {/* Goo on colour: blur mixes both images, contrast re-solidifies only\n            alpha; colours come from a wider blur clipped into that shape, so\n            internal edges average away while the boundary stays liquid. */}\n        <filter id={`${uid}-goo`} x=\"-15%\" y=\"-15%\" width=\"130%\" height=\"130%\" colorInterpolationFilters=\"sRGB\">\n          <feGaussianBlur in=\"SourceGraphic\" stdDeviation={blurEff} result=\"b\" />\n          <feColorMatrix\n            in=\"b\"\n            type=\"matrix\"\n            values={`1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 ${contrast} ${intercept}`}\n            result=\"goo\"\n          />\n          <feGaussianBlur in=\"SourceGraphic\" stdDeviation={colorBlur} result=\"bc\" />\n          <feComposite in=\"bc\" in2=\"goo\" operator=\"in\" result=\"mix\" />\n          <feTurbulence\n            type=\"fractalNoise\"\n            baseFrequency={(2 + waviness * 1.2) / 1000}\n            numOctaves=\"2\"\n            seed=\"4\"\n            result=\"wn\"\n          />\n          <feDisplacementMap in=\"mix\" in2=\"wn\" scale={warpEff} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"warped\" />\n          {/* Solidify by self-compositing (premultiplied-safe), then restore\n              the anti-aliased edge with a sub-pixel blur. */}\n          <feComposite in=\"warped\" in2=\"warped\" operator=\"over\" result=\"s1\" />\n          <feComposite in=\"s1\" in2=\"s1\" operator=\"over\" result=\"s2\" />\n          <feComposite in=\"s2\" in2=\"s2\" operator=\"over\" result=\"solid\" />\n          <feGaussianBlur in=\"solid\" stdDeviation=\"0.6\" />\n        </filter>\n        <filter id={`${uid}-soft`} x=\"-60%\" y=\"-60%\" width=\"220%\" height=\"220%\">\n          <feGaussianBlur stdDeviation={fade} />\n        </filter>\n        {/* Marbling: nested large-scale displacements fold the molten colours\n            into streaks, clipped to the goo silhouette. */}\n        {mixAmt > 0.01 && (\n          <filter id={`${uid}-marble`} x=\"-25%\" y=\"-25%\" width=\"150%\" height=\"150%\" colorInterpolationFilters=\"sRGB\">\n            <feGaussianBlur in=\"SourceGraphic\" stdDeviation={mixBlur} result=\"c\" />\n            <feTurbulence type=\"fractalNoise\" baseFrequency=\"0.011\" numOctaves=\"2\" seed=\"5\" result=\"n1\" />\n            <feDisplacementMap in=\"c\" in2=\"n1\" scale={mixAmt * 90} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"d1\" />\n            <feTurbulence type=\"fractalNoise\" baseFrequency=\"0.019\" numOctaves=\"2\" seed=\"11\" result=\"n2\" />\n            <feDisplacementMap in=\"d1\" in2=\"n2\" scale={mixAmt * 50} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"d2\" />\n            <feComposite in=\"d2\" in2=\"d2\" operator=\"over\" result=\"m1\" />\n            <feComposite in=\"m1\" in2=\"m1\" operator=\"over\" result=\"m2\" />\n            <feGaussianBlur in=\"m2\" stdDeviation=\"0.6\" result=\"marble\" />\n            <feGaussianBlur in=\"SourceGraphic\" stdDeviation={blurEff} result=\"mb\" />\n            <feColorMatrix\n              in=\"mb\"\n              type=\"matrix\"\n              values={`1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 ${contrast} ${intercept}`}\n              result=\"mg\"\n            />\n            <feTurbulence\n              type=\"fractalNoise\"\n              baseFrequency={(2 + waviness * 1.2) / 1000}\n              numOctaves=\"2\"\n              seed=\"4\"\n              result=\"mwn\"\n            />\n            <feDisplacementMap in=\"mg\" in2=\"mwn\" scale={warpEff} xChannelSelector=\"R\" yChannelSelector=\"G\" result=\"mshape\" />\n            <feComposite in=\"marble\" in2=\"mshape\" operator=\"in\" />\n          </filter>\n        )}\n        {mixAmt > 0.01 && (\n          <mask id={`${uid}-marblemask`} maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width={width} height={height}>\n            <g filter={`url(#${uid}-soft)`}>\n              <ellipse\n                cx={seam.x}\n                cy={seam.y}\n                rx={(rA + rB) / 2 + tanHalf}\n                ry={((rA + rB) / 2) * gravity}\n                transform={`rotate(${seamDeg}, ${seam.x}, ${seam.y})`}\n                fill=\"#fff\"\n              />\n            </g>\n          </mask>\n        )}\n        <filter id={`${uid}-edge`} x=\"-40%\" y=\"-40%\" width=\"180%\" height=\"180%\">\n          <feGaussianBlur stdDeviation={edgeSoft} />\n        </filter>\n        {/* Crisp faces: each is its plain card minus a blurred seam-spanning\n            erase ellipse — apart, a card is exactly a card. */}\n        <mask id={`${uid}-ma`} maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width={width} height={height}>\n          <g filter={`url(#${uid}-edge)`}>\n            <g transform={gA}>\n              <rect width={a.w} height={a.h} rx={a.r} fill=\"#fff\" />\n            </g>\n          </g>\n          <g filter={`url(#${uid}-soft)`}>\n            <ellipse\n              cx={seam.x}\n              cy={seam.y}\n              rx={rB + tanHalf}\n              ry={rB}\n              transform={`rotate(${seamDeg}, ${seam.x}, ${seam.y})`}\n              fill=\"#000\"\n            />\n          </g>\n        </mask>\n        <mask id={`${uid}-mb`} maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width={width} height={height}>\n          <g filter={`url(#${uid}-edge)`}>\n            <g transform={gB}>\n              <rect width={b.w} height={b.h} rx={b.r} fill=\"#fff\" />\n            </g>\n          </g>\n          <g filter={`url(#${uid}-soft)`}>\n            <ellipse\n              cx={seam.x}\n              cy={seam.y}\n              rx={rA + tanHalf}\n              ry={rA}\n              transform={`rotate(${seamDeg}, ${seam.x}, ${seam.y})`}\n              fill=\"#000\"\n            />\n          </g>\n        </mask>\n      </defs>\n\n      {/* MOLTEN layer */}\n      <g filter={`url(#${uid}-goo)`}>\n        <g transform={gA}><rect width={a.w} height={a.h} rx={a.r} fill={`url(#${uid}-pa)`} /></g>\n        <g transform={gB}><rect width={b.w} height={b.h} rx={b.r} fill={`url(#${uid}-pb)`} /></g>\n      </g>\n\n      {/* MARBLE layer */}\n      {mixAmt > 0.01 && (\n        <g mask={`url(#${uid}-marblemask)`}>\n          <g filter={`url(#${uid}-marble)`}>\n            <g transform={gA}><rect width={a.w} height={a.h} rx={a.r} fill={`url(#${uid}-pa)`} /></g>\n            <g transform={gB}><rect width={b.w} height={b.h} rx={b.r} fill={`url(#${uid}-pb)`} /></g>\n          </g>\n        </g>\n      )}\n\n      {/* CRISP layer */}\n      <g mask={`url(#${uid}-ma)`}>\n        <g transform={gA}><rect width={a.w} height={a.h} rx={a.r} fill={`url(#${uid}-pa)`} /></g>\n      </g>\n      <g mask={`url(#${uid}-mb)`}>\n        <g transform={gB}><rect width={b.w} height={b.h} rx={b.r} fill={`url(#${uid}-pb)`} /></g>\n      </g>\n    </svg>\n  )\n}\n\n/** Rendered by the Gooey group: watches the registered melt items and draws\n *  the pair. rAF-measured; re-renders only when a rect actually moves. */\nexport function ImageMeltLayer({ registry }: { registry: ImageMeltRegistry }) {\n  const { getGroup } = useGooeyContext()\n  const [, bump] = useState(0)\n  const [geoms, setGeoms] = useState<{ a: CardGeom; b: CardGeom } | null>(null)\n  const keyRef = useRef('')\n\n  useEffect(() => registry.subscribe(() => bump(v => v + 1)), [registry])\n\n  const pair = registry.entries().slice(0, 2)\n  const active = pair.length === 2\n\n  useEffect(() => {\n    if (!active) {\n      setGeoms(null)\n      keyRef.current = ''\n      return\n    }\n    let raf = 0\n    const tick = () => {\n      const group = getGroup()\n      if (group) {\n        const a = readGeom(group, pair[0].el)\n        const b = readGeom(group, pair[1].el)\n        const key = geomKey(a) + '|' + geomKey(b)\n        if (key !== keyRef.current) {\n          keyRef.current = key\n          setGeoms({ a, b })\n        }\n      }\n      raf = requestAnimationFrame(tick)\n    }\n    raf = requestAnimationFrame(tick)\n    return () => cancelAnimationFrame(raf)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [active, pair[0]?.el, pair[1]?.el, getGroup])\n\n  if (!active || !geoms) return null\n  const group = getGroup()\n  const w = group?.offsetWidth ?? 0\n  const h = group?.offsetHeight ?? 0\n  return (\n    <MeltPair\n      a={geoms.a}\n      b={geoms.b}\n      srcA={pair[0].src}\n      srcB={pair[1].src}\n      opts={pair[0].opts}\n      width={w}\n      height={h}\n    />\n  )\n}\n\n/** Host for one melting item: keeps the child interactive but invisible —\n *  the melt SVG is the painter. Auto-detects the image source from the\n *  first <img> descendant when `src` isn't given. */\nexport function ImageMeltItem({\n  src,\n  opts,\n  registry,\n  children,\n}: {\n  src?: string\n  opts: Required<ImageMeltOptions>\n  registry: ImageMeltRegistry\n  children: React.ReactNode\n}) {\n  const hostRef = useRef<HTMLSpanElement | null>(null)\n\n  useEffect(() => {\n    const host = hostRef.current\n    const target = host?.firstElementChild as HTMLElement | null\n    if (!target) return\n    const img = src ?? target.querySelector('img')?.src ?? (target as HTMLImageElement).src\n    if (!img) {\n      if (process.env.NODE_ENV !== 'production') {\n        console.warn('[liquid-gooey] effect=\"melt\" needs an image: pass melt={{ src }} or put an <img> inside the item.')\n      }\n      return\n    }\n    // The DOM element stays for layout + interaction; the SVG paints it.\n    const prevOpacity = target.style.opacity\n    target.style.opacity = '0'\n    const unregister = registry.register({ el: target, src: img, opts })\n    return () => {\n      target.style.opacity = prevOpacity\n      unregister()\n    }\n  }, [src, opts, registry])\n\n  return <span ref={hostRef} style={{ display: 'contents' }}>{children}</span>\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/observer.ts",
          "target": "@components/effects/liquid-gooey/upstream/observer.ts",
          "type": "registry:component",
          "content": "import { measureRadius } from './geometry'\n\n// Vite dev only: this module owns live singletons — the measurement loop and\n// the overlay DOM it built. React Refresh hot-swaps our importers while the\n// RUNNING engine keeps executing the old code, so an engine edit could leave\n// a page showing new controls wired to old behavior; that stale-engine state\n// repeatedly presented as \"the fix didn't work\". Any edit here is a full\n// reload. Dead code in production builds (import.meta.hot is undefined).\nconst viteHot = (\n  import.meta as { hot?: { accept(cb: () => void): void; invalidate(): void } }\n).hot\nif (viteHot) viteHot.accept(() => viteHot.invalidate())\n\n\nexport interface BlendConfig {\n  /** SVG group in the melt-overlay layer; the engine builds the warped-image\n   *  structure inside it (pattern-filled rounded rects run through a\n   *  turbulence → displacement → blur → saturation filter chain). Filters on\n   *  SVG content render correctly in every browser — CSS url() filters on\n   *  HTML are what WebKit breaks. */\n  host: SVGGElement\n  /** Melt blur radius in px. */\n  blur: number\n  /** Displacement strength of the liquid warp (feDisplacementMap scale). */\n  warp: number\n  /** Max px the melted imagery is pulled toward the contact. */\n  pull: number\n  /** Distance (px) at which melting starts; defaults from the group's goo blur. */\n  range?: number\n  /** Base radius (px) of the melt zone around the contact point. Defaults\n   *  from the group's goo blur — the mixing zone matches the bridge width\n   *  instead of swallowing the whole element. */\n  zone?: number\n  /** 0..1 — two-liquid mixing: the melted image is eroded into noise-shaped\n   *  tendrils so the neighbour's liquid (already behind it) shows through the\n   *  gaps. Never paints a shape — a painted disc reads as a visible circle. */\n  mix?: number\n  /** Px the melted material is drawn toward the NEIGHBOUR's centre at full\n   *  contact — the dissolve streams into the other body instead of\n   *  scattering symmetrically. Default 25. */\n  gravity?: number\n  /** 0..1 — how POINTY the gravity flow is. Each layer's mask is pushed\n   *  further along the flow and shrunk, so their union tapers to a tip\n   *  instead of stretching as an even blob. Default 0.65. */\n  taper?: number\n  /** Noise octaves — higher = finer, more detailed swirls. Default 2. */\n  detail?: number\n  /** Multiplier on the noise frequency: <1 = broad lazy swirls, >1 = fine\n   *  busy veins. Default 1. */\n  warpFreq?: number\n  /** Px/s the noise field drifts, so the liquid visibly churns while held\n   *  instead of sitting frozen. 0 = static. Default 26. */\n  flowSpeed?: number\n  /** 'fractalNoise' = soft billows (default), 'turbulence' = veinier,\n   *  more marbled liquid. */\n  warpStyle?: 'fractalNoise' | 'turbulence'\n  /** While false, the melt fades out over `releaseMs` regardless of\n   *  proximity — e.g. the moment a drag is released. Default true. */\n  active?: boolean\n  /** Structural release time when `active` goes false, ms. Default 240. */\n  releaseMs?: number\n  /** Ms the melt takes to EVAPORATE — its opacity fades to zero over this,\n   *  independently of `releaseMs`, so the dissolve can leave gradually\n   *  instead of blinking out. May exceed `releaseMs` (the melt then lives\n   *  until the fade finishes). Defaults to `releaseMs`. */\n  fadeMs?: number\n  /** 0..1 — overall dissolve intensity, independent of proximity: a master\n   *  ceiling on how far the melt can develop even at full contact. Scales\n   *  warp/blur/gravity/mix AND the hole depth together, so a weak strength\n   *  reads as a shallower liquid rather than an erased edge with no melt to\n   *  justify it. 1 = full strength (default). */\n  strength?: number\n  /** How deep this piece may sink into its neighbour before the melt is fully\n   *  gone, as a fraction of the smaller body (1 = completely engulfed).\n   *  Melting is a SURFACE event: it belongs to the moment two skins meet, and\n   *  once a piece is well inside the other there is no seam left to mix at —\n   *  it has simply joined. Without this the proximity gap pins to zero on\n   *  first overlap and the melt stays at full while the piece buries itself,\n   *  which reads as a smear that should have resolved. Default 0.8; raise\n   *  toward (or past) 1 to keep melting while deeply overlapped. */\n  sink?: number\n  /** What the liquid is MADE OF. 'liquid' (default): the group's fill — the\n   *  classic white/surface goo, imagery painted over it. 'image': the item's\n   *  blob is pattern-filled with its own imagery, so the goo neck between\n   *  two such items renders as a blur-blend of both images' local colours —\n   *  no surface material visible at the seam at all. */\n  surface?: 'liquid' | 'image'\n  /** Blur radius (px) of the seam-blend layer: the item's imagery painted\n   *  once more through a PLAIN heavy blur, masked to the contact zone, at\n   *  half opacity. Both sides of a pair paint one, so the seam shows the two\n   *  pictures' local colours literally averaged — a guaranteed-smooth wash\n   *  over any hard crossing edge, independent of warp and erosion. Defaults\n   *  to 1.6x `blur`; 0 disables the layer. */\n  seamBlur?: number\n}\n\nexport interface EvolveOptions {\n  /** Spring driving the liquid mass's centre. Default 320 / 17. */\n  massStiffness?: number\n  massDamping?: number\n  /** Spring driving width/height. Default 170 / 11.5. */\n  sizeStiffness?: number\n  sizeDamping?: number\n  /** Spring driving the corner radius. Default 900 / 60 — stiff and\n   *  overdamped, so the element's own border-radius transition timing shows\n   *  through instead of the spring imposing its own. Soften it to make the\n   *  corners lag the element. */\n  radiusStiffness?: number\n  radiusDamping?: number\n  /** Max content cross-blur during the morph, px. 0 disables. Default 7. */\n  contentBlur?: number\n  /** 0..1 — how strongly the blob rounds into a droplet while morphing. Default 1. */\n  roundness?: number\n  /** Corner-forming timeline: starts at the very beginning of the morph and\n   *  runs droplet-round → target radius over `cornerDuration` ms with\n   *  `cornerEase` (a cubic-bezier(...) string, 'ease-in-out' or 'linear'),\n   *  after `cornerDelay` ms. No motion gating — tweak duration/easing and it\n   *  behaves like a normal animation. Defaults 460 / 0 / smooth. */\n  cornerDuration?: number\n  cornerDelay?: number\n  cornerEase?: string\n  /** Ms the travel lead takes to ramp in — how EAGERLY the droplet commits to\n   *  the destination. 0 leads instantly; it never scales the reach.\n   *  Default 90. */\n  anticipation?: number\n  /** Px the mass centre leads ahead of the element — how FAR the droplet\n   *  travels toward the destination before it inflates. 0 disables.\n   *  Default 32. */\n  travel?: number\n}\n\nexport const EVOLVE_DEFAULTS: Required<EvolveOptions> = {\n  massStiffness: 320,\n  massDamping: 17,\n  sizeStiffness: 170,\n  sizeDamping: 11.5,\n  radiusStiffness: 900,\n  radiusDamping: 60,\n  contentBlur: 7,\n  roundness: 1,\n  cornerDuration: 460,\n  cornerDelay: 0,\n  cornerEase: 'cubic-bezier(0.3, 1.05, 0.4, 1)',\n  anticipation: 90,\n  travel: 32,\n}\n\nconst easeCache = new Map<string, (t: number) => number>()\n\n/** Evaluate a CSS timing function ('cubic-bezier(...)', 'ease-in-out',\n *  'linear') at progress t — lets the engine's corner timeline match the\n *  element's CSS transition exactly. */\nfunction easingFn(spec: string): (t: number) => number {\n  let fn = easeCache.get(spec)\n  if (fn) return fn\n  const m = /cubic-bezier\\(([^)]+)\\)/.exec(spec)\n  if (m) {\n    const [x1, y1, x2, y2] = m[1].split(',').map(Number)\n    fn = (t: number) => {\n      if (t <= 0) return 0\n      if (t >= 1) return 1\n      let lo = 0\n      let hi = 1\n      for (let i = 0; i < 24; i++) {\n        const mid = (lo + hi) / 2\n        const x = 3 * mid * (1 - mid) * (1 - mid) * x1 + 3 * mid * mid * (1 - mid) * x2 + mid ** 3\n        if (x < t) lo = mid\n        else hi = mid\n      }\n      const u = (lo + hi) / 2\n      return 3 * u * (1 - u) * (1 - u) * y1 + 3 * u * u * (1 - u) * y2 + u ** 3\n    }\n  } else if (spec === 'ease-in-out') {\n    fn = easingFn('cubic-bezier(0.42, 0, 0.58, 1)')\n  } else {\n    fn = (t: number) => Math.min(1, Math.max(0, t))\n  }\n  easeCache.set(spec, fn)\n  return fn\n}\n\nexport interface MoveOptions {\n  /** Spring pulling the liquid surface after the element. Lower stiffness /\n   *  damping = a laggier, more rubbery trail. Default 380 / 18. */\n  stiffness?: number\n  damping?: number\n  /** Max axial stretch at speed (0 = rigid). Default 0.18. */\n  stretch?: number\n  /** Trailing droplet size as a fraction of the body. 0 disables the tail.\n   *  Default 0.46. */\n  tail?: number\n  /** How FAR the tail extends behind the body — the reach of the tongue,\n   *  from hugging the trailing edge (0) to trailing a full extra\n   *  body-length (1). Size is `tail`'s job alone. Default 0.5. */\n  force?: number\n  /** Vertical body bow: vertical velocity arcs the top and bottom edges —\n   *  the middle leads into the motion, the ends lag, like a flexible bar\n   *  pulled through liquid. 0 disables. Default 0.3. */\n  bend?: number\n  /** Horizontal cap deformation: horizontal velocity reshapes the rounded\n   *  left/right sides — the leading cap blunts against the flow, the\n   *  trailing cap stretches out, like a soft body pushed through liquid.\n   *  0 disables. Default 0.3. */\n  bendX?: number\n}\n\nexport const MOVE_DEFAULTS: Required<MoveOptions> = {\n  stiffness: 380,\n  damping: 18,\n  stretch: 0.18,\n  tail: 0.46,\n  force: 0.5,\n  // Both bows are OPT-IN. As defaults they deformed every move item: the\n  // sliders' circular thumbs turned egg-shaped mid-drag (cap deformation)\n  // and sagged off the track's centreline (vertical bow) from nothing but\n  // spring wobble in the velocity.\n  bend: 0,\n  bendX: 0,\n}\n\nexport interface ItemDynamics {\n  /** Liquid surface springs behind size/shape changes and settles like jelly. */\n  evolve: boolean\n  /** Surface lags the moving element and stretches with velocity — liquid rubber. */\n  move: boolean\n  /** Resolved evolve tuning; falls back to EVOLVE_DEFAULTS. */\n  evolveOpts?: Required<EvolveOptions>\n  /** Resolved move tuning; falls back to MOVE_DEFAULTS. */\n  moveOpts?: Required<MoveOptions>\n}\n\nexport interface ObservedTarget {\n  target: HTMLElement\n  blob: SVGRectElement\n  radius?: number\n  /** Px to shrink the blob on every side relative to the element — lets an\n   *  opaque element (e.g. a round photo) fully cover its own liquid so white\n   *  only appears as the merge bridge. */\n  blobInset?: number\n  /** Px the blob swells back OUT (beyond blobInset) as the item nears a\n   *  neighbour — an opaque element visibly grows a liquid coat that necks\n   *  into the other surface, instead of merging invisibly behind itself. */\n  bridgeGrow?: number\n  blend?: BlendConfig\n  dynamics?: ItemDynamics\n}\n\ninterface Frame {\n  x: number\n  y: number\n  w: number\n  h: number\n}\n\ninterface MeltEntry {\n  el: HTMLImageElement\n  /** One rect per melt layer, all fed by the same image pattern. */\n  rects: SVGRectElement[]\n  pattern: SVGPatternElement\n  image: SVGImageElement\n  radiusPx: number\n  /** Geometry sampled during the frame's READ pass (group coordinates).\n   *  Measuring lazily inside the write pass meant every item's mask write\n   *  invalidated layout for the next item's read — one forced synchronous\n   *  layout per item per frame. */\n  measured: { x: number; y: number; w: number; h: number; ow: number; oh: number } | null\n  /** True once the pattern feeds a pre-downscaled copy (see downscaleHref). */\n  lowRes: boolean\n  /** Last geometry + mask written, so unchanged frames stay DOM-silent. */\n  lastGeom: string | null\n  lastHole: string | null\n}\n\ninterface MeltLayer {\n  /** Compact fingerprint of the last values written to this layer's filter\n   *  primitives — a matching frame skips every write, so WebKit does not\n   *  re-rasterize the layer at all. */\n  last?: string\n  /** The layer's <filter>; its region is resized per frame to the melt zone. */\n  filter: SVGElement\n  disp: SVGElement\n  blurEl: SVGElement\n  erode: SVGElement\n  /** The noise source — baseFrequency is re-aimed per frame so the field is\n   *  elongated ALONG the flow (melting drips), not isotropic swirl. */\n  turb: SVGElement\n  /** Scrolls the shared noise field so the liquid churns over time. */\n  noiseOffset: SVGElement\n  circle: SVGCircleElement\n  gl: SVGGElement\n  shift: SVGGElement\n}\n\n/** Two graded warp layers sharing one noise field: a wide, gentle ripple and\n *  a tight, strong core — the melt reads as one continuous liquid that gets\n *  progressively deeper toward the contact point. */\n/** Melt layers ordered outermost → innermost. Blur, warp and erosion ramp\n *  smoothly across them and each is masked to a progressively tighter radius,\n *  so the stack reads as a continuous gradient rather than discrete bands. */\ninterface MeltRefs {\n  layers: MeltLayer[]\n  entries: MeltEntry[]\n  /** The seam-blend layer: the item's imagery drawn once more through a\n   *  plain heavy blur, masked to the contact zone, at half opacity. Both\n   *  sides of a pair paint one, so the seam shows the two pictures' local\n   *  colours literally averaged — the guaranteed-smooth base the turbulence\n   *  layers then texture. Null when the item was built without it. */\n  seam: {\n    gl: SVGGElement\n    filter: SVGElement\n    blurEl: SVGElement\n    circle: SVGCircleElement\n    last?: string\n  } | null\n}\n\n/** How many stacked layers approximate the gradient. */\nconst MELT_LAYERS = 3\n\n/** Total length of the corner timeline (delay + duration). */\nfunction cornerTotalOf(eo: Required<EvolveOptions>): number {\n  return Math.max(0, eo.cornerDelay) + Math.max(1, eo.cornerDuration)\n}\n\n/** Clamp a CSS corner radius for use as an SVG rect `rx`.\n *\n *  SVG clamps `rx` to w/2 and `ry` (defaulted from rx) to h/2 INDEPENDENTLY,\n *  so a large radius on a wide short box — the `border-radius: 999px` pill\n *  idiom — degenerates into an ellipse. Clamping to min(w,h)/2 keeps it a\n *  true pill, matching how CSS renders the same value. */\nfunction pillRadius(r: number, w: number, h: number): number {\n  return Math.max(0, Math.min(r, Math.min(w, h) / 2))\n}\n\n/** Centre-based liquid body: the mass's centre leads, size follows, corner\n *  radius adapts last — the order real liquid reads as. */\ninterface Sim {\n  cx: number\n  cy: number\n  w: number\n  h: number\n  r: number\n  vcx: number\n  vcy: number\n  vw: number\n  vh: number\n  vr: number\n}\n\ninterface Item extends ObservedTarget {\n  baseW: number\n  baseH: number\n  radiusPx: number\n  last: Frame | null\n  frame: Frame | null\n  lastBlend: { cx: number; cy: number; s: number; d: number; pk: string } | null\n  melt: MeltRefs | null\n  sim: Sim | null\n  /** Peak-hold envelope of morph motion: rises instantly, decays smoothly —\n   *  keeps roundness/blur monotone through the springs' settle oscillations. */\n  motionEnv: number\n  /** Previous target centre + smoothed target velocity, for anticipation. */\n  tPrev: { cx: number; cy: number } | null\n  tvx: number\n  tvy: number\n  /** Ramp-in envelope for the travel lead, 0..1, timed by `anticipation`. */\n  lead01: number\n  /** Corner timeline: morph start time + target-size change tracking. */\n  cornerT0: number\n  lastTargetMoveT: number\n  lastTargetSize: { w: number; h: number } | null\n  /** Latch: a morph is in progress, so the corner timeline can't restart. */\n  morphActive: boolean\n  /** Rate-limited droplet-roundness value — glides, never steps. */\n  round01: number\n  /** Trailing droplet for move items: a laggier satellite the goo filter\n   *  strings into a teardrop tail while the element is in motion. */\n  tailEl: SVGCircleElement | null\n  /** Two intermediate droplets between body and main satellite — the taper\n   *  that keeps the tail reading as one organic tongue, not a lone circle. */\n  tailMidA: SVGCircleElement | null\n  tailMidB: SVGCircleElement | null\n  /** Wobble phase, advanced by distance travelled (not wall time), so the\n   *  mid-droplets weave slightly and the tail never looks die-cut. */\n  tailPhase: number\n  /** Smoothed body-bow displacements (px): Y arcs top/bottom edges,\n   *  X arcs left/right. */\n  bendCur: number\n  bendCurX: number\n  /** Path that replaces the rect while the body is bowed — a rect cannot\n   *  arc, so the bend renders as a real curved silhouette. */\n  bendPathEl: SVGPathElement | null\n  lastBendD: string | null\n  /** Last \"--lg-bend-x,--lg-bend-y\" write, to skip redundant style sets. */\n  lastBendVars: string | null\n  tailX: number\n  tailY: number\n  tailVx: number\n  tailVy: number\n  tailR: number\n  /** True while an evolve morph has a motion blur written onto the target. */\n  contentBlurred: boolean\n  /** Last values painted to the blob by the dynamics branch. Writes are\n   *  skipped when unchanged: the 300ms asleep-check calls writeBlob too, and\n   *  an unconditional setAttribute — even with an identical value — dirties\n   *  the SVG filter, which Safari answers by re-rasterizing the whole filter\n   *  region. A settled sim must be DOM-silent. */\n  lastPaint: { t: string; w: string; h: string; rx: string } | null\n  /** Last tail-circle write ('hidden' when parked at r=0), same reason. */\n  lastTail: string | null\n  /** Last effective blob inset written (bridgeGrow makes it proximity-driven). */\n  lastBi: number\n  /** Time-smoothed bridgeGrow inset; null until the first frame seeds it. */\n  biSmooth: number | null\n  /** Smoothed melt strength: fast attack, gradual release-time decay. */\n  meltFade: number\n  /** In-flight release: start strength + elapsed ms, so the fade completes in\n   *  exactly `releaseMs` instead of chasing zero forever. */\n  meltRel: { from: number; t: number } | null\n  /** Smoothed overlay opacity — carries the progressive release fade, and\n   *  keeps a re-approach mid-fade from popping back to full. */\n  meltOp: number\n  /** Accumulated noise-drift phase — makes the liquid churn. */\n  meltPhase: number\n  /** Previous frame position, to gate the churn on actual movement. */\n  meltPrev: { x: number; y: number } | null\n  /** Last contact geometry, so the fading tail keeps its position. */\n  meltGeom: { o: Frame } | null\n  /** performance.now() of the last melt layer/entry write pass — writes back\n   *  off to ~28fps when the frame clock degrades (see frameEma), because each\n   *  one re-rasterizes turbulence filters, which WebKit runs on the CPU. */\n  meltWroteAt: number\n  /** Dominant flow axis of the anisotropic noise ('x' = features elongated\n   *  horizontally), held with hysteresis — re-aiming exactly at |gux|==|guy|\n   *  flipped the whole texture 90° on every crossing of the diagonal while\n   *  dragging around the contact, a hard visible flicker. */\n  meltAxis: 'x' | 'y' | null\n  /** Last host opacity/transform written. */\n  meltHostLast: string | null\n  ro: ResizeObserver\n}\n\n/** Semi-implicit Euler spring step; returns [position, velocity]. */\nfunction springStep(\n  cur: number,\n  vel: number,\n  target: number,\n  k: number,\n  c: number,\n  dt: number,\n): [number, number] {\n  const a = k * (target - cur) - c * vel\n  const v = vel + a * dt\n  return [cur + v * dt, v]\n}\n\n/** Spring advance over a WALL-CLOCK dt, substepped at ≤1/60s so the\n *  integration stays stable no matter how long the frame gap was.\n *\n *  The loop used to clamp dt to 1/24 per FRAME instead: at Safari's worst\n *  (~1 paint per 2s under filter load) the simulation then advanced 42ms per\n *  2000ms of wall time — everything ran in ~50x slow motion, so timed melt\n *  releases visibly never finished (avatars stayed erased) and silhouettes\n *  trailed their elements by seconds. Time must follow the wall clock; only\n *  the integration STEP is capped. */\nfunction springSteps(\n  cur: number,\n  vel: number,\n  target: number,\n  k: number,\n  c: number,\n  dt: number,\n): [number, number] {\n  let n = Math.max(1, Math.ceil(dt * 60))\n  const h = dt / n\n  let p = cur\n  let v = vel\n  while (n-- > 0) {\n    const step = springStep(p, v, target, k, c, h)\n    p = step[0]\n    v = step[1]\n  }\n  return [p, v]\n}\n\n/** Quantize a value so near-identical frames produce IDENTICAL strings and\n *  the dirty-checks can skip the DOM write — WebKit re-rasterizes a filter's\n *  whole region on any primitive-attribute write, identical value or not. */\nfunction q(v: number, step: number): number {\n  return Math.round(v / step) * step\n}\n\nconst SVG_NS = 'http://www.w3.org/2000/svg'\nlet meltCounter = 0\n\nfunction smoothstep(t: number): number {\n  const c = Math.min(1, Math.max(0, t))\n  return c * c * (3 - 2 * c)\n}\n\nfunction svg<K extends keyof SVGElementTagNameMap>(\n  tag: K,\n  attrs: Record<string, string>,\n): SVGElementTagNameMap[K] {\n  const el = document.createElementNS(SVG_NS, tag)\n  for (const [k, v] of Object.entries(attrs)) el.setAttribute(k, v)\n  return el\n}\n\n/** Shared per-group measurement loop for observe-mode items: mirrors externally\n *  animated elements onto their blobs each frame, then sleeps entirely once\n *  nothing has moved for ~half a second. MutationObserver + transition /\n *  animation events + a slow safety tick wake it, so idle cost is zero.\n *\n *  Items opted into contact blur additionally get a liquid melt at the point\n *  where they touch a neighbour: their images are re-rendered as SVG shapes\n *  warped by a turbulence displacement field — edges bend and smear like two\n *  materials merging — while the originals' edges dissolve under them. */\n/** Pre-downscaled copy of an <img> for the melt patterns. The pattern draws\n *  its source at display size on EVERY filter-graph execution — megapixel\n *  photos inside a 40px avatar meant layers x entries full-resolution\n *  rescales per animated frame, a dominant slice of the melt's cost on\n *  WebKit's CPU rasterizer. The copy keeps 3x the display size (device\n *  pixels on a 3x phone plus warp-stretch headroom), so nothing visible is\n *  lost. Returns null when the image is not decodable yet, is already\n *  small, or would taint the canvas (cross-origin) — caller keeps the\n *  original then. */\nfunction downscaleHref(el: HTMLImageElement): string | null {\n  try {\n    if (!el.complete || !el.naturalWidth) return null\n    const dw = Math.max(2, Math.min(el.naturalWidth, Math.round((el.offsetWidth || 40) * 3)))\n    const dh = Math.max(2, Math.min(el.naturalHeight, Math.round((el.offsetHeight || 40) * 3)))\n    if (el.naturalWidth <= dw * 1.5) return null\n    const cv = document.createElement('canvas')\n    cv.width = dw\n    cv.height = dh\n    const c2 = cv.getContext('2d')\n    if (!c2) return null\n    // Mirror `preserveAspectRatio: slice`: cover-crop, centred.\n    const scale = Math.max(dw / el.naturalWidth, dh / el.naturalHeight)\n    const sw = dw / scale\n    const sh = dh / scale\n    c2.drawImage(el, (el.naturalWidth - sw) / 2, (el.naturalHeight - sh) / 2, sw, sh, 0, 0, dw, dh)\n    return cv.toDataURL()\n  } catch {\n    return null\n  }\n}\n\nexport class ObserveEngine {\n  /** Goo blur of the owning group; used to derive the default blend range. */\n  gooBlur = 6\n\n  private items = new Set<Item>()\n  private awake = false\n  private clean = 0\n  private raf = 0\n  private sourcesReady = false\n  private mo: MutationObserver | null = null\n  private interval: ReturnType<typeof setInterval> | null = null\n  private removeListeners: Array<() => void> = []\n\n  constructor(private getGroup: () => HTMLElement | null) {}\n\n  add(t: ObservedTarget): () => void {\n    const item: Item = {\n      ...t,\n      baseW: t.target.offsetWidth || 1,\n      baseH: t.target.offsetHeight || 1,\n      radiusPx: this.resolveRadius(t),\n      last: null,\n      frame: null,\n      lastBlend: null,\n      melt: null,\n      sim: null,\n      motionEnv: 0,\n      tPrev: null,\n      tvx: 0,\n      tvy: 0,\n      lead01: 0,\n      cornerT0: 0,\n      lastTargetMoveT: 0,\n      lastTargetSize: null,\n      morphActive: false,\n      round01: 0,\n      tailEl: null,\n      tailMidA: null,\n      tailMidB: null,\n      tailPhase: 0,\n      bendCur: 0,\n      bendCurX: 0,\n      bendPathEl: null,\n      lastBendD: null,\n      lastBendVars: null,\n      tailX: 0,\n      tailY: 0,\n      tailVx: 0,\n      tailVy: 0,\n      tailR: 0,\n      contentBlurred: false,\n      lastPaint: null,\n      lastTail: null,\n      lastBi: t.blobInset ?? 0,\n      biSmooth: null,\n      meltFade: 0,\n      meltRel: null,\n      meltOp: 1,\n      meltPhase: 0,\n      meltPrev: null,\n      meltGeom: null,\n      meltWroteAt: 0,\n      meltAxis: null,\n      meltHostLast: null,\n      ro: new ResizeObserver(() => {\n        item.baseW = t.target.offsetWidth || 1\n        item.baseH = t.target.offsetHeight || 1\n        item.radiusPx = this.resolveRadius(t)\n        this.syncMelt(item)\n        this.wake()\n      }),\n    }\n    item.ro.observe(t.target)\n    this.items.add(item)\n    this.refreshMelt(item)\n    if (t.dynamics?.move) {\n      // Painted before (below) the main blob; the goo merge does the rest.\n      // Three circles: main satellite plus two tapering mid-droplets, so the\n      // merged silhouette is a tongue that thins organically, not one disc.\n      const tail = svg('circle', { cx: '0', cy: '0', r: '0' })\n      const midA = svg('circle', { cx: '0', cy: '0', r: '0' })\n      const midB = svg('circle', { cx: '0', cy: '0', r: '0' })\n      t.blob.parentNode?.insertBefore(tail, t.blob)\n      t.blob.parentNode?.insertBefore(midA, t.blob)\n      t.blob.parentNode?.insertBefore(midB, t.blob)\n      item.tailEl = tail\n      item.tailMidA = midA\n      item.tailMidB = midB\n      const bendPath = svg('path', { d: '' }) as SVGPathElement\n      t.blob.parentNode?.insertBefore(bendPath, t.blob)\n      item.bendPathEl = bendPath\n    }\n    this.ensureSources()\n    this.measureAll()\n    this.wake()\n    return () => {\n      item.ro.disconnect()\n      this.items.delete(item)\n      this.clearBlend(item)\n      if (item.contentBlurred) item.target.style.removeProperty('filter')\n      item.tailEl?.remove()\n      item.tailMidA?.remove()\n      item.tailMidB?.remove()\n      item.bendPathEl?.remove()\n    }\n  }\n\n  wake = (): void => {\n    this.clean = 0\n    if (this.awake || this.items.size === 0) return\n    this.awake = true\n    this.raf = requestAnimationFrame(this.loop)\n  }\n\n  dispose(): void {\n    cancelAnimationFrame(this.raf)\n    this.mo?.disconnect()\n    this.removeListeners.forEach(off => off())\n    this.removeListeners = []\n    if (this.interval) clearInterval(this.interval)\n    this.items.forEach(i => i.ro.disconnect())\n    this.items.clear()\n    this.awake = false\n    this.sourcesReady = false\n  }\n\n  private resolveRadius(t: ObservedTarget): number {\n    if (t.radius != null) return t.radius\n    return measureRadius(t.target, t.target.offsetWidth, t.target.offsetHeight)[0]\n  }\n\n  /** (Re)build the warped-image SVG structure for a melt item. Two graded\n   *  warp layers share ONE noise field (same frequency + seed): a wide gentle\n   *  ripple and a tight strong core. Same field, different displacement\n   *  scales → the layers align and read as a single liquid getting deeper\n   *  toward the contact. The noise frequency is derived from the melt zone,\n   *  so several ripple wavelengths fit across it — a fixed low frequency\n   *  displaces the whole zone as one chunk, which reads as a shifted ghost\n   *  copy instead of liquid. */\n  /** Resize response. The melt DOM only needs REBUILDING when the set of\n   *  images changes; a resize alone just makes the cached corner radii stale.\n   *\n   *  Rebuilding on every resize tore down and recreated three turbulence\n   *  filters plus a pattern + <image> per photo, and WebKit re-decodes and\n   *  re-rasterises all of it synchronously. The pill resizes the moment the\n   *  hover gap opens — i.e. exactly as the flight begins — so that landed as\n   *  a ~120ms main-thread stall. CSS transitions keep running on the\n   *  compositor through a stall, but the silhouette is written from this\n   *  loop, so the liquid froze while the content sailed on: the timing\n   *  mismatch, and it never showed in Chromium because the rebuild is cheap\n   *  enough there to fit in a frame. */\n  private syncMelt(item: Item): void {\n    if (!item.blend) return\n    const melt = item.melt\n    const t = item.target\n    const imgs =\n      t instanceof HTMLImageElement\n        ? [t]\n        : (Array.from(t.querySelectorAll('img')) as HTMLImageElement[])\n    const same =\n      !!melt &&\n      melt.entries.length === imgs.length &&\n      melt.entries.every((e, i) => e.el === imgs[i])\n    if (!same) {\n      this.refreshMelt(item)\n      return\n    }\n    for (const entry of melt.entries) {\n      entry.radiusPx = measureRadius(entry.el, entry.el.offsetWidth, entry.el.offsetHeight)[0]\n      // Geometry is re-derived from the new radius on the next write.\n      entry.lastGeom = null\n    }\n  }\n\n  private refreshMelt(item: Item): void {\n    const blend = item.blend\n    if (!blend) return\n    const host = blend.host\n    while (host.firstChild) host.removeChild(host.firstChild)\n    const t = item.target\n    const imgs =\n      t instanceof HTMLImageElement\n        ? [t]\n        : (Array.from(t.querySelectorAll('img')) as HTMLImageElement[])\n    const uid = `gooey-melt-${++meltCounter}`\n    const seed = String((meltCounter * 7) % 100)\n    const zone = blend.zone ?? this.gooBlur * 2.2 + 4\n    const freqK = Math.max(0.2, blend.warpFreq ?? 1)\n    const bf = Math.min(0.3, Math.max(0.01, freqK / (zone * 1.1))).toFixed(4)\n    const octaves = String(Math.max(1, Math.round(blend.detail ?? 2)))\n    const noiseType = blend.warpStyle ?? 'fractalNoise'\n\n    const defs = svg('defs', {})\n    const gradient = svg('radialGradient', { id: `${uid}-g` })\n    gradient.append(\n      // Long, smooth falloff: the melt reads as a gradient from intact rim\n      // to fully mixed core, not as a disc with a soft edge.\n      // Core-to-mid FULLY opaque, rim tight. Two failure modes shaped this:\n      // a translucent middle let the white silhouette neck glow through the\n      // copy right at the seam (a bright ring/dot wherever the goo bridges\n      // dark imagery — the neck sits between the photos' rounded corners, so\n      // nothing else can cover it), and a half-opaque rim let the copy's\n      // blurred imagery drift far past the neck, reading as fog over a\n      // contrasting neighbour. Opaque to 55%, then a fast falloff.\n      svg('stop', { offset: '0%', 'stop-color': '#fff' }),\n      svg('stop', { offset: '55%', 'stop-color': '#fff' }),\n      svg('stop', { offset: '78%', 'stop-color': '#fff', 'stop-opacity': '0.55' }),\n      svg('stop', { offset: '100%', 'stop-color': '#fff', 'stop-opacity': '0' }),\n    )\n    defs.append(gradient)\n\n    const mkLayer = (suffix: string) => {\n      // Region in USER SPACE, resized per frame to the melt zone (see the\n      // write pass). As a %-of-bbox region it covered the whole group — and\n      // feTurbulence is generated on the CPU across the entire region, so the\n      // cost scaled with the group, not with the small area the mask actually\n      // reveals. That was the ~110ms main-thread stall at the start of a\n      // flight: the content kept moving on the compositor while this loop —\n      // which writes the silhouette — was blocked, so the liquid visibly fell\n      // behind the UI.\n      const filter = svg('filter', {\n        id: `${uid}-f${suffix}`,\n        filterUnits: 'userSpaceOnUse',\n        x: '0',\n        y: '0',\n        width: '0',\n        height: '0',\n        'color-interpolation-filters': 'sRGB',\n      })\n      const turb = svg('feTurbulence', {\n        type: noiseType,\n        baseFrequency: bf,\n        numOctaves: octaves,\n        seed,\n        result: 'noise0',\n      })\n      filter.append(turb)\n      // Scrolling the noise field (rather than re-seeding, which jumps) makes\n      // the liquid churn continuously while the surfaces are held together.\n      const noiseOffset = svg('feOffset', { in: 'noise0', dx: '0', dy: '0', result: 'noise' })\n      const disp = svg('feDisplacementMap', {\n        in: 'SourceGraphic',\n        in2: 'noise',\n        scale: '0',\n        xChannelSelector: 'R',\n        yChannelSelector: 'G',\n        result: 'disp',\n      })\n      filter.append(noiseOffset)\n      const blurEl = svg('feGaussianBlur', { in: 'disp', stdDeviation: '0', result: 'soft' })\n      // Melted material reads as concentrated pigment, not fog.\n      const sat = svg('feColorMatrix', {\n        in: 'soft',\n        type: 'saturate',\n        values: '1.2',\n        result: 'col',\n      })\n      // Two-liquid mixing WITHOUT painting anything: threshold the same noise\n      // into an alpha map and clip the melted copy with it, so the image\n      // breaks into tendrils and the liquid already behind shows through the\n      // gaps. Identity by default (alpha = 1 everywhere).\n      const erode = svg('feColorMatrix', {\n        in: 'noise',\n        type: 'matrix',\n        values: '0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 1',\n        result: 'erode',\n      })\n      const clip = svg('feComposite', { in: 'col', in2: 'erode', operator: 'in' })\n      filter.append(disp, blurEl, sat, erode, clip)\n      const mask = svg('mask', {\n        id: `${uid}-m${suffix}`,\n        maskUnits: 'userSpaceOnUse',\n        x: '-10000',\n        y: '-10000',\n        width: '20000',\n        height: '20000',\n      })\n      const circle = svg('circle', { cx: '0', cy: '0', r: '0', fill: `url(#${uid}-g)` })\n      mask.append(circle)\n      defs.append(filter, mask)\n      // `filter` and `mask` MUST live on separate elements. SVG orders them\n      // filter → mask, so masking a filtered layer should clip the blur to\n      // the contact zone; with both on ONE <g>, WebKit effectively masks\n      // first and then blurs, so the melt's blurred copy bleeds far outside\n      // its zone and paints a washed-out blob over whatever is next to it —\n      // the neighbouring avatar \"disappearing\" in Safari while Chromium (which\n      // orders them per spec) renders the identical values correctly.\n      // Outer <g> owns the mask + opacity, inner <g> owns the filter, so the\n      // order is unambiguous in every engine.\n      const gl = svg('g', {})\n      gl.setAttribute('mask', `url(#${uid}-m${suffix})`)\n      gl.setAttribute('opacity', '0')\n      const filtered = svg('g', {})\n      filtered.setAttribute('filter', `url(#${uid}-f${suffix})`)\n      const shift = svg('g', {})\n      filtered.append(shift)\n      gl.append(filtered)\n      return { filter, disp, blurEl, erode, turb, noiseOffset, circle, gl, shift }\n    }\n    // Outermost first so inner (stronger) layers paint on top.\n    const layers = Array.from({ length: MELT_LAYERS }, (_, i) => mkLayer(`l${i}`))\n    host.append(defs, ...layers.map(l => l.gl))\n\n    // Seam-blend layer, UNDER the turbulence layers: the imagery through a\n    // plain heavy blur, masked to the contact zone, at half opacity. Blur is\n    // local colour-averaging, and with both sides of a pair painting one,\n    // the seam renders the two pictures' tones literally averaged — the\n    // guaranteed-smooth base the turbulence layers then texture. Plain blur\n    // only: no turbulence to re-rasterize, so it is cheap per frame.\n    let seam: NonNullable<MeltRefs['seam']> | null = null\n    if ((blend.seamBlur ?? 1) > 0) {\n      const filter = svg('filter', {\n        id: `${uid}-fs`,\n        filterUnits: 'userSpaceOnUse',\n        x: '0',\n        y: '0',\n        width: '0',\n        height: '0',\n        'color-interpolation-filters': 'sRGB',\n      })\n      const blurEl = svg('feGaussianBlur', { in: 'SourceGraphic', stdDeviation: '0' })\n      filter.append(blurEl)\n      const mask = svg('mask', {\n        id: `${uid}-ms`,\n        maskUnits: 'userSpaceOnUse',\n        x: '-10000',\n        y: '-10000',\n        width: '20000',\n        height: '20000',\n      })\n      const circle = svg('circle', { cx: '0', cy: '0', r: '0', fill: `url(#${uid}-g)` })\n      mask.append(circle)\n      defs.append(filter, mask)\n      const gl = svg('g', {})\n      gl.setAttribute('mask', `url(#${uid}-ms)`)\n      gl.setAttribute('opacity', '0')\n      const filtered = svg('g', {})\n      filtered.setAttribute('filter', `url(#${uid}-fs)`)\n      gl.append(filtered)\n      // Under the turbulence layers: base wash first, texture on top.\n      host.insertBefore(gl, defs.nextSibling)\n      seam = { gl, filter, blurEl, circle: circle as SVGCircleElement }\n    }\n\n    const entries: MeltEntry[] = imgs.map((el, i) => {\n      const pattern = svg('pattern', {\n        id: `${uid}-p${i}`,\n        patternUnits: 'userSpaceOnUse',\n        x: '0',\n        y: '0',\n        width: '1',\n        height: '1',\n      })\n      const image = svg('image', { width: '1', height: '1', preserveAspectRatio: 'xMidYMid slice' })\n      image.setAttribute('href', el.currentSrc || el.src)\n      pattern.append(image)\n      defs.append(pattern)\n      const rects = layers.map(l => {\n        const rect = svg('rect', { x: '0', y: '0', width: '0', height: '0', fill: `url(#${uid}-p${i})` })\n        l.shift.append(rect)\n        return rect\n      })\n      // The seam rect joins entry.rects, so the per-frame geometry writer\n      // positions it exactly like the turbulence layers' rects.\n      if (seam) {\n        const rect = svg('rect', { x: '0', y: '0', width: '0', height: '0', fill: `url(#${uid}-p${i})` })\n        seam.gl.firstElementChild!.append(rect)\n        rects.push(rect)\n      }\n      const radiusPx = measureRadius(el, el.offsetWidth, el.offsetHeight)[0]\n      return {\n        el,\n        rects,\n        pattern,\n        image,\n        radiusPx,\n        lowRes: false,\n        measured: null,\n        lastGeom: null,\n        lastHole: null,\n      }\n    })\n\n    host.setAttribute('opacity', '0')\n    item.melt = { layers, entries, seam }\n\n    // surface: 'image' — the LIQUID ITSELF is made of the image, not of the\n    // group fill. The blob is pattern-filled with the item's own imagery\n    // (objectBoundingBox, so the pattern rides the blob with zero per-frame\n    // bookkeeping), and the goo filter's blur then mixes both bodies' colours\n    // wherever their blobs merge: the neck becomes a gradient of the two\n    // images' local tones — colour averaging by the same blur that builds\n    // the neck — instead of a strip of bare surface material.\n    if (blend.surface === 'image' && imgs[0]) {\n      const bp = svg('pattern', {\n        id: `${uid}-bp`,\n        patternUnits: 'objectBoundingBox',\n        patternContentUnits: 'objectBoundingBox',\n        width: '1',\n        height: '1',\n      })\n      const bpImage = svg('image', {\n        width: '1',\n        height: '1',\n        preserveAspectRatio: 'xMidYMid slice',\n      })\n      bpImage.setAttribute('href', imgs[0].currentSrc || imgs[0].src)\n      bp.append(bpImage)\n      defs.append(bp)\n      item.blob.setAttribute('fill', `url(#${uid}-bp)`)\n    } else {\n      // Back to inheriting the group fill if a rebuild dropped the mode.\n      item.blob.removeAttribute('fill')\n    }\n  }\n\n  /** Remove all melt traces: hide the warped overlay, restore image masks. */\n  private clearBlend(item: Item): void {\n    item.blend?.host.setAttribute('opacity', '0')\n    // The DOM no longer matches the caches — drop them all, or the next melt\n    // would skip the writes that re-apply the state.\n    item.meltHostLast = null\n    item.meltWroteAt = 0\n    item.meltAxis = null\n    for (const layer of item.melt?.layers ?? []) layer.last = undefined\n    if (item.melt?.seam) {\n      item.melt.seam.last = undefined\n      item.melt.seam.gl.setAttribute('opacity', '0')\n    }\n    for (const entry of item.melt?.entries ?? []) {\n      entry.el.style.removeProperty('mask-image')\n      entry.el.style.removeProperty('-webkit-mask-image')\n      entry.el.style.removeProperty('mask-composite')\n      entry.el.style.removeProperty('-webkit-mask-composite')\n      entry.lastHole = null\n      entry.lastGeom = null\n    }\n  }\n\n  private lastNow = 0\n\n  /** EMA of the raw frame interval (ms) — the melt write pass consults it to\n   *  pick its cadence: every frame while the clock is healthy, backed off to\n   *  ~28fps when frames are dropping (WebKit under CPU-raster load is exactly\n   *  the case that degrades the clock). Seeded at 60Hz-healthy. */\n  private frameEma = 17\n\n  private loop = (now: number): void => {\n    if (this.items.size === 0) {\n      this.awake = false\n      this.lastNow = 0\n      return\n    }\n    // WALL-CLOCK dt (capped only against tab-switch gaps): timed fades and\n    // smoothing must complete in real time even when paints are slow —\n    // springs handle large dt via substepping (see springSteps).\n    const dt = this.lastNow ? Math.min(0.25, Math.max(1 / 240, (now - this.lastNow) / 1000)) : 1 / 60\n    if (this.lastNow) {\n      // Spikes clamped so one GC hitch doesn't flip the cadence for long.\n      this.frameEma += (Math.min(now - this.lastNow, 80) - this.frameEma) * 0.12\n    }\n    this.lastNow = now\n    if (this.measureAll(dt)) this.clean = 0\n    else this.clean++\n    if (this.clean > 30) {\n      this.awake = false\n      this.lastNow = 0\n      return\n    }\n    this.raf = requestAnimationFrame(this.loop)\n  }\n\n  private measureAll(dt = 1 / 60): boolean {\n    const group = this.getGroup()\n    if (!group || this.items.size === 0) return false\n    const g = group.getBoundingClientRect()\n    let changed = false\n    // ONE read pass, before any write. bridgeGrow proximity needs every\n    // neighbour's frame before any blob is written — and the melt entries must\n    // be measured here too: reading them lazily inside writeBlend meant each\n    // item's mask-image write invalidated layout for the next item's read, so\n    // a 4-item group forced four synchronous layouts every frame. Safari pays\n    // for those far more than Chromium does, which is most of why the same\n    // component ran smooth in one and stuttered in the other.\n    for (const item of this.items) {\n      const r = item.target.getBoundingClientRect()\n      item.frame = { x: r.left - g.left, y: r.top - g.top, w: r.width, h: r.height }\n    }\n    for (const item of this.items) {\n      if (!item.blend || !item.melt) continue\n      for (const entry of item.melt.entries) {\n        const ir = entry.el.getBoundingClientRect()\n        entry.measured = {\n          x: ir.left - g.left,\n          y: ir.top - g.top,\n          w: ir.width,\n          h: ir.height,\n          ow: entry.el.offsetWidth,\n          oh: entry.el.offsetHeight,\n        }\n      }\n    }\n    for (const item of this.items) {\n      if (this.writeBlob(item, dt)) changed = true\n    }\n    for (const item of this.items) {\n      if (item.blend && this.writeBlend(item, dt)) changed = true\n    }\n    return changed\n  }\n\n  /** Effective blob inset: bridgeGrow pulls it toward negative (a visible\n   *  liquid coat) as the nearest neighbour approaches.\n   *\n   *  Smoothed on a time constant rather than tracking proximity instantly.\n   *  The raw value is a function of the dragged neighbour's position, so it\n   *  moves as fast as the pointer does and lands on a different value every\n   *  frame; the blob grows symmetrically from it, so that per-frame step is\n   *  visible on the silhouette's far edge as a size flicker. It stayed small\n   *  enough to read as smooth at 60fps, but a frame-rate drop multiplies the\n   *  per-frame delta — which is why the pill's left edge flashed in Safari\n   *  and not in Chromium. dt-based smoothing makes the growth rate identical\n   *  at any frame rate. */\n  private effectiveInset(item: Item, dt: number): number {\n    let bi = item.blobInset ?? 0\n    const grow = item.bridgeGrow ?? 0\n    if (grow > 0 && item.frame) {\n      const f = item.frame\n      const range = Math.max(14, this.gooBlur * 3)\n      let best = Infinity\n      for (const other of this.items) {\n        if (other === item || !other.frame) continue\n        const o = other.frame\n        const dx = Math.max(o.x - (f.x + f.w), f.x - (o.x + o.w), 0)\n        const dy = Math.max(o.y - (f.y + f.h), f.y - (o.y + o.h), 0)\n        const gap = Math.hypot(dx, dy)\n        if (gap < best) best = gap\n      }\n      if (best < range) bi -= grow * smoothstep(1 - best / range)\n    }\n    if (grow <= 0) {\n      item.biSmooth = bi\n      return bi\n    }\n    if (item.biSmooth === null) item.biSmooth = bi\n    else item.biSmooth += (bi - item.biSmooth) * Math.min(1, dt * 18)\n    return item.biSmooth\n  }\n\n  private writeBlob(item: Item, dt: number): boolean {\n    const f = item.frame!\n    const dyn = item.dynamics\n    if (!dyn || (!dyn.evolve && !dyn.move)) {\n      const bi = this.effectiveInset(item, dt)\n      const last = item.last\n      const frameChanged =\n        !last ||\n        Math.abs(last.x - f.x) >= 0.05 ||\n        Math.abs(last.y - f.y) >= 0.05 ||\n        Math.abs(last.w - f.w) >= 0.05 ||\n        Math.abs(last.h - f.h) >= 0.05\n      const biChanged = Math.abs(bi - item.lastBi) >= 0.05\n      if (!frameChanged && !biChanged) return false\n      item.blob.style.transform = `translate(${f.x + bi}px, ${f.y + bi}px)`\n      if (frameChanged || biChanged) {\n        const bw = Math.max(0, f.w - bi * 2)\n        const bh = Math.max(0, f.h - bi * 2)\n        item.blob.setAttribute('width', String(bw))\n        item.blob.setAttribute('height', String(bh))\n        // CSS border-radius doesn't scale with transforms, but the rendered\n        // corner does — track it through the rect/layout-width ratio.\n        const scale = item.baseW > 0 ? f.w / item.baseW : 1\n        item.blob.setAttribute('rx', String(pillRadius(item.radiusPx * scale - bi, bw, bh)))\n      }\n      // This branch bypasses the dynamics paint cache — drop it so a later\n      // dynamics frame can't mistake the DOM for already matching.\n      item.lastPaint = null\n      item.last = f\n      item.lastBi = bi\n      return true\n    }\n\n    // Liquid dynamics: the surface is a simulated body chasing the element.\n    // Centre-based on purpose: the mass's CENTRE moves first (fast spring),\n    // size follows on a slower jelly spring, corner radius adapts last —\n    // liquid flows to where it's going before it takes the new shape.\n    const tcx = f.x + f.w / 2\n    const tcy = f.y + f.h / 2\n    // Evolve re-measures the element's border-radius every frame, so the\n    // element's OWN css transition timing (duration/easing) shows through on\n    // the liquid surface. A one-time snapshot would ignore it entirely.\n    let tr: number\n    if (dyn.evolve) {\n      // measureRadius already resolves the CURRENT radius for the CURRENT\n      // box (px values pass through as-is; % values resolve against the\n      // ow/oh passed in) — no further scaling is needed or correct here.\n      // The previous version additionally multiplied by (f.w / ow): the\n      // getBoundingClientRect width (f.w, float) vs offsetWidth (ow, an\n      // independently-rounded integer) differ by sub-pixel noise on every\n      // animation frame, especially under Safari's own layout rounding\n      // during a live width transition. That near-1.0 ratio contributed\n      // nothing functionally but injected exactly that noise into the\n      // radius spring's target — which a near-critically-damped spring\n      // tracks almost instantly, i.e. visible per-frame jitter (\"flashing\")\n      // on the rendered corner.\n      const ow = item.target.offsetWidth\n      const oh = item.target.offsetHeight\n      tr = measureRadius(item.target, ow, oh)[0]\n    } else {\n      tr = item.radiusPx * (item.baseW > 0 ? f.w / item.baseW : 1)\n    }\n    if (!item.sim) {\n      item.sim = { cx: tcx, cy: tcy, w: f.w, h: f.h, r: tr, vcx: 0, vcy: 0, vw: 0, vh: 0, vr: 0 }\n    }\n    const s = item.sim\n    if (dyn.move) {\n      // Lag + wobble: liquid rubber trailing the element.\n      const mo = dyn.moveOpts ?? MOVE_DEFAULTS\n      ;[s.cx, s.vcx] = springSteps(s.cx, s.vcx, tcx, mo.stiffness, mo.damping, dt)\n      ;[s.cy, s.vcy] = springSteps(s.cy, s.vcy, tcy, mo.stiffness, mo.damping, dt)\n    } else if (dyn.evolve) {\n      // Mass moves first: springs can only chase, so aim AHEAD of the moving\n      // target by its (smoothed) velocity — the droplet travels toward the\n      // destination while still small, then the size catches up.\n      const eo = dyn.evolveOpts ?? EVOLVE_DEFAULTS\n      const rawVx = item.tPrev ? (tcx - item.tPrev.cx) / dt : 0\n      const rawVy = item.tPrev ? (tcy - item.tPrev.cy) / dt : 0\n      item.tvx = item.tvx * 0.7 + rawVx * 0.3\n      item.tvy = item.tvy * 0.7 + rawVy * 0.3\n      item.tPrev = { cx: tcx, cy: tcy }\n      // Lead direction: the target's own velocity while it is moving, else\n      // whatever distance the droplet still has to cover.\n      const remX = tcx - s.cx\n      const remY = tcy - s.cy\n      const rem = Math.hypot(remX, remY)\n      const vMag = Math.hypot(item.tvx, item.tvy)\n      let dx = 0\n      let dy = 0\n      if (vMag > 1e-3) {\n        dx = item.tvx / vMag\n        dy = item.tvy / vMag\n      } else if (rem > 1e-3) {\n        dx = remX / rem\n        dy = remY / rem\n      }\n      // `anticipation` only times the ramp-in; it must never scale the reach,\n      // or a small value would silently cancel `travel`.\n      const tau = Math.max(0, eo.anticipation) / 1000\n      const k = tau > 0 ? 1 - Math.exp(-dt / tau) : 1\n      item.lead01 += ((rem > 0.5 ? 1 : 0) - item.lead01) * k\n      // Clamping the reach to the remaining distance keeps the lead from\n      // pulling the spring target past the destination as it arrives.\n      const reach = Math.min(Math.max(0, eo.travel) * item.lead01, rem)\n      const ox = dx * reach\n      const oy = dy * reach\n      ;[s.cx, s.vcx] = springSteps(s.cx, s.vcx, tcx + ox, eo.massStiffness, eo.massDamping, dt)\n      ;[s.cy, s.vcy] = springSteps(s.cy, s.vcy, tcy + oy, eo.massStiffness, eo.massDamping, dt)\n    } else {\n      s.cx = tcx\n      s.cy = tcy\n      s.vcx = 0\n      s.vcy = 0\n    }\n    if (dyn.evolve) {\n      // Size adapts after the mass, radius after the size.\n      const eo = dyn.evolveOpts ?? EVOLVE_DEFAULTS\n      ;[s.w, s.vw] = springSteps(s.w, s.vw, f.w, eo.sizeStiffness, eo.sizeDamping, dt)\n      ;[s.h, s.vh] = springSteps(s.h, s.vh, f.h, eo.sizeStiffness, eo.sizeDamping, dt)\n      // Default near-critical damping: the corner radius must land without\n      // bouncing — the roundness envelope already supplies the liquid overshoot.\n      ;[s.r, s.vr] = springSteps(s.r, s.vr, tr, eo.radiusStiffness, eo.radiusDamping, dt)\n    } else {\n      s.w = f.w\n      s.h = f.h\n      s.r = tr\n      s.vw = 0\n      s.vh = 0\n      s.vr = 0\n    }\n    let extra = ''\n    const speed = Math.hypot(s.vcx, s.vcy)\n    if (dyn.move && speed > 2) {\n      // Mild stretch along the velocity axis — the drop shape itself comes\n      // from the trailing satellite below, not from squashing the body into\n      // an ellipse.\n      const st = Math.min((dyn.moveOpts ?? MOVE_DEFAULTS).stretch, speed * 0.0006)\n      const a = Math.round(Math.atan2(s.vcy, s.vcx) * 100) / 100\n      extra += ` rotate(${a}rad) scale(${(1 + st).toFixed(3)}, ${(1 / (1 + st * 0.65)).toFixed(3)}) rotate(${-a}rad)`\n    }\n    if (dyn.move && item.tailEl) {\n      // Trailing droplet: chases the body's centre on a laggier spring and\n      // swells with speed — the goo filter strings body + satellite into a\n      // moving-drop silhouette with a liquid tail. The lag is clamped so the\n      // satellite always overlaps the body's blur field: a small circle on\n      // its own sits below the goo alpha threshold and would simply vanish.\n      const round = (v: number) => Math.round(v * 10) / 10\n      if (item.tailR === 0 && Math.abs(item.tailX) < 0.001 && Math.abs(item.tailY) < 0.001) {\n        item.tailX = s.cx\n        item.tailY = s.cy\n      }\n      ;[item.tailX, item.tailVx] = springSteps(item.tailX, item.tailVx, s.cx, 170, 22, dt)\n      ;[item.tailY, item.tailVy] = springSteps(item.tailY, item.tailVy, s.cy, 170, 22, dt)\n      const bi = item.blobInset ?? 0\n      // The droplet belongs to the SIDE it trails from, and it has to clear\n      // that side to be seen at all. Both were wrong for a non-square body:\n      // sizing off min(w,h) made a wide card's tail as small as its short\n      // edge, and capping the lag at that same number kept the droplet\n      // buried inside a 246px-wide card — invisible however large the knob.\n      // Perpendicular extent sets the SIZE (a horizontal drag trails the\n      // card's height, a vertical one its width), and the lag cap clears the\n      // body's own half-extent along the motion.\n      const ux = speed > 0.001 ? s.vcx / speed : 1\n      const uy = speed > 0.001 ? s.vcy / speed : 0\n      const perp = Math.max(4, Math.abs(ux) * s.h + Math.abs(uy) * s.w - bi * 2)\n      const halfAlong = (Math.abs(ux) * s.w + Math.abs(uy) * s.h) / 2\n      const base = perp / 2\n      const lagX = item.tailX - s.cx\n      const lagY = item.tailY - s.cy\n      const lag = Math.hypot(lagX, lagY)\n      // `force` = the tongue's reach: how far past the body's trailing edge\n      // the satellite may lag before being dragged along.\n      const mo = dyn.moveOpts ?? MOVE_DEFAULTS\n      const maxLag = halfAlong + base * (0.2 + mo.force * 1.6)\n      if (lag > maxLag) {\n        item.tailX = s.cx + (lagX / lag) * maxLag\n        item.tailY = s.cy + (lagY / lag) * maxLag\n      }\n      // Growth is RELATIVE, not a fixed px-per-speed slope. An absolute\n      // slope is a size cap in disguise: a wide card trailing its 246px\n      // side needed ~2000px/s before the droplet finished growing, so it\n      // stayed a pebble at any human drag speed. The droplet now reaches\n      // its full size — `tail` x the trailing side's half-extent, so tail 1\n      // is a drop as big as the side it leaves — at a reachable ~400px/s,\n      // whatever the body's dimensions.\n      const tailK = mo.tail\n      // Size is not speed-scaled: once the drag is genuinely moving, the\n      // tail is at its full `tail`-fraction of the trailing side (tail 1 =\n      // the whole side). The short onset ramp only stops it popping in on\n      // micro-jitters; reach/extension is `force`'s job above.\n      const onset = Math.max(0, Math.min(1, (speed - 20) / 120))\n      const targetR = base * tailK * onset\n      item.tailR += (targetR - item.tailR) * Math.min(1, dt * 10)\n\n      if (item.tailR < 0.3) {\n        if (item.lastTail !== 'hidden') {\n          item.tailEl.setAttribute('r', '0')\n          item.tailMidA?.setAttribute('r', '0')\n          item.tailMidB?.setAttribute('r', '0')\n          item.lastTail = 'hidden'\n        }\n      } else {\n        // Wobble phase rides distance travelled, so it freezes when the\n        // drag pauses instead of idling on wall time.\n        item.tailPhase += speed * dt * 0.045\n        // Mid-droplets sit at 45% and 75% of the way out, tapering, each\n        // nudged off-axis in opposite directions — the merged tongue gets a\n        // slight S-curve and stops reading as a plain circle chain.\n        const wob = item.tailR * 0.16\n        const px = -uy\n        const py = ux\n        const w1 = Math.sin(item.tailPhase) * wob\n        const w2 = Math.sin(item.tailPhase + 2.4) * -wob\n        const aX = s.cx + lagX * 0.45 + px * w1\n        const aY = s.cy + lagY * 0.45 + py * w1\n        const bX = s.cx + lagX * 0.75 + px * w2\n        const bY = s.cy + lagY * 0.75 + py * w2\n        const tail =\n          `${round(item.tailX)},${round(item.tailY)},${round(item.tailR)},` +\n          `${round(aX)},${round(aY)},${round(bX)},${round(bY)}`\n        if (tail !== item.lastTail) {\n          item.tailEl.setAttribute('cx', String(round(item.tailX)))\n          item.tailEl.setAttribute('cy', String(round(item.tailY)))\n          item.tailEl.setAttribute('r', String(round(item.tailR)))\n          if (item.tailMidA) {\n            item.tailMidA.setAttribute('cx', String(round(aX)))\n            item.tailMidA.setAttribute('cy', String(round(aY)))\n            item.tailMidA.setAttribute('r', String(round(item.tailR * 0.62)))\n          }\n          if (item.tailMidB) {\n            item.tailMidB.setAttribute('cx', String(round(bX)))\n            item.tailMidB.setAttribute('cy', String(round(bY)))\n            item.tailMidB.setAttribute('r', String(round(item.tailR * 0.4)))\n          }\n          item.lastTail = tail\n        }\n      }\n    }\n    let renderR = Math.max(0, s.r)\n    let cornerActive = false\n    if (dyn.evolve) {\n      const eo = dyn.evolveOpts ?? EVOLVE_DEFAULTS\n      const now = performance.now()\n      // Corner timeline: detect a morph beginning (target size starts\n      // changing after a quiet spell) and run droplet-round → target radius\n      // over the configured duration/easing/delay, starting at t=0 of the\n      // morph — a normal animation, no motion gating.\n      const prevSize = item.lastTargetSize\n      const sizeDelta = prevSize ? Math.abs(f.w - prevSize.w) + Math.abs(f.h - prevSize.h) : 0\n      // LATCHED trigger: the timeline starts once per morph and cannot\n      // restart until the size has been still AND the timeline has finished.\n      // A gap-based test (\"no size change for 120ms → new morph\") restarts\n      // mid-morph whenever frames are delivered irregularly — which Safari\n      // does under filter repaints — and each restart snaps the corners back\n      // to fully round, reading as flashing.\n      if (sizeDelta > 0.5) {\n        if (!item.morphActive) {\n          item.cornerT0 = now\n          item.morphActive = true\n        }\n        item.lastTargetMoveT = now\n      } else if (\n        item.morphActive &&\n        now - item.lastTargetMoveT > 150 &&\n        now - item.cornerT0 > cornerTotalOf(eo)\n      ) {\n        item.morphActive = false\n      }\n      item.lastTargetSize = { w: f.w, h: f.h }\n      const cornerTotal = cornerTotalOf(eo)\n      let target01 = 0\n      if (item.cornerT0 > 0 && eo.roundness > 0 && now - item.cornerT0 < cornerTotal) {\n        const p = Math.min(\n          1,\n          Math.max(0, (now - item.cornerT0 - Math.max(0, eo.cornerDelay)) / Math.max(1, eo.cornerDuration)),\n        )\n        const eased = easingFn(eo.cornerEase)(p)\n        target01 = Math.min(1, Math.max(0, (1 - eased) * eo.roundness))\n      }\n      // Rate-limit the roundness so it GLIDES to the timeline value instead of\n      // stepping: at morph start the timeline jumps to full round — invisible\n      // when opening from a circle, a hard snap when closing from a card.\n      const maxStep = dt * 8\n      item.round01 += Math.max(-maxStep, Math.min(maxStep, target01 - item.round01))\n      cornerActive =\n        (item.cornerT0 > 0 && now - item.cornerT0 < cornerTotal + 80) ||\n        Math.abs(target01 - item.round01) > 0.004 ||\n        item.round01 > 0.004\n      if (item.round01 > 0.001) {\n        // The boost may only RAISE the radius above the spring value: when the\n        // size spring undershoots, min(w,h)/2 can fall below the corner radius\n        // and would drag it down — that reads as the corners pulsing.\n        const roundTarget = Math.max(Math.min(s.w, s.h) / 2, renderR)\n        renderR = renderR + (roundTarget - renderR) * item.round01\n        // And never dip below the destination radius on the way down. (Safe\n        // unconditionally: SVG clamps rx to half the rect on its own.)\n        renderR = Math.max(renderR, tr)\n      }\n      // Content cross-blur still follows physical motion.\n      const motionRaw = Math.min(\n        1,\n        (Math.hypot(s.vcx, s.vcy) + Math.abs(s.vw) + Math.abs(s.vh)) / 420,\n      )\n      item.motionEnv = Math.max(motionRaw, item.motionEnv - dt * 1.9)\n      const motion = item.motionEnv\n      const blurPx = motion * motion * Math.max(0, eo.contentBlur)\n      if (blurPx > 0.3) {\n        item.target.style.filter = `blur(${blurPx.toFixed(1)}px)`\n        item.contentBlurred = true\n      } else if (item.contentBlurred) {\n        item.target.style.removeProperty('filter')\n        item.contentBlurred = false\n      }\n    }\n    const bi = item.blobInset ?? 0\n    const bw = Math.max(0, s.w - bi * 2)\n    const bh = Math.max(0, s.h - bi * 2)\n    const paintRx = pillRadius(renderR - bi, bw, bh)\n    // Body bow, two independent axes: vertical velocity arcs the top and\n    // bottom edges (middle leads, ends lag), horizontal velocity arcs the\n    // left and right edges — each behind its own knob. A rect cannot arc,\n    // so while bowed the silhouette is drawn as a path with the affected\n    // edges curved, and the rect is parked at zero size.\n    let bendD = ''\n    if (dyn.move && item.bendPathEl) {\n      const mo = dyn.moveOpts ?? MOVE_DEFAULTS\n      const cap = Math.min(bw, bh) * 0.5\n      const bTy = Math.max(-cap, Math.min(cap, s.vcy * 0.05)) * mo.bend\n      // The cap deformation reads at larger amplitudes than the bow, so the\n      // horizontal axis gets a higher ceiling and a hotter velocity slope.\n      const capX = Math.min(bw, bh) * 0.9\n      const bTx = Math.max(-capX, Math.min(capX, s.vcx * 0.09)) * mo.bendX\n      item.bendCur += (bTy - item.bendCur) * Math.min(1, dt * 9)\n      item.bendCurX += (bTx - item.bendCurX) * Math.min(1, dt * 9)\n      // Expose the live bend to the content as CSS vars, so the DOM inside\n      // can lean with the liquid (the silhouette arcs; real elements can\n      // only translate/skew, so the content chooses its own response).\n      const bvx = Math.round(item.bendCurX * 10) / 10\n      const bvy = Math.round(item.bendCur * 10) / 10\n      const bendVars = `${bvx},${bvy}`\n      if (bendVars !== item.lastBendVars) {\n        item.target.style.setProperty('--lg-bend-x', `${bvx}px`)\n        item.target.style.setProperty('--lg-bend-y', `${bvy}px`)\n        // Unitless twins: CSS calc() cannot turn px into deg, so rotation/\n        // skew/scale responses need the raw numbers.\n        item.target.style.setProperty('--lg-bend-xn', String(bvx))\n        item.target.style.setProperty('--lg-bend-yn', String(bvy))\n        item.lastBendVars = bendVars\n      }\n      const bendActive = Math.abs(item.bendCur) > 0.5 || Math.abs(item.bendCurX) > 0.5\n      if (bendActive && bw > 1 && bh > 1) {\n        const r = Math.min(paintRx, bw / 2, bh / 2)\n        // Vertical bow: quadratic sag b at the edge midpoint (control 2b).\n        const cy = Math.round(item.bendCur * 2 * 10) / 10\n        // Horizontal \"bend\" on a pill can't bow the side edges — they are\n        // zero-length between the corner arcs, so a curve there only shoves\n        // the caps sideways. Real physics deforms the CAPS instead: the\n        // leading cap blunts against the flow (shorter horizontal extent),\n        // the trailing cap stretches out behind, roughly twice as far.\n        const k = item.bendCurX\n        const rxR = Math.max(r * 0.2, Math.min(r * 3, k > 0 ? r - 0.8 * k : r + 1.6 * -k))\n        const rxL = Math.max(r * 0.2, Math.min(r * 3, k > 0 ? r + 1.6 * k : r - 0.8 * -k))\n        // Quarter-circle as cubic: control offset 0.5523 x the radius.\n        const K = 0.5523\n        const f = (v: number) => Math.round(v * 10) / 10\n        bendD =\n          `M ${f(rxL)} 0 Q ${f(bw / 2)} ${cy} ${f(bw - rxR)} 0 ` +\n          `C ${f(bw - rxR + K * rxR)} 0 ${f(bw)} ${f(r - K * r)} ${f(bw)} ${f(r)} ` +\n          `L ${f(bw)} ${f(bh - r)} ` +\n          `C ${f(bw)} ${f(bh - r + K * r)} ${f(bw - rxR + K * rxR)} ${f(bh)} ${f(bw - rxR)} ${f(bh)} ` +\n          `Q ${f(bw / 2)} ${f(bh + item.bendCur * 2)} ${f(rxL)} ${f(bh)} ` +\n          `C ${f(rxL - K * rxL)} ${f(bh)} 0 ${f(bh - r + K * r)} 0 ${f(bh - r)} ` +\n          `L 0 ${f(r)} ` +\n          `C 0 ${f(r - K * r)} ${f(rxL - K * rxL)} 0 ${f(rxL)} 0 Z`\n      }\n    }\n    const bending = bendD !== ''\n    const paint = {\n      t: `translate(${s.cx - s.w / 2 + bi}px, ${s.cy - s.h / 2 + bi}px)` + extra,\n      w: bending ? '0' : String(bw),\n      h: String(bh),\n      rx: String(paintRx),\n    }\n    const lp = item.lastPaint\n    if (!lp || lp.t !== paint.t) item.blob.style.transform = paint.t\n    if (!lp || lp.w !== paint.w) item.blob.setAttribute('width', paint.w)\n    if (!lp || lp.h !== paint.h) item.blob.setAttribute('height', paint.h)\n    if (!lp || lp.rx !== paint.rx) item.blob.setAttribute('rx', paint.rx)\n    item.lastPaint = paint\n    if (item.bendPathEl) {\n      if (bendD !== (item.lastBendD ?? '')) {\n        item.bendPathEl.setAttribute('d', bendD)\n        item.lastBendD = bendD\n      }\n      if (bending) item.bendPathEl.style.transform = paint.t\n    }\n    item.last = f\n    const settled =\n      Math.abs(s.cx - tcx) < 0.05 &&\n      Math.abs(s.cy - tcy) < 0.05 &&\n      Math.abs(s.w - f.w) < 0.05 &&\n      Math.abs(s.h - f.h) < 0.05 &&\n      Math.abs(s.r - tr) < 0.05 &&\n      speed < 1 &&\n      Math.abs(s.vw) + Math.abs(s.vh) + Math.abs(s.vr) < 1 &&\n      item.motionEnv < 0.01 &&\n      item.tailR < 0.3 &&\n      !cornerActive\n    return !settled\n  }\n\n  /** Nearest-neighbour proximity → a liquid warp-melt at the contact point.\n   *  The strength is ONE smoothed value: fast attack while approaching, and\n   *  a gradual `releaseMs` decay whenever the target drops — whether from a\n   *  drag release (`active: false`), moving out of range, or absorption. No\n   *  path clears instantly. */\n  private writeBlend(item: Item, dt: number): boolean {\n    const f = item.frame!\n    const blend = item.blend!\n    const melt = item.melt\n    if (!melt) return false\n    // Melt range tracks where the goo bridge actually forms (~2.5x the goo\n    // blur) — melting before surfaces visually neck reads as a bug.\n    const range = blend.range ?? Math.max(10, this.gooBlur * 2.5)\n    let bestGap = Infinity\n    let bestOther: Frame | null = null\n    for (const other of this.items) {\n      if (other === item || !other.frame) continue\n      const o = other.frame\n      const dx = Math.max(o.x - (f.x + f.w), f.x - (o.x + o.w), 0)\n      const dy = Math.max(o.y - (f.y + f.h), f.y - (o.y + o.h), 0)\n      const gap = Math.hypot(dx, dy)\n      if (gap < bestGap) {\n        bestGap = gap\n        bestOther = o\n      }\n    }\n    // How far INSIDE the neighbour this piece has travelled. `bestGap` is an\n    // outside distance and clamps to 0 the instant the boxes touch, so on its\n    // own it cannot tell \"just met\" from \"buried\" — everything past first\n    // contact looks identical to it. Overlap depth is the missing half of the\n    // measurement: the shallower of the two axis overlaps, which is how deep\n    // the piece has actually sunk rather than how much area happens to\n    // intersect. Normalized by the SMALLER body, since that is the most\n    // overlap the pair can ever produce, so 1 means fully engulfed and the\n    // two items agree on the number from either side.\n    let embed = 0\n    /** Longest axis of the overlap rect — how much SEAM the pair currently\n     *  shares. The photo-edge erasure must scale with this: a hole sized to\n     *  the melt zone is a dot on a 40px seam, and everything past it stays a\n     *  razor-sharp photo edge cutting across the neighbour. */\n    let contactSpan = 0\n    if (bestOther && bestGap === 0) {\n      const o = bestOther\n      const ox = Math.min(f.x + f.w, o.x + o.w) - Math.max(f.x, o.x)\n      const oy = Math.min(f.y + f.h, o.y + o.h) - Math.max(f.y, o.y)\n      const span = Math.max(1, Math.min(f.w, f.h, o.w, o.h))\n      embed = Math.max(0, Math.min(ox, oy)) / span\n      contactSpan = Math.max(0, Math.max(ox, oy))\n    }\n    // Target strength from proximity and activity; squared smoothstep biases\n    // the ramp late — barely anything at first neck.\n    let sTarget = 0\n    if (bestOther && bestGap < range && blend.active !== false) {\n      // FULL strength while bridged, soft only at the entry: the melt used to\n      // keep ramping across the whole range (0.34 at half range), so a long\n      // goo neck carried only ghost-faint imagery — the taffy strand read as\n      // bare liquid with two weak stubs. A strand exists exactly while the\n      // neck does, and it should be as saturated mid-flight as at contact;\n      // the outer 35% of the range remains the fade-in so approach still\n      // reads as gradual.\n      const sRaw = smoothstep(Math.min(1, (1 - bestGap / range) / 0.65))\n      // Strength is a CEILING, not a linear scale: even at full contact the\n      // melt cannot exceed it, but it still ramps the same way on approach —\n      // scaling sRaw itself would also slow the ramp, reading as \"farther\n      // away\" rather than \"weaker\".\n      const strength = Math.max(0, Math.min(1, blend.strength ?? 1))\n      // Sink-out: the melt belongs to the seam, so it recedes as the seam is\n      // swallowed. The ramp begins as soon as the piece is properly overlapping\n      // rather than merely touching, and is finished by `sink` — well before\n      // the piece is buried, since by then it reads as joined, not melting.\n      // Smoothstep at both ends so neither the onset nor the finish shows an\n      // edge as the piece is dragged in and out.\n      const sink = Math.max(0.01, blend.sink ?? 0.45)\n      const sunk = smoothstep(\n        Math.max(0, Math.min(1, (embed - sink * 0.2) / Math.max(0.01, sink * 0.8))),\n      )\n      sTarget = Math.pow(sRaw, 1.25) * strength * (1 - sunk)\n    }\n    // Asymmetric smoothing: quick attack; the release is a TIMED fade that\n    // reaches the target in exactly `releaseMs`. An exponential chase here\n    // needs ~4.4 time constants to clear its threshold, so a 110ms release\n    // still had the image masked ~490ms later — and whenever the consumer\n    // removed the element mid-tail (an avatar landing in its slot), the\n    // residual dissolve hole popped off in a single frame.\n    if (sTarget >= item.meltFade) {\n      item.meltFade += (sTarget - item.meltFade) * Math.min(1, dt * 16)\n      item.meltRel = null\n    } else if (sTarget > 0.02) {\n      // In-range fluctuation (pointer jitter, slow retreat): a gentle chase\n      // down, NOT the evaporation pipeline. Engaging the timed release here\n      // started the opacity fade mid-hover — the dissolve visibly vanished\n      // while still necking, then popped back on re-approach.\n      item.meltFade += (sTarget - item.meltFade) * Math.min(1, dt * 6)\n      item.meltRel = null\n    } else {\n      // The melt lives until BOTH the structural release and the opacity\n      // fade are done, so `fadeMs` can outlast `releaseMs` and give a long,\n      // clearly readable evaporation.\n      const relMs = Math.max(\n        40,\n        Math.max(blend.releaseMs ?? 240, blend.fadeMs ?? blend.releaseMs ?? 240),\n      )\n      if (!item.meltRel) item.meltRel = { from: item.meltFade, t: 0 }\n      const rel = item.meltRel\n      rel.t += dt * 1000\n      const k = Math.min(1, rel.t / relMs)\n      // (1-k)^2: fast start, gentle tail — the exponential's look, but it\n      // lands on an exact zero instead of an asymptote.\n      item.meltFade = sTarget + (rel.from - sTarget) * (1 - k) * (1 - k)\n    }\n    if (sTarget === 0 && item.meltFade < 0.001) item.meltFade = 0\n    const s = item.meltFade\n    if (s <= 0.001) {\n      if (item.lastBlend && item.lastBlend.s !== 0) {\n        this.clearBlend(item)\n        item.lastBlend = { cx: 0, cy: 0, s: 0, d: 0, pk: '' }\n        return true\n      }\n      return false\n    }\n    // Geometry: fresh while in contact; while the tail fades out of range,\n    // keep melting around the LAST contact point.\n    let o = bestOther\n    if ((!o || bestGap >= range) && item.meltGeom) o = item.meltGeom.o\n    if (!o) return false\n    const cx =\n      f.x + f.w < o.x\n        ? (f.x + f.w + o.x) / 2\n        : o.x + o.w < f.x\n          ? (o.x + o.w + f.x) / 2\n          : (Math.max(f.x, o.x) + Math.min(f.x + f.w, o.x + o.w)) / 2\n    const cy =\n      f.y + f.h < o.y\n        ? (f.y + f.h + o.y) / 2\n        : o.y + o.h < f.y\n          ? (o.y + o.h + f.y) / 2\n          : (Math.max(f.y, o.y) + Math.min(f.y + f.h, o.y + o.h)) / 2\n    item.meltGeom = { o: { ...o } }\n    // Progressive release: OPACITY leads, STRUCTURE lags. Scaling warp and\n    // blur down with the strength made the copy un-warp while still opaque —\n    // the image visibly \"snapped back to normal\" before disappearing.\n    // Instead the melt keeps most of its liquid character (structure relaxes\n    // only ~45%) and EVAPORATES: the overlay's opacity rides the timed\n    // release curve to zero, while the original image restores in sync with\n    // the true strength `s`.\n    const rel = item.meltRel\n    // Opacity runs on its OWN clock (`fadeMs`), not on the strength ratio —\n    // that tied the fade to `releaseMs`, so at the tuned 110ms release it was\n    // over before it could be read as a fade at all.\n    const fadeMs = Math.max(40, blend.fadeMs ?? blend.releaseMs ?? 240)\n    const fadeK = rel ? Math.min(1, rel.t / fadeMs) : 0\n    // Eased so it leaves gently instead of stepping off at a constant rate.\n    const relFade = rel ? (1 - fadeK) * (1 - fadeK) : 1\n    const sStruct = rel ? Math.min(1, rel.from * (0.55 + 0.45 * (1 - fadeK))) : s\n    const eStruct = sStruct * sStruct * (3 - 2 * sStruct)\n    // Falling follows the timed curve EXACTLY — it is already smooth, and a\n    // lagging chase here left the overlay at ~0.4 opacity when the fade hit\n    // zero and clearBlend cut it off: a visible pop at the very end. Only a\n    // re-approach mid-fade ramps, so opacity can't jump back to full.\n    item.meltOp =\n      relFade < item.meltOp\n        ? relFade\n        : item.meltOp + (relFade - item.meltOp) * Math.min(1, dt * 16)\n    // Melt zone sized like the goo bridge (from the group's blur), growing a\n    // little as contact deepens, and never swallowing the whole element —\n    // only the part around the contact mixes; the rest stays intact.\n    const zone = blend.zone ?? this.gooBlur * 2.2 + 4\n    const d = Math.min(Math.min(f.w, f.h) * 0.9, zone * (0.7 + 0.6 * sStruct))\n    // Churn phase, gated on ACTUAL movement: liquid only flows while the\n    // element is being dragged — a held drag freezes, and churn scales with\n    // drag speed.\n    const flowSpeed = Math.max(0, blend.flowSpeed ?? 26)\n    const prevPos = item.meltPrev\n    const moveSpeed = prevPos\n      ? Math.hypot(f.x - prevPos.x, f.y - prevPos.y) / Math.max(1e-3, dt)\n      : 0\n    item.meltPrev = { x: f.x, y: f.y }\n    // Phase advance capped per frame: dt is wall-clock, and after a slow\n    // frame a full-dt advance would visibly teleport the noise field.\n    const phaseAdv = Math.min(dt, 1 / 24) * flowSpeed * 0.12 * Math.min(1, moveSpeed / 40)\n    item.meltPhase += phaseAdv\n    const lb = item.lastBlend\n    // Live-tunable params join the still-frame check: without them a slider\n    // change on a static pose (the tuning workflow) never re-ran the writes\n    // and the knob looked dead until the next drag.\n    const paramKey = `${blend.seamBlur ?? ''}/${blend.strength ?? ''}/${blend.warp}/${blend.blur}/${blend.mix ?? ''}/${blend.gravity ?? ''}`\n    if (\n      phaseAdv < 1e-4 &&\n      lb &&\n      lb.pk === paramKey &&\n      Math.abs(lb.cx - cx) < 0.05 &&\n      Math.abs(lb.cy - cy) < 0.05 &&\n      Math.abs(lb.s - s) < 0.005 &&\n      Math.abs(lb.d - d) < 0.05\n    ) {\n      return false\n    }\n    // Write cadence, ADAPTIVE on frame health. Every write below dirties a\n    // turbulence/displacement filter, and WebKit re-rasterizes those on the\n    // CPU — at full frame rate on a struggling device the paint loop drowns\n    // (measured: ~1 paint per 2s in the iOS simulator). But a fixed 35ms\n    // throttle on a healthy 60Hz clock quantizes to every THIRD frame: the\n    // warped copy held still while the dragged photo glided, then hopped\n    // 3-5px to catch up — a 20Hz strobe that reads as the dissolve\n    // flickering during any in-contact move. So: while the frame clock is\n    // healthy the overlay is written every frame and tracks the photo\n    // exactly; when frames drop (the CPU-raster case the throttle protects)\n    // the 35ms backoff re-engages by itself. The simulation state above is\n    // already advanced either way; only the DOM flush waits. The active flag\n    // stays true so the loop keeps ticking.\n    const nowMs = performance.now()\n    if (this.frameEma > 20 && nowMs - item.meltWroteAt < 35) return true\n    item.meltWroteAt = nowMs\n    const round = (v: number) => Math.round(v * 10) / 10\n    const host = blend.host\n\n    const n = melt.layers.length\n\n    // Gravity direction: toward the NEIGHBOUR's centre.\n    const ncx = o.x + o.w / 2\n    const ncy = o.y + o.h / 2\n    const gdx = ncx - cx\n    const gdy = ncy - cy\n    const gdl = Math.hypot(gdx, gdy) || 1\n    const gux = gdx / gdl\n    const guy = gdy / gdl\n    const gAmt = Math.max(0, blend.gravity ?? 25) * eStruct\n    const gDeg = round((Math.atan2(guy, gux) * 180) / Math.PI)\n    const r3 = (v: number) => Math.round(v * 1000) / 1000\n    const taper = Math.max(0, Math.min(1, blend.taper ?? 0.65))\n\n    // MELTING is anisotropic: real melt drips ALONG the flow. Elongate the\n    // noise features along the dominant gravity axis (low frequency along,\n    // high across) so the displacement forms streaks/drips instead of an\n    // isotropic swirl. Re-aimed only when the dominant axis flips.\n    const freqK = Math.max(0.2, blend.warpFreq ?? 1)\n    const zoneBase = blend.zone ?? this.gooBlur * 2.2 + 4\n    const bfBase = Math.min(0.3, Math.max(0.01, freqK / (zoneBase * 1.1)))\n    const alongF = (bfBase * 0.35).toFixed(4)\n    const acrossF = (bfBase * 1.6).toFixed(4)\n    // Dominant axis held with HYSTERESIS: re-aiming exactly at |gux|==|guy|\n    // rotated the whole noise field 90° on every crossing of the diagonal —\n    // dragging around the contact wobbles the gravity vector across it\n    // repeatedly, and each flip re-generates the turbulence: a hard texture\n    // flicker. The axis only flips once the other component clearly wins.\n    const ax = Math.abs(gux)\n    const ay = Math.abs(guy)\n    const axis: 'x' | 'y' =\n      item.meltAxis === 'x'\n        ? ay > ax * 1.25 ? 'y' : 'x'\n        : item.meltAxis === 'y'\n          ? ax > ay * 1.25 ? 'x' : 'y'\n          : ax >= ay ? 'x' : 'y'\n    item.meltAxis = axis\n    const bfStr = axis === 'x' ? `${alongF} ${acrossF}` : `${acrossF} ${alongF}`\n\n    // Progressive melt: every layer shares one noise field (so they stay in\n    // phase and read as a single liquid) but blur, warp and erosion ramp\n    // smoothly from the zone's rim to its core, each masked to a tighter\n    // radius. Stacked, that approximates a continuous gradient — a two-step\n    // version banded visibly once blur got large.\n    //\n    // All masks are CONCENTRIC and centred AT the seam (tiny bias toward the\n    // neighbour): the warped imagery must cover the white liquid bridge, and\n    // with two melting items their copies overlap and interleave in the neck\n    // — colour mixes with colour. Centred into the item instead, the copies\n    // hugged their own edge and the neck showed as bare white fog between\n    // them. Pointiness comes from the content's gravity stretch — a\n    // per-layer pushed disc separates from the body and shows a detached\n    // circular fragment.\n    const bx = cx + gux * d * 0.05\n    const by = cy + guy * d * 0.05\n    // Every value below is QUANTIZED before writing, and each layer keeps a\n    // fingerprint of its last-written values: a frame that lands on the same\n    // quantized values skips the layer's writes entirely, so its turbulence\n    // filter is not re-rasterized. The steps are chosen below what the soft\n    // noise can visually resolve.\n    const layerVals: string[][] = melt.layers.map((_, i) => {\n      const t = n > 1 ? i / (n - 1) : 1 // 0 = outermost rim, 1 = tip\n      // Outer layer carries REAL warp (0.45, was 0.2): the rim of the melt is\n      // what the eye reads as the image's own edge bending — a calm rim made\n      // the surface look rigid with only the core swirling. Blur floor is up\n      // for the same reason: blur is local colour-averaging, and the taffy\n      // look wants the strand smoothed into blended tones over its whole\n      // length, not just at the tip.\n      const blurK = 0.15 + 0.85 * Math.pow(t, 1.4)\n      const warpK = 0.45 + 0.55 * t\n      const pr = 0.7 + 0.45 * t\n      const oa = 6 * Math.sin(item.meltPhase * pr)\n      const ob = 2 * Math.sin(item.meltPhase * pr * 1.31 + 1.7)\n      return [\n        String(q(blend.warp * warpK * eStruct, 0.25)),\n        String(q(blend.blur * blurK * eStruct, 0.25)),\n        String(q(gux * oa - guy * ob, 0.5)),\n        String(q(guy * oa + gux * ob, 0.5)),\n        String(q(bx, 0.5)),\n        String(q(by, 0.5)),\n        // Outermost disc at 0.95d, not 1.15d: past d the copy has left the\n        // neck entirely, and its blurred rim smearing onto the neighbour's\n        // body was half of the white-fog-ring report (the other half was the\n        // gradient rim above).\n        String(q(d * (0.95 - 0.55 * t), 0.5)),\n        String(q(Math.min(1, eStruct * (0.75 + 0.25 * t)), 0.02)),\n      ]\n    })\n    // (The single fingerprint-guarded write pass for the layers sits below,\n    // once the shift transform and erosion row are computable too — they\n    // dirty the same filters, so they must share the fingerprint.)\n    // Anchored stretch, NOT translation: scaling from the trailing edge of\n    // the melt zone keeps the warped copy aligned with the original at the\n    // back (a translated copy shows its silhouette as an offset ghost ring),\n    // while its leading side streams toward the pill by up to `gravity` px.\n    const anchorX = cx - gux * d\n    const anchorY = cy - guy * d\n    // Taper now shapes the STRETCH (how sharply content is drawn out toward\n    // the pill) rather than mask geometry.\n    // Gap-aware: while the bodies are APART the copies must travel the whole\n    // neck to meet mid-strand — that meeting is what mixes the two images\n    // into averaged tones along the bridge. The old 0.6 cap stopped the\n    // stretch at the seam, so a long neck stayed bare liquid with two short\n    // stubs of imagery at its ends.\n    // Stretch dies as the bodies MERGE: it exists to carry imagery across a\n    // neck, and once the pieces overlap there is no neck to cross — the same\n    // stretch then just paints a scaled ghost of the image over its own crisp\n    // photo (misaligned edges, the \"grown image\" look). Gone by ~45% embed.\n    // Floored, not zeroed. Killing the stretch outright on overlap also\n    // disconnected `gravity` in exactly the phase where the melt is supposed\n    // to run deepest — max gravity did nothing once the cards touched. The\n    // ghost-over-own-photo problem it was guarding against is now handled at\n    // the source: the leading edge is feathered away by the cross-fade, so\n    // there is no crisp edge left for a stretched copy to double.\n    const settle = 1 - 0.45 * smoothstep(Math.min(1, embed * 2.2))\n    const kFlow =\n      Math.min(2.2, (gAmt + bestGap) / Math.max(8, 2 * d)) * (0.5 + taper) * settle\n    const flow = (k: number) => {\n      const sx = r3(1 + kFlow * k)\n      const sy = r3(1 / (1 + kFlow * 0.35 * k))\n      return (\n        `translate(${round(anchorX)}, ${round(anchorY)}) rotate(${gDeg}) ` +\n        `scale(${sx}, ${sy}) ` +\n        `rotate(${-gDeg}) translate(${round(-anchorX)}, ${round(-anchorY)})`\n      )\n    }\n    // Two-liquid mixing by EROSION, not by painting: threshold the same noise\n    // into an alpha map (alpha = k·R + c) and clip the melted copy with it.\n    // The image breaks into tendrils and the liquid already behind shows\n    // through the gaps — no shape is drawn, so no disc can appear. The core\n    // erodes harder than the outer ripple, so mixing deepens toward the seam.\n    const mixAmt = Math.max(0, Math.min(1, blend.mix ?? 0)) * eStruct\n    const erodeRow = (amt: number) => {\n      if (amt < 0.002) return '0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 1'\n      // fractalNoise R sits around 0.5; a SOFT slope keeps tendril edges\n      // feathered — a steep one cut the image into hard patchy fragments.\n      const k = r3(1 + 4 * amt)\n      const c = r3(1 - k * (0.38 + 0.12 * amt))\n      return `0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  ${k} 0 0 0 ${c}`\n    }\n    // ONE fingerprint-guarded write pass per layer: any single primitive\n    // write re-rasterizes the layer's turbulence filter, so all of a layer's\n    // values must be compared — and skipped — together.\n    // Filter region: the mask only reveals a disc around the contact, so the\n    // region only has to cover that disc plus however far blur/warp/gravity\n    // can carry pixels into it. Quantized to 8px so small movements don't\n    // re-trigger a raster.\n    // The melt zone is a STRAND, not a disc, whenever the bodies are apart:\n    // the mask disc is stretched along the flow axis so the revealed imagery\n    // spans the whole goo neck. A circle sized to the seam left a long neck\n    // as bare liquid with imagery only at its ends; sized to the neck it\n    // swallowed the bodies sideways. Elongation only, width unchanged.\n    const elong = q(1 + Math.min(1.8, bestGap / Math.max(8, 2 * d)), 0.05)\n    const zoneT =\n      elong > 1.001\n        ? `translate(${round(bx)}, ${round(by)}) rotate(${gDeg}) ` +\n          `scale(${r3(elong)}, 1) ` +\n          `rotate(${-gDeg}) translate(${round(-bx)}, ${round(-by)})`\n        : ''\n    // Region grows with the elongated strand plus the stronger stretch.\n    const spread = blend.blur * 2.5 + blend.warp + gAmt * 0.5 + kFlow * d + 8\n    const rr = q(d * 1.15 * elong + spread, 8)\n    const regionX = String(q(bx - rr, 8))\n    const regionY = String(q(by - rr, 8))\n    const regionW = String(q(rr * 2, 8))\n\n    melt.layers.forEach((layer, i) => {\n      const t = n > 1 ? i / (n - 1) : 1\n      const v = layerVals[i]\n      const shiftT = flow(0.4 + 0.6 * t)\n      const erodeV = erodeRow(q(mixAmt * (0.15 + 0.85 * t), 0.01))\n      const fp =\n        v.join(',') + '|' + bfStr + '|' + shiftT + '|' + erodeV + '|' + zoneT +\n        '|' + regionX + ',' + regionY + ',' + regionW\n      if (layer.last === fp) return\n      layer.last = fp\n      layer.filter.setAttribute('x', regionX)\n      layer.filter.setAttribute('y', regionY)\n      layer.filter.setAttribute('width', regionW)\n      layer.filter.setAttribute('height', regionW)\n      layer.disp.setAttribute('scale', v[0])\n      layer.blurEl.setAttribute('stdDeviation', v[1])\n      if (layer.turb.getAttribute('baseFrequency') !== bfStr) {\n        layer.turb.setAttribute('baseFrequency', bfStr)\n      }\n      layer.noiseOffset.setAttribute('dx', v[2])\n      layer.noiseOffset.setAttribute('dy', v[3])\n      layer.circle.setAttribute('cx', v[4])\n      layer.circle.setAttribute('cy', v[5])\n      layer.circle.setAttribute('r', v[6])\n      // Mask writes don't dirty the turbulence raster — the transform rides\n      // the shared fingerprint anyway so a still frame writes nothing.\n      if (zoneT) layer.circle.setAttribute('transform', zoneT)\n      else layer.circle.removeAttribute('transform')\n      layer.gl.setAttribute('opacity', v[7])\n      layer.shift.setAttribute('transform', shiftT)\n      layer.erode.setAttribute('values', erodeV)\n    })\n    // Seam-blend layer: plain blur, no turbulence — the guaranteed-smooth\n    // colour-averaging wash under the textured layers. Half opacity so a\n    // pair's two washes sum to an average of both pictures at the seam.\n    if (melt.seam) {\n      const seam = melt.seam\n      const sBlur = q((blend.seamBlur ?? blend.blur * 1.6) * eStruct, 0.25)\n      const sOp = q(Math.min(1, eStruct * 1.2) * 0.55, 0.02)\n      const sR = q(d * 1.25, 0.5)\n      const fp =\n        `${sBlur}|${sOp}|${q(bx, 0.5)},${q(by, 0.5)},${sR}|${zoneT}` +\n        `|${regionX},${regionY},${regionW}`\n      if (seam.last !== fp) {\n        seam.last = fp\n        seam.filter.setAttribute('x', regionX)\n        seam.filter.setAttribute('y', regionY)\n        seam.filter.setAttribute('width', regionW)\n        seam.filter.setAttribute('height', regionW)\n        seam.blurEl.setAttribute('stdDeviation', String(sBlur))\n        seam.circle.setAttribute('cx', String(q(bx, 0.5)))\n        seam.circle.setAttribute('cy', String(q(by, 0.5)))\n        seam.circle.setAttribute('r', String(sR))\n        if (zoneT) seam.circle.setAttribute('transform', zoneT)\n        else seam.circle.removeAttribute('transform')\n        seam.gl.setAttribute('opacity', String(sOp))\n      }\n    }\n    // Gentle magnetic pull of the melted body toward the contact.\n    const icx = f.x + f.w / 2\n    const icy = f.y + f.h / 2\n    const ang = Math.atan2(cy - icy, cx - icx)\n    // Pull holds with the structure during the fade — the overlay must not\n    // glide back while it evaporates.\n    const pull = blend.pull * sStruct\n    const hostStr =\n      r3(item.meltOp).toString() +\n      '|' +\n      `translate(${round(Math.cos(ang) * pull)}px, ${round(Math.sin(ang) * pull)}px)`\n    if (hostStr !== item.meltHostLast) {\n      item.meltHostLast = hostStr\n      const parts = hostStr.split('|')\n      host.setAttribute('opacity', parts[0])\n      host.style.transform = parts[1]\n    }\n\n    // Depth 2.2x-biased: the original's edge is FULLY erased from s ≈ 0.45 —\n    // a partially faded high-contrast edge still reads as an edge, and the\n    // edge must be gone as soon as the goo neck reaches it. But ONLY then:\n    // the hole strength is gated on the actual bridging distance, not the\n    // melt's `range` — a large range starts the warp far out (anticipation),\n    // and opening the hole that early revealed the item's own white blob\n    // through the erased edge as a hard pale wedge, with no neck to justify\n    // it.\n    const bridgeRange = Math.max(10, this.gooBlur * 2.5)\n    const sBridge = bestOther\n      ? bestGap < bridgeRange\n        ? smoothstep(1 - bestGap / bridgeRange)\n        : 0\n      : s\n    // Quantized alongside the geometry below, for the same reason: a new\n    // alpha means a new mask string means a re-raster of every photo.\n    const holeAlpha = q(Math.max(0, 1 - Math.min(s, sBridge) * 2.2), 0.05).toFixed(2)\n    const holeMid = (Math.round(((1 + 2 * Number(holeAlpha)) / 3) * 20) / 20).toFixed(2)\n    for (const entry of melt.entries) {\n      // Swap in the downscaled pattern source once the image has decoded —\n      // at mount (refreshMelt) it usually hasn't, so this must be lazy.\n      if (!entry.lowRes) {\n        const lo = downscaleHref(entry.el)\n        if (lo) {\n          entry.image.setAttribute('href', lo)\n          entry.lowRes = true\n        } else if (entry.el.complete && entry.el.naturalWidth) {\n          entry.lowRes = true // already small, or tainted: original is final\n        }\n      }\n      const ir = entry.measured\n      if (!ir || ir.w < 1 || ir.h < 1) continue\n      const ix = ir.x\n      const iy = ir.y\n      // Warped copy geometry (group coordinates), written to every layer.\n      const kx = (ir.ow || ir.w) / ir.w\n      const geom = `${round(ix)},${round(iy)},${round(ir.w)},${round(ir.h)},${round(pillRadius(entry.radiusPx / (kx || 1), ir.w, ir.h))}`\n      if (geom !== entry.lastGeom) {\n        entry.lastGeom = geom\n        for (const rect of entry.rects) {\n          rect.setAttribute('x', String(round(ix)))\n          rect.setAttribute('y', String(round(iy)))\n          rect.setAttribute('width', String(round(ir.w)))\n          rect.setAttribute('height', String(round(ir.h)))\n          rect.setAttribute(\n            'rx',\n            String(round(pillRadius(entry.radiusPx / (kx || 1), ir.w, ir.h))),\n          )\n        }\n        entry.pattern.setAttribute('x', String(round(ix)))\n        entry.pattern.setAttribute('y', String(round(iy)))\n        entry.pattern.setAttribute('width', String(round(ir.w)))\n        entry.pattern.setAttribute('height', String(round(ir.h)))\n        entry.image.setAttribute('width', String(round(ir.w)))\n        entry.image.setAttribute('height', String(round(ir.h)))\n      }\n      // Edge dissolve on the original image, imagery only — labels around it\n      // stay sharp. Coordinates in the image's untransformed layout space.\n      const ky = (ir.oh || ir.h) / ir.h\n      // Only images the neck actually REACHES may dissolve. Relying on the\n      // hole landing off-canvas is not enough: once the two items overlap\n      // (a chip dragged onto the pill) the contact point sits INSIDE the\n      // group, so every image in it got a live hole — including ones the\n      // neck is nowhere near.\n      const gapToImg = Math.hypot(\n        Math.max(ix - cx, cx - (ix + ir.w), 0),\n        Math.max(iy - cy, cy - (iy + ir.h), 0),\n      )\n      if (gapToImg > d) {\n        if (entry.lastHole !== null) {\n          entry.lastHole = null\n          entry.el.style.removeProperty('mask-image')\n          entry.el.style.removeProperty('-webkit-mask-image')\n          entry.el.style.removeProperty('mask-composite')\n          entry.el.style.removeProperty('-webkit-mask-composite')\n        }\n        continue\n      }\n      // The hole must always eat an EDGE, never the middle. `cx,cy` is the\n      // centre of the contact SPAN, so as soon as the boxes overlap deeply it\n      // lands inside a photo — a hole centred on a 32px avatar with the neck's\n      // radius erases the whole face, which is the \"avatars disappear while\n      // dragging\" report. Push the centre out to the image's own rim along the\n      // contact direction, and cap the radius to that rim, so the far side of\n      // every image always survives.\n      const ow = ir.ow || ir.w\n      const oh = ir.oh || ir.h\n      const rim = Math.min(ow, oh) / 2\n      let lx = (cx - ix) * kx\n      let ly = (cy - iy) * ky\n      let vx = lx - ow / 2\n      let vy = ly - oh / 2\n      const vlen = Math.hypot(vx, vy)\n      if (vlen < rim) {\n        if (vlen < 1e-3) {\n          vx = gux\n          vy = guy\n        } else {\n          vx /= vlen\n          vy /= vlen\n        }\n        lx = ow / 2 + vx * rim\n        ly = oh / 2 + vy * rim\n      }\n      // Quantized to whole pixels. Every distinct mask string makes WebKit\n      // re-rasterise that <img>, and with a photo per group member this ran on\n      // every frame of a drag — the dominant cost behind the main-thread\n      // stalls that desynced the silhouette. The hole is a soft gradient, so\n      // 1px steps are invisible, and most frames now reuse the cached string\n      // and write nothing.\n      const hx = Math.round(lx)\n      const hy = Math.round(ly)\n      // Sized to the SEAM, not just the melt zone: once the boxes overlap,\n      // the shared edge is contactSpan long, and an erasure sized to the\n      // zone alone leaves most of that edge as a razor-sharp photo line\n      // cutting across the neighbour. Growing the hole with the span erases\n      // the whole crossing edge — what shows through is the image-filled\n      // blobs beneath, whose goo blur is already blending both pictures'\n      // local colours, so the seam resolves as the two tones melting\n      // together instead of a hard cut.\n      const hd = q(\n        Math.min(Math.max(d, contactSpan * 0.75) * Math.min(kx, ky), rim),\n        1,\n      )\n      // White stops (opaque under both alpha- and luminance-mode masking), and\n      // a final keep-stop that reaches the image's farthest corner. The hole's\n      // own stops only span the neck, so on any image bigger than the neck\n      // every pixel past them is outside the gradient's stop range: Chromium\n      // extends the last colour (opaque, image intact) but WebKit paints\n      // nothing there and erases the image.\n      //\n      // The stop is sized to the element, NOT some huge constant: WebKit sizes\n      // the gradient's raster by its declared extent, so a `9999px` stop asked\n      // it to rasterise an enormous buffer and cost ~130ms of main thread on\n      // the frame the mask changed.\n      const far =\n        round(\n          Math.max(\n            Math.hypot(hx, hy),\n            Math.hypot(hx - ow, hy),\n            Math.hypot(hx, hy - oh),\n            Math.hypot(hx - ow, hy - oh),\n          ),\n        ) + 2\n      // Erasure must stay INSIDE the warped copy's coverage. The copy's mask\n      // falls to ~0.25 opacity by 82% of its disc, so a hole restoring at\n      // 0.8·hd left an annulus where the photo was already erased but the\n      // copy was nearly gone — the white silhouette showed through as a pale\n      // ring hugging the melt. Tighter stops keep the fully-erased core well\n      // under the copy's opaque middle, and the photo is back to intact\n      // before the copy's falloff can no longer cover it.\n      let hole: string\n      if (bestGap === 0 && contactSpan > 4 && bestOther) {\n        const o2 = bestOther\n        // OVERLAPPED: the crossing edge is contactSpan long, and any disc —\n        // however sized — softens one point of it and leaves the rest razor\n        // sharp. So while the boxes overlap, the erasure is a LINEAR feather\n        // instead: the image's whole leading edge (everything facing the\n        // neighbour, full width) fades out across a band, and with both\n        // sides feathering toward each other the seam is a true cross-fade —\n        // each pixel a weighted average of the two pictures. The band width\n        // rides seamBlur, so the public knob directly widens the melt.\n        //\n        // ONE radial mask, centred on the NEIGHBOUR's centre: everything on\n        // my body nearest them fades out, curved around their body — corner\n        // contact, edge contact and deep overlap all feather correctly with\n        // a single gradient. (The previous approach — two axis gradients\n        // combined with mask-composite — depended on compositing support and\n        // on both writes landing; one browser quirk and an edge stayed\n        // razor. A lone gradient cannot half-apply.)\n        const ncx2 = (o2.x + o2.w / 2 - ix) * kx\n        const ncy2 = (o2.y + o2.h / 2 - iy) * ky\n        // Cover the whole crossing region: farthest corner of the OVERLAP\n        // rect from the neighbour centre, in my local px.\n        const ovx0 = (Math.max(f.x, o2.x) - ix) * kx\n        const ovy0 = (Math.max(f.y, o2.y) - iy) * ky\n        const ovx1 = (Math.min(f.x + f.w, o2.x + o2.w) - ix) * kx\n        const ovy1 = (Math.min(f.y + f.h, o2.y + o2.h) - iy) * ky\n        const rEnd = Math.round(\n          Math.max(\n            Math.hypot(ovx0 - ncx2, ovy0 - ncy2),\n            Math.hypot(ovx1 - ncx2, ovy0 - ncy2),\n            Math.hypot(ovx0 - ncx2, ovy1 - ncy2),\n            Math.hypot(ovx1 - ncx2, ovy1 - ncy2),\n          ) + 3,\n        )\n        const band = Math.round(\n          Math.min(\n            rim * 2.6,\n            Math.max(hd, (blend.seamBlur ?? blend.blur * 1.6) * 3.2),\n          ),\n        )\n        const rCore = Math.max(0, rEnd - band)\n        const farR =\n          Math.round(\n            Math.max(\n              Math.hypot(ncx2, ncy2),\n              Math.hypot(ncx2 - ow, ncy2),\n              Math.hypot(ncx2, ncy2 - oh),\n              Math.hypot(ncx2 - ow, ncy2 - oh),\n            ),\n          ) + 2\n        hole = `radial-gradient(circle at ${Math.round(ncx2)}px ${Math.round(ncy2)}px, rgba(255,255,255,${holeAlpha}) ${rCore}px, #fff ${rEnd}px, #fff ${farR}px)`\n      } else {\n        hole = `radial-gradient(circle at ${hx}px ${hy}px, rgba(255,255,255,${holeAlpha}) ${round(hd * 0.2)}px, rgba(255,255,255,${holeMid}) ${round(hd * 0.45)}px, #fff ${round(hd * 0.78)}px, #fff ${far}px)`\n      }\n      if (hole !== entry.lastHole) {\n        entry.lastHole = hole\n        entry.el.style.setProperty('mask-image', hole)\n        entry.el.style.setProperty('-webkit-mask-image', hole)\n        // Single-image masks need no compositing; clear any stale one.\n        entry.el.style.removeProperty('mask-composite')\n        entry.el.style.removeProperty('-webkit-mask-composite')\n      }\n    }\n    item.lastBlend = { cx, cy, s, d, pk: paramKey }\n    return true\n  }\n\n  private ensureSources(): void {\n    if (this.sourcesReady) return\n    const group = this.getGroup()\n    if (!group) return\n    this.sourcesReady = true\n    this.mo = new MutationObserver(muts => {\n      for (const m of muts) {\n        const t = m.target\n        // Ignore our own writes: blob attrs inside the silhouette svg and\n        // melt-overlay writes.\n        if (!(t instanceof Element) || !t.closest('[data-gooey-svg], [data-gooey-overlay]')) {\n          this.wake()\n          return\n        }\n      }\n    })\n    this.mo.observe(group, {\n      attributes: true,\n      childList: true,\n      subtree: true,\n      attributeFilter: ['style', 'class'],\n    })\n    const wake = () => this.wake()\n    for (const type of ['transitionrun', 'animationstart', 'pointerdown']) {\n      group.addEventListener(type, wake, true)\n      this.removeListeners.push(() => group.removeEventListener(type, wake, true))\n    }\n    window.addEventListener('scroll', wake, { capture: true, passive: true })\n    this.removeListeners.push(() => window.removeEventListener('scroll', wake, true))\n    // Safety net for motion the wake sources can't see (e.g. WAAPI):\n    // a cheap silent check 3x/second while asleep.\n    this.interval = setInterval(() => {\n      if (!this.awake && this.measureAll()) this.wake()\n    }, 300)\n  }\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/geometry.ts",
          "target": "@components/effects/liquid-gooey/upstream/geometry.ts",
          "type": "registry:component",
          "content": "export type CornerRadii = [number, number, number, number]\n\nexport interface BlobBox {\n  x: number\n  y: number\n  w: number\n  h: number\n  r: CornerRadii\n}\n\n/** Transform-free position of `el` relative to `ancestor` via the offsetParent\n *  chain — the blob mirrors motion separately, so its base box must ignore the\n *  transform currently applied to the wrapper. */\nexport function offsetTo(el: HTMLElement, ancestor: HTMLElement): { x: number; y: number } {\n  let x = 0\n  let y = 0\n  let node: HTMLElement | null = el\n  while (node && node !== ancestor && ancestor.contains(node)) {\n    x += node.offsetLeft\n    y += node.offsetTop\n    node = node.offsetParent as HTMLElement | null\n  }\n  return { x, y }\n}\n\nexport function measureRadius(el: Element, w: number, h: number): CornerRadii {\n  const cs = getComputedStyle(el)\n  const parse = (v: string): number => {\n    const first = v.split(' ')[0]\n    if (first.endsWith('%')) return ((parseFloat(first) || 0) / 100) * Math.min(w, h)\n    return parseFloat(first) || 0\n  }\n  return [\n    parse(cs.borderTopLeftRadius),\n    parse(cs.borderTopRightRadius),\n    parse(cs.borderBottomRightRadius),\n    parse(cs.borderBottomLeftRadius),\n  ]\n}\n\nexport function normalizeRadius(r: number | CornerRadii): CornerRadii {\n  return typeof r === 'number' ? [r, r, r, r] : r\n}\n\n/** Rounded-rect path with per-corner radii, CSS-style overlap clamping. */\nexport function roundedRectPath(x: number, y: number, w: number, h: number, radii: CornerRadii): string {\n  let [tl, tr, br, bl] = radii.map(v => Math.max(0, v)) as CornerRadii\n  const f = Math.min(\n    1,\n    w / Math.max(1e-6, tl + tr),\n    w / Math.max(1e-6, bl + br),\n    h / Math.max(1e-6, tl + bl),\n    h / Math.max(1e-6, tr + br),\n  )\n  tl *= f\n  tr *= f\n  br *= f\n  bl *= f\n  return (\n    `M ${x + tl} ${y} ` +\n    `H ${x + w - tr} A ${tr} ${tr} 0 0 1 ${x + w} ${y + tr} ` +\n    `V ${y + h - br} A ${br} ${br} 0 0 1 ${x + w - br} ${y + h} ` +\n    `H ${x + bl} A ${bl} ${bl} 0 0 1 ${x} ${y + h - bl} ` +\n    `V ${y + tl} A ${tl} ${tl} 0 0 1 ${x + tl} ${y} Z`\n  )\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/filter.tsx",
          "target": "@components/effects/liquid-gooey/upstream/filter.tsx",
          "type": "registry:component",
          "content": "import type { ReactElement } from 'react'\nimport type { ShadowLayer } from './shadow'\n\n/** Alpha-binarize matrix used before spread dilation: the goo alpha has a soft\n *  fringe past the opaque edge — dilating it directly pushes a spread ring a\n *  pixel out and the fringe reads as a second hairline. */\nconst BINARIZE = '1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 60 -29.5'\n\n/** CSS inset emulation on the LIQUID: paint the colour where the silhouette\n *  is NOT covered by a shrunk/offset/blurred copy of itself, clipped back to\n *  the silhouette — an inner ring (spread), inner edge line (offset) or soft\n *  inner shadow (blur) that follows the merged goo through every state. */\nfunction InsetPass({ i, s }: { i: number; s: ShadowLayer }): ReactElement {\n  const parts: ReactElement[] = []\n  // `bin` is computed once for the whole stack (see GooFilterPrimitives) —\n  // every full-region pass costs real milliseconds on WebKit's CPU\n  // rasterizer, and each pass here used to re-binarize `shape` identically.\n  let src = 'bin'\n  // Erode by the SPREAD only. An offset-only inset (`inset 0 1px 0 0`) must\n  // leave a 1px strip along the TOP edge and nothing else — eroding for it\n  // too shrinks the shape all round and paints a spurious ring on the sides\n  // and bottom, doubling up with a real inner ring in the same stack.\n  if (s.spread !== 0) {\n    parts.push(\n      <feMorphology\n        key=\"er\"\n        in={src}\n        operator={s.spread > 0 ? 'erode' : 'dilate'}\n        radius={Math.abs(s.spread)}\n        result={`s${i}-er`}\n      />,\n    )\n    src = `s${i}-er`\n  }\n  if (s.x !== 0 || s.y !== 0) {\n    parts.push(<feOffset key=\"o\" in={src} dx={s.x} dy={s.y} result={`s${i}-o`} />)\n    src = `s${i}-o`\n  }\n  if (s.blur > 0) {\n    parts.push(<feGaussianBlur key=\"b\" in={src} stdDeviation={s.blur / 2} result={`s${i}-b`} />)\n    src = `s${i}-b`\n  }\n  parts.push(\n    // The band: silhouette minus its shrunk/offset self.\n    <feComposite key=\"band\" in=\"bin\" in2={src} operator=\"out\" result={`s${i}-band`} />,\n    <feFlood key=\"c\" floodColor={s.color} result={`s${i}-c`} />,\n    <feComposite key=\"f\" in={`s${i}-c`} in2={`s${i}-band`} operator=\"in\" result={`s${i}`} />,\n  )\n  return <>{parts}</>\n}\n\nfunction ShadowPass({ i, s }: { i: number; s: ShadowLayer }): ReactElement {\n  const parts: ReactElement[] = []\n  let src = 'shape'\n  if (s.spread !== 0) {\n    parts.push(\n      <feMorphology\n        key=\"sp\"\n        in=\"bin\"\n        operator={s.spread > 0 ? 'dilate' : 'erode'}\n        radius={Math.abs(s.spread)}\n        result={`s${i}-sp`}\n      />,\n    )\n    src = `s${i}-sp`\n  }\n  if (s.blur > 0) {\n    parts.push(<feGaussianBlur key=\"b\" in={src} stdDeviation={s.blur / 2} result={`s${i}-b`} />)\n    src = `s${i}-b`\n  }\n  if (s.x !== 0 || s.y !== 0) {\n    parts.push(<feOffset key=\"o\" in={src} dx={s.x} dy={s.y} result={`s${i}-o`} />)\n    src = `s${i}-o`\n  }\n  parts.push(\n    <feFlood key=\"c\" floodColor={s.color} result={`s${i}-c`} />,\n    <feComposite key=\"f\" in={`s${i}-c`} in2={src} operator=\"in\" result={`s${i}`} />,\n  )\n  return <>{parts}</>\n}\n\nexport function GooFilterPrimitives({\n  blur,\n  contrast,\n  shadows,\n  waviness = 0,\n  wavinessFreq = 0.018,\n}: {\n  blur: number\n  contrast: number\n  shadows: ShadowLayer[]\n  /** Max px the liquid boundary undulates. 0 (default) = calm geometric edge. */\n  waviness?: number\n  /** Noise frequency of the undulation — lower = longer, lazier waves. */\n  wavinessFreq?: number\n}): ReactElement {\n  const wavy = waviness > 0\n  // Intercept tracks the slope so the alpha threshold stays near the same\n  // crossing as the classic 18/-7 goo pairing.\n  const intercept = Math.round((0.5 - contrast * (5 / 12)) * 100) / 100\n  return (\n    <>\n      <feGaussianBlur in=\"SourceGraphic\" stdDeviation={blur} result=\"blur\" />\n      <feColorMatrix\n        in=\"blur\"\n        type=\"matrix\"\n        values={`1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 ${contrast} ${intercept}`}\n        result=\"goo\"\n      />\n      <feComposite\n        in=\"SourceGraphic\"\n        in2=\"goo\"\n        operator=\"atop\"\n        result={wavy ? 'shape-raw' : 'shape'}\n      />\n      {/* The liquid boundary itself undulates: the whole silhouette — edges,\n          neck, shadow source — runs through one gentle displacement field, so\n          the surface reads as fluid even at rest. Shadows consume the\n          displaced 'shape', so they hug the wavy edge exactly. */}\n      {wavy && (\n        <>\n          <feTurbulence\n            type=\"fractalNoise\"\n            baseFrequency={wavinessFreq}\n            numOctaves={2}\n            seed=\"7\"\n            result=\"wave-noise\"\n          />\n          <feDisplacementMap\n            in=\"shape-raw\"\n            in2=\"wave-noise\"\n            scale={waviness * 2}\n            xChannelSelector=\"R\"\n            yChannelSelector=\"G\"\n            result=\"shape\"\n          />\n        </>\n      )}\n      {/* Binarized silhouette, computed ONCE and shared by every pass that\n          needs it. Each inset pass and each spread pass used to run this\n          identical feColorMatrix themselves — on a 5-layer stack that was\n          three redundant full-region passes per repaint. */}\n      {shadows.some(s => s.inset || s.spread !== 0) && (\n        <feColorMatrix in=\"shape\" type=\"matrix\" values={BINARIZE} result=\"bin\" />\n      )}\n      {shadows.map((s, i) =>\n        s.inset ? <InsetPass key={i} i={i} s={s} /> : <ShadowPass key={i} i={i} s={s} />,\n      )}\n      {shadows.length > 0 && (\n        <feMerge>\n          {/* CSS paints the first shadow of the list on top: outer passes\n              merge in reverse (among themselves) BELOW the shape; inset\n              passes paint ABOVE it — they live inside the liquid edge. */}\n          {shadows\n            .map((s, i) => (!s.inset ? i : -1))\n            .filter(i => i >= 0)\n            .reverse()\n            .map(i => (\n              <feMergeNode key={i} in={`s${i}`} />\n            ))}\n          <feMergeNode in=\"shape\" />\n          {shadows.map((s, i) => (s.inset ? <feMergeNode key={i} in={`s${i}`} /> : null))}\n        </feMerge>\n      )}\n    </>\n  )\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/shadow.ts",
          "target": "@components/effects/liquid-gooey/upstream/shadow.ts",
          "type": "registry:component",
          "content": "/** `box-shadow`-syntax parser. Layers become SVG filter passes built from the\n *  merged liquid silhouette, so one shadow hugs the goo through every state. */\n\nexport interface ShadowLayer {\n  x: number\n  y: number\n  blur: number\n  spread: number\n  color: string\n  /** Inner shadow/highlight: painted INSIDE the liquid edge, following the\n   *  merged silhouette exactly like the outer passes. */\n  inset: boolean\n}\n\nfunction splitTop(s: string, sep: ',' | ' '): string[] {\n  const parts: string[] = []\n  let depth = 0\n  let cur = ''\n  for (const ch of s) {\n    if (ch === '(') depth++\n    else if (ch === ')') depth--\n    if (depth === 0 && (sep === ',' ? ch === ',' : /\\s/.test(ch))) {\n      if (cur.trim()) parts.push(cur.trim())\n      cur = ''\n    } else {\n      cur += ch\n    }\n  }\n  if (cur.trim()) parts.push(cur.trim())\n  return parts\n}\n\nconst LENGTH = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)(px)?$/\n\nexport function parseShadow(input?: string | null): ShadowLayer[] {\n  if (!input || input.trim() === '' || input.trim() === 'none') return []\n  const out: ShadowLayer[] = []\n  for (const layer of splitTop(input, ',')) {\n    const tokens = splitTop(layer, ' ')\n    if (tokens.length === 0) continue\n    const inset = tokens.includes('inset')\n    const nums: number[] = []\n    const colorParts: string[] = []\n    for (const tok of tokens) {\n      if (tok === 'inset') continue\n      if (nums.length < 4 && LENGTH.test(tok)) nums.push(parseFloat(tok))\n      else colorParts.push(tok)\n    }\n    const [x = 0, y = 0, blur = 0, spread = 0] = nums\n    out.push({ x, y, blur, spread, color: colorParts.join(' ') || 'rgba(0, 0, 0, 0.35)', inset })\n  }\n  return out\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/hooks.ts",
          "target": "@components/effects/liquid-gooey/upstream/hooks.ts",
          "type": "registry:component",
          "content": "import { useEffect, useLayoutEffect, useState } from 'react'\n\nexport const useIsoLayoutEffect =\n  typeof window !== 'undefined' ? useLayoutEffect : useEffect\n\nexport function useReducedMotion(): boolean {\n  const [reduced, setReduced] = useState(false)\n  useEffect(() => {\n    const mq = window.matchMedia('(prefers-reduced-motion: reduce)')\n    setReduced(mq.matches)\n    const onChange = (e: MediaQueryListEvent) => setReduced(e.matches)\n    mq.addEventListener('change', onChange)\n    return () => mq.removeEventListener('change', onChange)\n  }, [])\n  return reduced\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/LiquidItem.tsx",
          "target": "@components/effects/liquid-gooey/upstream/LiquidItem.tsx",
          "type": "registry:component",
          "content": "import type { CSSProperties, ReactNode } from 'react'\nimport type { CornerRadii } from './geometry'\nimport { GooeyItem, type DissolveOptions } from './GooeyItem'\nimport { useGooeyContext } from './context'\nimport { IMAGE_MELT_DEFAULTS, ImageMeltItem, type ImageMeltOptions } from './imageMelt'\nimport {\n  EVOLVE_DEFAULTS,\n  MOVE_DEFAULTS,\n  type EvolveOptions,\n  type MoveOptions,\n} from './observer'\nimport type { Transition } from './spring'\n\n/** The two public liquid behaviors:\n *  - 'morph' (default): pieces merge gooily, change shape like jelly, and can\n *    dissolve into each other on contact — menus, avatar groups, morphing\n *    panels.\n *  - 'move': the surface trails a moving element as liquid rubber with a\n *    droplet tail — sliders, tab indicators, dragged things. */\nexport type LiquidEffect = 'morph' | 'move' | 'melt' | 'bend'\n\n/** Tuning for effect=\"bend\": the surface stays glued to the content and the\n *  BODY deforms with velocity — vertical drag arcs the top/bottom edges\n *  (middle leads, ends lag), horizontal drag reshapes the rounded caps\n *  (leading blunts, trailing stretches). The live bend is published on the\n *  item as --lg-bend-x/-y (px) and --lg-bend-xn/-yn (unitless) CSS vars, so\n *  content can lean/rotate/shear along with the silhouette. */\nexport interface BendTuning {\n  /** Vertical bow strength, 0..1. Default 0.6. */\n  vertical?: number\n  /** Horizontal cap deformation, 0..1. Default 0.35. */\n  horizontal?: number\n  /** Raw MoveOptions escape hatch, merged last. */\n  advanced?: MoveOptions\n}\n\n/** Simple tuning for effect=\"morph\". All knobs are normalized; defaults are\n *  the library's tuned look. Raw physics live under `advanced`. */\nexport interface MorphTuning {\n  /** Liquid shape-change physics: the surface springs behind size changes,\n   *  travels as a droplet and settles like jelly. Off by default — plain\n   *  merge needs no engine. */\n  shape?: boolean\n  /** Speed multiplier for the shape physics. 1 = default, 2 = twice as fast. */\n  speed?: number\n  /** 0..1 — how much the shape physics overshoot and wobble. 0 = calm and\n   *  critically damped, 1 = very springy. Default 0.5. */\n  bounce?: number\n  /** Max px your CONTENT cross-blurs by while the liquid is in motion,\n   *  sharpening as the shape settles — the content half of the effect, not\n   *  just the surface. Applies with `shape`. Default 7, `0` disables. */\n  contentBlur?: number\n  /** Full escape hatch: raw engine options, merged over the mapped values. */\n  advanced?: {\n    evolve?: EvolveOptions\n    /** Shrink the blob by px per side so opaque content fully covers its own\n     *  liquid (e.g. round photos). */\n    blobInset?: number\n    /** Px the blob swells back out near a neighbour — a visible liquid coat\n     *  that necks into the other surface. */\n    bridgeGrow?: number\n  }\n}\n\n/** Simple tuning for effect=\"move\". All knobs are 0..1; defaults are the\n *  library's tuned look. Raw physics live under `advanced`. */\nexport interface MoveTuning {\n  /** How tightly the liquid chases the element. 0 = heavy syrup lag,\n   *  1 = near-instant. Default 0.5. */\n  springiness?: number\n  /** How much the surface overshoots and wobbles on arrival. Default 0.5. */\n  wobble?: number\n  /** Velocity stretch of the drop. 0 = rigid. Default 0.36. */\n  stretch?: number\n  /** Trailing droplet size. 0 disables the tail. Default 0.575. */\n  trail?: number\n  /** Full escape hatch: raw spring values, merged over the mapped values. */\n  advanced?: MoveOptions\n}\n\nexport interface LiquidItemProps {\n  /** 'morph' (default) or 'move'. */\n  effect?: LiquidEffect\n  /** Tuning for effect=\"morph\". */\n  morph?: MorphTuning\n  /** Tuning for effect=\"move\". */\n  move?: MoveTuning\n  /** Tuning for effect=\"bend\". */\n  bend?: BendTuning\n  /** Tuning for effect=\"melt\": the image source (auto-detected from a child\n   *  <img> when omitted) plus the melt's physics. */\n  melt?: ImageMeltOptions & { src?: string }\n  /** Melt this item's imagery into a touching neighbour at the contact point\n   *  — a liquid warp, not a blur. Orthogonal to `effect`: it describes what\n   *  your CONTENT does where two surfaces meet, not how the surface moves.\n   *  `true` for the tuned look, `0..1` to scale it, or the raw\n   *  `DissolveOptions` for full control (wire `active` to your drag). */\n  dissolve?: boolean | number | DissolveOptions\n  /** Component-driven position: the library animates both the element and its\n   *  liquid in perfect sync. Omit x/y and animate the child yourself (CSS,\n   *  Framer Motion, …) — the liquid follows automatically when the effect\n   *  needs it, or with `observe` for plain merge. */\n  x?: number\n  y?: number\n  scale?: number\n  /** Spring preset/config or `{ duration, ease }` for x/y. Default 'smooth'. */\n  transition?: Transition\n  /** Transition delay in ms (stagger). */\n  delay?: number\n  /** Plain-merge items animated by YOUR code: makes the liquid follow the\n   *  child's rendered rect. Implied by `morph.shape`, `dissolve` and\n   *  effect=\"move\". */\n  observe?: boolean\n  /** Override the measured border-radius for the liquid (px). */\n  radius?: number | CornerRadii\n  className?: string\n  style?: CSSProperties\n  children?: ReactNode\n}\n\n/** Damping ratio from a 0..1 bounciness knob. 0.5 lands exactly on the tuned\n *  defaults' ratio (≈0.45); 0 is critically damped; 1 is very springy. */\nfunction zeta(bounce: number): number {\n  return Math.max(0.12, 1 - 1.1 * Math.min(1, Math.max(0, bounce)))\n}\n\nfunction mapMorphSprings(t: MorphTuning | undefined): EvolveOptions {\n  const s = Math.max(0.25, t?.speed ?? 1)\n  // Damping scales with ζ(bounce)/ζ(0.5) so (speed 1, bounce 0.5) reproduces\n  // EVOLVE_DEFAULTS exactly; stiffness × s² + damping × s keeps the ratio, so\n  // `speed` changes tempo without changing character.\n  const k = zeta(t?.bounce ?? 0.5) / zeta(0.5)\n  return {\n    massStiffness: EVOLVE_DEFAULTS.massStiffness * s * s,\n    massDamping: EVOLVE_DEFAULTS.massDamping * s * k,\n    sizeStiffness: EVOLVE_DEFAULTS.sizeStiffness * s * s,\n    sizeDamping: EVOLVE_DEFAULTS.sizeDamping * s * k,\n    // The radius spring stays critically damped at every bounce setting — the\n    // roundness envelope supplies the liquid look; a bouncing radius reads as\n    // flicker, not jelly.\n    radiusStiffness: EVOLVE_DEFAULTS.radiusStiffness * s * s,\n    radiusDamping: EVOLVE_DEFAULTS.radiusDamping * s,\n    cornerDuration: EVOLVE_DEFAULTS.cornerDuration / s,\n    contentBlur: t?.contentBlur ?? EVOLVE_DEFAULTS.contentBlur,\n  }\n}\n\nfunction mapDissolve(d: boolean | number): DissolveOptions {\n  const k = typeof d === 'number' ? Math.min(1, Math.max(0, d)) : 1\n  // `strength` is the engine's own ceiling: it scales warp/blur/gravity/mix\n  // AND the hole that erases the image's edge together, so a weak dissolve\n  // reads as a shallower liquid rather than an erased edge with nothing\n  // there to justify it. Geometry (zone/range) and motion character (taper/\n  // churn) stay at the tuned values regardless of strength.\n  return {\n    warp: 26,\n    blur: 8,\n    mix: 0.7,\n    gravity: 60,\n    taper: 1,\n    warpFreq: 1.7,\n    flowSpeed: 22,\n    detail: 2,\n    zone: 18,\n    range: 49,\n    releaseMs: 110,\n    strength: k,\n  }\n}\n\nfunction mapMove(t: MoveTuning | undefined): MoveOptions {\n  const p = Math.min(1, Math.max(0, t?.springiness ?? 0.5))\n  // Exponential feel curve centred on the default: 0 → ~120, 0.5 → 380,\n  // 1 → ~1200. Damping rescales with √stiffness and ζ(wobble) so the default\n  // knob positions reproduce MOVE_DEFAULTS exactly.\n  const stiffness = MOVE_DEFAULTS.stiffness * Math.pow(10, p - 0.5)\n  const damping =\n    MOVE_DEFAULTS.damping *\n    Math.sqrt(stiffness / MOVE_DEFAULTS.stiffness) *\n    (zeta(t?.wobble ?? 0.5) / zeta(0.5))\n  return {\n    stiffness,\n    damping,\n    stretch: 0.5 * Math.min(1, Math.max(0, t?.stretch ?? 0.36)),\n    tail: 0.8 * Math.min(1, Math.max(0, t?.trail ?? 0.575)),\n    ...t?.advanced,\n  }\n}\n\n/** The public item: two effects, simple normalized knobs, `advanced` escape\n *  hatches into the raw engine options. */\nfunction mapBend(t: BendTuning | undefined): MoveOptions {\n  return {\n    // Springiness 1 on the public curve: the surface tracks the content\n    // 1:1, so all liquid character comes from the bends.\n    ...mapMove({ springiness: 1, stretch: 0, trail: 0 }),\n    bend: Math.min(1, Math.max(0, t?.vertical ?? 0.6)),\n    bendX: Math.min(1, Math.max(0, t?.horizontal ?? 0.35)),\n    ...t?.advanced,\n  }\n}\n\n/** The melt item is architecturally different: nothing registers with the\n *  engine — the group's ImageMeltLayer paints the pair. Hooks order demands\n *  its own component. */\nfunction MeltItem({\n  melt,\n  children,\n}: {\n  melt?: ImageMeltOptions & { src?: string }\n  children?: ReactNode\n}) {\n  const { imageMelt } = useGooeyContext()\n  const { src, ...tuning } = melt ?? {}\n  return (\n    <ImageMeltItem src={src} opts={{ ...IMAGE_MELT_DEFAULTS, ...tuning }} registry={imageMelt}>\n      {children}\n    </ImageMeltItem>\n  )\n}\n\nexport function LiquidItem(props: LiquidItemProps) {\n  const { effect = 'morph', morph, move, bend, melt, dissolve, observe, ...rest } = props\n\n  if (effect === 'melt') {\n    return <MeltItem melt={melt}>{rest.children}</MeltItem>\n  }\n\n  if (effect === 'bend') {\n    return <GooeyItem {...rest} observe effect=\"move\" move={mapBend(bend)} />\n  }\n\n  // `dissolve` is positioned as orthogonal to `effect`, but the melt is drawn\n  // from the element's MEASURED rect while move's liquid deliberately lags on\n  // a spring — the melt would sit on the element with the surface trailing\n  // behind it. Refuse loudly rather than ship the mismatch; lifting this means\n  // feeding writeBlend the sprung position.\n  if (effect === 'move') {\n    if (process.env.NODE_ENV !== 'production' && dissolve !== undefined && dissolve !== false) {\n      console.warn(\n        '[liquid-gooey] `dissolve` is ignored with effect=\"move\": the melt ' +\n          'follows the element while the liquid lags on its spring, so the two ' +\n          'would visibly disagree. Use it on a morph item.',\n      )\n    }\n    return <GooeyItem {...rest} observe effect=\"move\" move={mapMove(move)} />\n  }\n\n  const adv = morph?.advanced\n  const shape = !!morph?.shape\n  const wantsDissolve = dissolve !== undefined && dissolve !== false\n  const contactBlur = wantsDissolve\n    ? typeof dissolve === 'object'\n      ? { ...mapDissolve(true), ...dissolve }\n      : mapDissolve(dissolve!)\n    : undefined\n  const evolve = shape ? { ...mapMorphSprings(morph), ...adv?.evolve } : undefined\n\n  return (\n    <GooeyItem\n      {...rest}\n      observe={observe || shape || !!contactBlur || undefined}\n      effect={shape ? 'evolve' : undefined}\n      evolve={evolve}\n      contactBlur={contactBlur}\n      blobInset={adv?.blobInset}\n      bridgeGrow={adv?.bridgeGrow}\n    />\n  )\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/GooeyItem.tsx",
          "target": "@components/effects/liquid-gooey/upstream/GooeyItem.tsx",
          "type": "registry:component",
          "content": "import {\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n  type CSSProperties,\n  type ReactNode,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { useGooeyContext, type GooeyContextValue } from './context'\nimport {\n  measureRadius,\n  normalizeRadius,\n  offsetTo,\n  roundedRectPath,\n  type BlobBox,\n  type CornerRadii,\n} from './geometry'\nimport { useIsoLayoutEffect, useReducedMotion } from './hooks'\nimport { EVOLVE_DEFAULTS, MOVE_DEFAULTS, type EvolveOptions, type MoveOptions } from './observer'\nimport { easingFunction, resolveTransition, type Transition } from './spring'\n\nexport type GooeyEffect = 'morph' | 'evolve' | 'move'\n\n/** Full tuning surface of the contact melt (\"dissolve\"). All values optional —\n *  the defaults are the library's tuned look. */\nexport interface DissolveOptions {\n  /** Melt blur in px. Default 8. */\n  blur?: number\n  /** Displacement strength of the liquid warp. Default 26. */\n  warp?: number\n  /** Magnetic drift toward the contact, px. Default 4. */\n  pull?: number\n  /** Distance where melting starts (defaults from the group's goo blur). */\n  range?: number\n  /** Size of the melt zone around the contact, px. */\n  zone?: number\n  /** 0..1 — two-liquid mixing: erodes the melted copy into tendrils so the\n   *  liquid behind shows through the gaps. Default 0.7 when dissolving. */\n  mix?: number\n  /** Px the melt is drawn toward the neighbour's centre (flow gravity). */\n  gravity?: number\n  /** 0..1 — how pointy that flow tapers toward the neighbour. */\n  taper?: number\n  /** Noise frequency multiplier: <1 broad swirls, >1 fine veins. */\n  warpFreq?: number\n  /** Px/s the noise field drifts so the liquid churns. 0 = static. */\n  flowSpeed?: number\n  /** 'fractalNoise' (soft billows) or 'turbulence' (veinier). */\n  warpStyle?: 'fractalNoise' | 'turbulence'\n  /** Noise octaves; higher = finer swirls. */\n  detail?: number\n  /** While false the melt fades out over `releaseMs`, regardless of\n   *  proximity. */\n  active?: boolean\n  /** Structural release time when `active` goes false, ms. */\n  releaseMs?: number\n  /** Ms the melt takes to evaporate (opacity -> 0), independent of\n   *  `releaseMs`. Defaults to `releaseMs`. */\n  fadeMs?: number\n  /** 0..1 — overall dissolve intensity, independent of proximity: caps how\n   *  far the melt can develop even at full contact (scales warp/blur/\n   *  gravity/mix and the hole depth together). Default 1. */\n  strength?: number\n  /** How deep this piece may sink into its neighbour before the melt is fully\n   *  gone, as a fraction of the smaller body (1 = completely engulfed).\n   *  Melting is a surface event — once a piece is well inside the other there\n   *  is no seam left to mix at, so the melt recedes and the content resolves\n   *  back to crisp. Default 0.8; raise toward (or past) 1 to keep melting\n   *  while deeply overlapped. */\n  sink?: number\n  /** What the liquid is made of. 'liquid' (default): the group fill — white\n   *  surface goo with imagery melted over it. 'image': the liquid body IS the\n   *  image, so the neck between two items blends both images' colours. */\n  surface?: 'liquid' | 'image'\n  /** Blur (px) of the seam-blend layer — the imagery painted once more\n   *  through a plain heavy blur at the contact, half opacity per side, so\n   *  the seam shows the two pictures' colours literally averaged. Defaults\n   *  to 1.6x `blur`; 0 disables. */\n  seamBlur?: number\n}\n\nexport interface GooeyItemProps {\n  /** Liquid behavior of this piece:\n   *  - 'morph' (default): merges gooily with touching neighbours.\n   *  - 'evolve': the surface springs behind size/shape changes and settles\n   *    like jelly.\n   *  - 'move': the surface lags a moving element and stretches with velocity —\n   *    liquid rubber (great for dragged things).\n   *  Combine with an array. Anything beyond 'morph' runs on the measurement\n   *  engine, so it implies observe mode. */\n  effect?: GooeyEffect | GooeyEffect[]\n  /** Tuning for effect=\"evolve\": springs for mass / size / corner radius,\n   *  content cross-blur, and droplet roundness. See EvolveOptions. */\n  evolve?: EvolveOptions\n  /** Tuning for effect=\"move\": trail spring, velocity stretch, tail size. */\n  move?: MoveOptions\n  /** Mirrored mode: translation applied to both the wrapper and its blob. */\n  x?: number\n  y?: number\n  scale?: number\n  /** Mirrored mode: spring preset/config or `{ duration, ease }`. Default 'smooth'. */\n  transition?: Transition\n  /** Mirrored mode: transition delay in ms (stagger). Default 0. */\n  delay?: number\n  /** Observe mode: you animate the child however you like (Framer Motion, GSAP,\n   *  CSS); the blob follows its rendered rect. `x/y/scale` are ignored. */\n  observe?: boolean\n  /** Observe mode: liquid-melt the item's imagery at the point where it\n   *  touches a neighbour — a turbulence-displacement warp bends the image and\n   *  its edge like two materials merging, ramping in as the goo bridge forms.\n   *  `blur` is the melt blur in px (default 8), `warp` the displacement\n   *  strength (default 26), `pull` the magnetic drift toward the contact in px\n   *  (default 4), `range` the distance where melting starts (defaults from the\n   *  group's goo blur). Text is never melted. */\n  contactBlur?: boolean | DissolveOptions\n  /** Override the measured border-radius for the blob (px). */\n  radius?: number | CornerRadii\n  /** Observe mode: shrink the blob by this many px on every side, so an opaque\n   *  element (e.g. a round photo) fully covers its own liquid — white then\n   *  only appears as the merge bridge. */\n  blobInset?: number\n  /** Observe mode: px the blob swells back out (beyond blobInset) as the item\n   *  nears a neighbour — the element visibly grows a liquid coat that necks\n   *  into the other surface. */\n  bridgeGrow?: number\n  className?: string\n  style?: CSSProperties\n  children?: ReactNode\n}\n\nfunction toEffects(effect: GooeyEffect | GooeyEffect[] | undefined): GooeyEffect[] {\n  return Array.isArray(effect) ? effect : effect ? [effect] : []\n}\n\nexport function GooeyItem(props: GooeyItemProps) {\n  const ctx = useGooeyContext()\n  const needsEngine = props.observe || toEffects(props.effect).some(e => e !== 'morph')\n  return needsEngine ? (\n    <ObservedItem {...props} ctx={ctx} />\n  ) : (\n    <MirroredItem {...props} ctx={ctx} />\n  )\n}\n\ntype Internal = GooeyItemProps & { ctx: GooeyContextValue }\n\nfunction transitionKey(t: Transition | undefined): string {\n  return typeof t === 'string' ? t : JSON.stringify(t ?? null)\n}\n\nfunction sameBox(a: BlobBox | null, b: BlobBox): boolean {\n  return (\n    !!a &&\n    a.x === b.x &&\n    a.y === b.y &&\n    a.w === b.w &&\n    a.h === b.h &&\n    a.r.every((v, i) => v === b.r[i])\n  )\n}\n\nfunction MirroredItem({\n  x = 0,\n  y = 0,\n  scale = 1,\n  transition = 'smooth',\n  delay = 0,\n  radius,\n  className,\n  style,\n  children,\n  ctx,\n}: Internal) {\n  const wrapRef = useRef<HTMLDivElement | null>(null)\n  const blobRef = useRef<SVGGraphicsElement | null>(null)\n  const [box, setBox] = useState<BlobBox | null>(null)\n  const reduced = useReducedMotion()\n\n  const tKey = transitionKey(transition)\n  const { duration, easing } = useMemo(\n    () => resolveTransition(transition, reduced),\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [tKey, reduced],\n  )\n\n  const radiusKey = radius == null ? '' : JSON.stringify(radius)\n  useIsoLayoutEffect(() => {\n    const el = wrapRef.current\n    const group = ctx.getGroup()\n    if (!el || !group) return\n    const measure = () => {\n      const base = offsetTo(el, group)\n      const w = el.offsetWidth\n      const h = el.offsetHeight\n      const target = (el.firstElementChild as HTMLElement | null) ?? el\n      const r: CornerRadii =\n        radius != null ? normalizeRadius(radius) : measureRadius(target, w, h)\n      const next: BlobBox = { x: base.x, y: base.y, w, h, r }\n      setBox(prev => (sameBox(prev, next) ? prev : next))\n    }\n    measure()\n    const ro = new ResizeObserver(measure)\n    ro.observe(el)\n    ro.observe(group)\n    return () => ro.disconnect()\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [ctx, radiusKey])\n\n  // Content and blob are animated by ONE JS clock — no CSS transition on the\n  // wrapper. A compositor transition keeps playing through a main-thread\n  // stall while the blob (always written from JS) freezes; under Safari's\n  // SVG-filter load that read as icons and photos sailing away from their own\n  // liquid. With both written in the same rAF tick from the same easing\n  // curve, they can only ever move together: a stall holds the whole\n  // ensemble, which reads as a hitch, never a tear. The curve is identical to\n  // the CSS one (same duration/easing via easingFunction), so browsers that\n  // never stall render exactly what they did before.\n  const cur = useRef<{ x: number; y: number; s: number } | null>(null)\n  const writeTransform = (px: number, py: number, ps: number) => {\n    const t = `translate(${px}px, ${py}px)` + (ps !== 1 ? ` scale(${ps})` : '')\n    if (wrapRef.current) wrapRef.current.style.transform = t\n    if (blobRef.current) blobRef.current.style.transform = t\n  }\n  useIsoLayoutEffect(() => {\n    const from = cur.current\n    if (\n      !from ||\n      duration <= 0 ||\n      (from.x === x && from.y === y && from.s === scale)\n    ) {\n      cur.current = { x, y, s: scale }\n      writeTransform(x, y, scale)\n      return\n    }\n    // Retarget like a CSS transition: from the currently rendered value, full\n    // duration. `delay` holds at the start value first (stagger).\n    const f = { ...from }\n    const ease = easingFunction(easing)\n    const start = performance.now() + delay\n    let raf = 0\n    const tick = (now: number) => {\n      const p = Math.min(1, Math.max(0, (now - start) / duration))\n      const e = ease(p)\n      const cx = f.x + (x - f.x) * e\n      const cy = f.y + (y - f.y) * e\n      const cs = f.s + (scale - f.s) * e\n      cur.current = { x: cx, y: cy, s: cs }\n      writeTransform(cx, cy, cs)\n      if (p < 1) raf = requestAnimationFrame(tick)\n    }\n    raf = requestAnimationFrame(tick)\n    return () => cancelAnimationFrame(raf)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [x, y, scale, duration, easing, delay])\n\n  return (\n    <>\n      <div\n        ref={wrapRef}\n        className={className}\n        style={{\n          display: 'inline-block',\n          ...style,\n          // `transform` is owned imperatively (see above) — React must never\n          // render it, or a re-render mid-flight would snap to the target.\n          willChange: 'transform',\n        }}\n      >\n        {children}\n      </div>\n      {ctx.portal &&\n        box &&\n        createPortal(\n          renderBlob(\n            box,\n            {\n              transformBox: 'fill-box',\n              transformOrigin: 'center',\n              willChange: 'transform',\n            },\n            el => {\n              blobRef.current = el\n              // The blob (re)mounts whenever the measured box changes; catch\n              // it up to the currently rendered value immediately.\n              if (el) {\n                const c = cur.current ?? { x, y, s: scale }\n                el.style.transform =\n                  `translate(${c.x}px, ${c.y}px)` + (c.s !== 1 ? ` scale(${c.s})` : '')\n              }\n            },\n          ),\n          ctx.portal,\n        )}\n    </>\n  )\n}\n\nfunction renderBlob(\n  box: BlobBox,\n  style: CSSProperties,\n  setRef: (el: SVGGraphicsElement | null) => void,\n) {\n  const [tl, tr, br, bl] = box.r\n  const uniform = tl === tr && tr === br && br === bl\n  if (uniform) {\n    // Clamp to min(w,h)/2: SVG clamps rx and ry independently, so a large\n    // radius on a wide short box (the `border-radius: 999px` pill idiom)\n    // would degenerate into an ellipse instead of a pill.\n    const rx = Math.max(0, Math.min(tl, Math.min(box.w, box.h) / 2))\n    return (\n      <rect\n        ref={setRef}\n        x={box.x}\n        y={box.y}\n        width={box.w}\n        height={box.h}\n        rx={rx}\n        style={style}\n      />\n    )\n  }\n  return (\n    <path\n      ref={setRef}\n      d={roundedRectPath(box.x, box.y, box.w, box.h, box.r)}\n      style={style}\n    />\n  )\n}\n\nfunction ObservedItem({\n  radius,\n  blobInset,\n  bridgeGrow,\n  contactBlur,\n  effect,\n  evolve,\n  move,\n  className,\n  style,\n  children,\n  ctx,\n}: Internal) {\n  const hostRef = useRef<HTMLSpanElement | null>(null)\n  const blobRef = useRef<SVGRectElement | null>(null)\n  const meltRef = useRef<SVGGElement | null>(null)\n  const blendRef = useRef<{\n    active?: boolean\n    releaseMs?: number\n    fadeMs?: number\n    strength?: number\n    sink?: number\n    seamBlur?: number\n  } | null>(null)\n\n  const opts = typeof contactBlur === 'object' ? contactBlur : {}\n  const blendBlur = opts.blur ?? 8\n  const blendWarp = opts.warp ?? 26\n  const blendPull = opts.pull ?? 4\n  const blendRange = opts.range\n  const blendZone = opts.zone\n  const blendMix = opts.mix ?? 0\n  const blendGravity = opts.gravity ?? 60\n  const blendTaper = opts.taper ?? 1\n  const blendWarpFreq = opts.warpFreq ?? 1.7\n  const blendFlowSpeed = opts.flowSpeed ?? 22\n  const blendWarpStyle = opts.warpStyle ?? 'fractalNoise'\n  const blendDetail = opts.detail ?? 2\n  const blendActive = opts.active !== false\n  const blendRelease = opts.releaseMs ?? 240\n  const blendFade = opts.fadeMs\n  const blendStrength = opts.strength ?? 1\n  // Left undefined when unset so the engine owns the default in one place.\n  const blendSink = opts.sink\n  const blendSurface = opts.surface\n  const blendSeamBlur = opts.seamBlur\n\n  const effects = toEffects(effect)\n  const dynamics = {\n    evolve: effects.includes('evolve'),\n    move: effects.includes('move'),\n    evolveOpts: { ...EVOLVE_DEFAULTS, ...evolve },\n    moveOpts: { ...MOVE_DEFAULTS, ...move },\n  }\n  const hasDynamics = dynamics.evolve || dynamics.move\n\n  const radiusKey = radius == null ? '' : JSON.stringify(radius)\n  // `active` is intentionally NOT in the key: it changes every drag and must\n  // not tear down the melt structure — the engine reads it live.\n  const blendKey = contactBlur\n    ? `${blendBlur}/${blendWarp}/${blendPull}/${blendRange ?? 'auto'}/${blendZone ?? 'auto'}/${blendMix}/${blendGravity}/${blendTaper}/${blendWarpFreq}/${blendFlowSpeed}/${blendWarpStyle}/${blendDetail}/${blendSurface ?? 'liquid'}/${(blendSeamBlur ?? 1) > 0 ? 'seam' : 'noseam'}`\n    : ''\n  const effectKey =\n    effects.join(',') +\n    (dynamics.evolve ? JSON.stringify(dynamics.evolveOpts) : '') +\n    (dynamics.move ? JSON.stringify(dynamics.moveOpts) : '')\n  useIsoLayoutEffect(() => {\n    const host = hostRef.current\n    const blob = blobRef.current\n    const target = (host?.firstElementChild as HTMLElement | null) ?? null\n    if (!target || !blob) return\n    const blend =\n      contactBlur && meltRef.current\n        ? {\n            host: meltRef.current,\n            blur: blendBlur,\n            warp: blendWarp,\n            pull: blendPull,\n            range: blendRange,\n            zone: blendZone,\n            mix: blendMix,\n            gravity: blendGravity,\n            taper: blendTaper,\n            warpFreq: blendWarpFreq,\n            flowSpeed: blendFlowSpeed,\n            warpStyle: blendWarpStyle,\n            detail: blendDetail,\n            active: blendActive,\n            releaseMs: blendRelease,\n            fadeMs: blendFade,\n            strength: blendStrength,\n            sink: blendSink,\n            surface: blendSurface,\n            seamBlur: blendSeamBlur,\n          }\n        : undefined\n    blendRef.current = blend ?? null\n    return ctx.engine.add({\n      target,\n      blob,\n      radius: radius == null ? undefined : normalizeRadius(radius)[0],\n      blobInset,\n      bridgeGrow,\n      blend,\n      dynamics: hasDynamics ? dynamics : undefined,\n    })\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [ctx, radiusKey, blendKey, effectKey, blobInset, bridgeGrow])\n\n  // `active` / `releaseMs` / `fadeMs` / `strength` / `sink` are pushed\n  // straight into the live config so a drag release (or a strength slider)\n  // updates the melt without rebuilding its SVG structure.\n  useEffect(() => {\n    if (!blendRef.current) return\n    blendRef.current.active = blendActive\n    blendRef.current.releaseMs = blendRelease\n    blendRef.current.fadeMs = blendFade\n    blendRef.current.strength = blendStrength\n    blendRef.current.sink = blendSink\n    blendRef.current.seamBlur = blendSeamBlur\n    ctx.engine.wake()\n  }, [ctx, blendActive, blendRelease, blendFade, blendStrength, blendSink, blendSeamBlur])\n\n  return (\n    <>\n      <span ref={hostRef} className={className} style={{ display: 'contents', ...style }}>\n        {children}\n      </span>\n      {ctx.portal &&\n        createPortal(\n          <rect\n            ref={blobRef}\n            x={0}\n            y={0}\n            width={0}\n            height={0}\n            style={{\n              willChange: 'transform',\n              // Dynamics scale (stretch / squash) about the blob's own centre.\n              transformBox: 'fill-box',\n              transformOrigin: 'center',\n            }}\n          />,\n          ctx.portal,\n        )}\n      {contactBlur !== undefined &&\n        contactBlur !== false &&\n        ctx.meltPortal &&\n        createPortal(<g ref={meltRef} opacity={0} />, ctx.meltPortal)}\n    </>\n  )\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/upstream/spring.ts",
          "target": "@components/effects/liquid-gooey/upstream/spring.ts",
          "type": "registry:component",
          "content": "/** Spring-driven easing, compiled to CSS `linear()` so the DOM wrapper and the\n *  SVG blob can share one GPU-composited transition — the core of zero-lag\n *  mirrored sync. Falls back to cubic-bezier where `linear()` is unsupported. */\n\nexport interface SpringConfig {\n  stiffness?: number\n  damping?: number\n  mass?: number\n}\n\nexport type TransitionPreset = 'snappy' | 'smooth' | 'bouncy'\n\nexport type Transition =\n  | TransitionPreset\n  | SpringConfig\n  | { duration: number; ease?: string }\n\nexport interface ResolvedTransition {\n  /** ms */\n  duration: number\n  /** CSS timing function */\n  easing: string\n}\n\nexport const presets: Record<TransitionPreset, Required<SpringConfig>> = {\n  snappy: { stiffness: 480, damping: 34, mass: 1 },\n  smooth: { stiffness: 190, damping: 26, mass: 1 },\n  bouncy: { stiffness: 320, damping: 17, mass: 1 },\n}\n\nconst DT = 1 / 240\n\nfunction simulate(c: Required<SpringConfig>) {\n  let x = 0\n  let v = 0\n  let t = 0\n  let settledAt = -1\n  let max = 0\n  const xs: number[] = [0]\n  while (t < 10) {\n    const a = (-c.stiffness * (x - 1) - c.damping * v) / c.mass\n    v += a * DT\n    x += v * DT\n    t += DT\n    xs.push(x)\n    if (x > max) max = x\n    if (Math.abs(x - 1) < 0.001 && Math.abs(v) < 0.02) {\n      if (settledAt < 0) settledAt = t\n      if (t - settledAt >= 0.064) break\n    } else {\n      settledAt = -1\n    }\n  }\n  const duration = settledAt > 0 ? settledAt : t\n  const n = Math.round(Math.min(120, Math.max(24, duration * 90)))\n  const lastIdx = Math.min(xs.length - 1, duration / DT)\n  const values: number[] = []\n  for (let i = 0; i <= n; i++) {\n    const idx = Math.min(xs.length - 1, Math.round((i / n) * lastIdx))\n    values.push(Math.round(xs[idx] * 1e4) / 1e4)\n  }\n  values[values.length - 1] = 1\n  return { duration, values, overshoots: max > 1.001 }\n}\n\nlet linearOK: boolean | null = null\nfunction supportsLinear(): boolean {\n  if (linearOK == null) {\n    linearOK =\n      typeof CSS !== 'undefined' &&\n      typeof CSS.supports === 'function' &&\n      CSS.supports('transition-timing-function', 'linear(0, 1)')\n  }\n  return linearOK\n}\n\nconst cache = new Map<string, ResolvedTransition>()\n\n/** Evaluate a CSS timing function in JS: `linear(...)` sample lists (what the\n *  spring compiler emits), `cubic-bezier(...)`, and the keyword curves.\n *\n *  Exists so item motion can be driven from the SAME rAF that writes the\n *  liquid silhouette instead of a CSS transition. A compositor-run transition\n *  keeps playing through a main-thread stall while the silhouette (written\n *  from JS) freezes — in Safari, where SVG-filter work makes such stalls\n *  routine, the content visibly sailed away from its own liquid. One shared\n *  clock makes the tear impossible: a stall now holds BOTH still. */\nconst evalCache = new Map<string, (t: number) => number>()\nexport function easingFunction(spec: string): (t: number) => number {\n  let fn = evalCache.get(spec)\n  if (fn) return fn\n  const lin = /^linear\\(([^)]+)\\)$/.exec(spec.trim())\n  const bez = /^cubic-bezier\\(([^)]+)\\)$/.exec(spec.trim())\n  if (lin) {\n    // Our compiled lists carry no percentages: stops are evenly spaced.\n    const values = lin[1].split(',').map(Number)\n    fn = (t: number) => {\n      if (t <= 0) return values[0]\n      if (t >= 1) return values[values.length - 1]\n      const f = t * (values.length - 1)\n      const i = Math.floor(f)\n      return values[i] + (values[i + 1] - values[i]) * (f - i)\n    }\n  } else if (bez) {\n    const [x1, y1, x2, y2] = bez[1].split(',').map(Number)\n    fn = (t: number) => {\n      if (t <= 0) return 0\n      if (t >= 1) return 1\n      let lo = 0\n      let hi = 1\n      for (let i = 0; i < 24; i++) {\n        const mid = (lo + hi) / 2\n        const xm = 3 * mid * (1 - mid) * (1 - mid) * x1 + 3 * mid * mid * (1 - mid) * x2 + mid ** 3\n        if (xm < t) lo = mid\n        else hi = mid\n      }\n      const u = (lo + hi) / 2\n      return 3 * u * (1 - u) * (1 - u) * y1 + 3 * u * u * (1 - u) * y2 + u ** 3\n    }\n  } else if (spec === 'ease') {\n    fn = easingFunction('cubic-bezier(0.25, 0.1, 0.25, 1)')\n  } else if (spec === 'ease-in') {\n    fn = easingFunction('cubic-bezier(0.42, 0, 1, 1)')\n  } else if (spec === 'ease-out') {\n    fn = easingFunction('cubic-bezier(0, 0, 0.58, 1)')\n  } else if (spec === 'ease-in-out') {\n    fn = easingFunction('cubic-bezier(0.42, 0, 0.58, 1)')\n  } else {\n    fn = (t: number) => Math.min(1, Math.max(0, t))\n  }\n  evalCache.set(spec, fn)\n  return fn\n}\n\nexport function resolveTransition(\n  t: Transition | undefined,\n  reducedMotion = false,\n): ResolvedTransition {\n  if (reducedMotion) return { duration: 0, easing: 'linear' }\n  const cfg = t ?? 'smooth'\n  if (typeof cfg === 'object' && 'duration' in cfg) {\n    return {\n      duration: cfg.duration,\n      easing: cfg.ease ?? 'cubic-bezier(0.22, 1, 0.36, 1)',\n    }\n  }\n  const spring: Required<SpringConfig> =\n    typeof cfg === 'string'\n      ? presets[cfg]\n      : { stiffness: 300, damping: 24, mass: 1, ...cfg }\n  const key = `${spring.stiffness}/${spring.damping}/${spring.mass}/${supportsLinear()}`\n  let resolved = cache.get(key)\n  if (!resolved) {\n    const sim = simulate(spring)\n    resolved = {\n      duration: Math.round(sim.duration * 1000),\n      easing: supportsLinear()\n        ? `linear(${sim.values.join(', ')})`\n        : sim.overshoots\n          ? 'cubic-bezier(0.34, 1.56, 0.64, 1)'\n          : 'cubic-bezier(0.22, 1, 0.36, 1)',\n    }\n    cache.set(key, resolved)\n  }\n  return resolved\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/effects/liquid-gooey/LICENSE",
          "target": "@components/effects/liquid-gooey/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Jakub\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/effects/liquid-gooey/SOURCE.json",
          "target": "@components/effects/liquid-gooey/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"liquid-gooey\",\n  \"repository\": \"https://github.com/Jakubantalik/Libraries.dev\",\n  \"revision\": \"422180dd7a5ac646c85deedc65500c4a74339127\",\n  \"packageVersion\": \"0.2.1\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Jakub\",\n  \"copiedPath\": \"upstream/\",\n  \"copiedFiles\": [\n    \"packages/liquid-gooey/src/Gooey.tsx\",\n    \"packages/liquid-gooey/src/GooeyItem.tsx\",\n    \"packages/liquid-gooey/src/LiquidItem.tsx\",\n    \"packages/liquid-gooey/src/context.ts\",\n    \"packages/liquid-gooey/src/filter.tsx\",\n    \"packages/liquid-gooey/src/geometry.ts\",\n    \"packages/liquid-gooey/src/hooks.ts\",\n    \"packages/liquid-gooey/src/imageMelt.tsx\",\n    \"packages/liquid-gooey/src/index.ts\",\n    \"packages/liquid-gooey/src/observer.ts\",\n    \"packages/liquid-gooey/src/shadow.ts\",\n    \"packages/liquid-gooey/src/spring.ts\"\n  ],\n  \"relationship\": \"Source-faithful copy of the pinned public React package. The top-level client facade directly re-exports the upstream Liquid API and its Morph, Move, Melt, Bend, dissolve, tuning, and advanced types.\"\n}\n"
        }
      ],
      "categories": [
        "Libraries.dev"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "metal-fx-v1",
      "type": "registry:block",
      "title": "Metal Fx V1",
      "description": "metal fx v1",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/effects/metal-fx-v1.tsx",
          "target": "@components/effects/metal-fx-v1.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nexport * from \"./metal-fx-v1/upstream\"\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/index.ts",
          "target": "@components/effects/metal-fx-v1/upstream/index.ts",
          "type": "registry:component",
          "content": "export { MetalFx } from './MetalFx';\n\nexport type {\n  MetalFxProps,\n  MetalFxVariant,\n  MetalFxTheme,\n  MetalFxPreset,\n} from './types';\n\n// Power-user surface: expose the engine primitives so consumers building\n// non-React integrations can drive the same renderer.\nexport {\n  PRESETS,\n  hexToRgb,\n  type Preset,\n  type PresetMode,\n  type PresetName,\n  type PresetTheme,\n} from './engine/presets';\n\nexport {\n  createInstance,\n  destroyInstance,\n  updateInstance,\n  setSharedPreset,\n  pauseShared,\n  resumeShared,\n} from './engine/renderer/loop';\n\nexport type { MetalFxInstance } from './engine/renderer/core';\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/MetalFx.tsx",
          "target": "@components/effects/metal-fx-v1/upstream/MetalFx.tsx",
          "type": "registry:component",
          "content": "import {\n  forwardRef,\n  useEffect,\n  useImperativeHandle,\n  useLayoutEffect,\n  useMemo,\n  useRef,\n  useState,\n  type CSSProperties,\n} from 'react';\nimport type { MetalFxInstance } from './engine/renderer/core';\nimport {\n  createInstance,\n  destroyInstance,\n  registerGlowInstance,\n  setGlowCallback,\n  setInstanceVisible,\n  setSharedPreset,\n  unregisterGlowInstance,\n  updateInstance,\n} from './engine/renderer/loop';\nimport { injectGlow, updateGlow } from './engine/glow/glow';\nimport { addReflectionTarget, removeReflectionTarget } from './engine/reflection/paint';\nimport { scheduleReflectionPaint } from './engine/reflection/reflectionScheduler';\nimport { ensureStylesInjected } from './styles';\nimport type { MetalFxProps, MetalFxTheme } from './types';\n\n// Runs at module scope so styles exist before the first component render,\n// even in SSR-hydration scenarios where effects haven't fired yet.\nensureStylesInjected();\n\n// Hoisted to avoid allocating new objects on every render.\nconst CANVAS_STYLE: CSSProperties = { position: 'absolute', inset: 0, width: '100%', height: '100%' };\nconst INNER_STYLE: CSSProperties = { position: 'absolute', inset: 3 };\nconst GLOW_HOST_STYLE: CSSProperties = { position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 3, borderRadius: 'inherit' };\n\n// Maps each live instance to its SVG glow handles and a theme ref.\n// Keyed by instance (not component) because the same component can be\n// remounted with a new instance after shape/glowEnabled changes.\nconst glowHandlesMap = new Map<MetalFxInstance, { handles: ReturnType<typeof injectGlow>; themeRef: { current: 'dark' | 'light' } }>();\n\n// Bridge between the shared animation loop and per-instance glow SVGs.\n// The loop module doesn't import glow directly — it invokes this callback\n// for one queued instance per frame (round-robin), keeping render work\n// proportional to frame budget regardless of instance count.\nsetGlowCallback((inst, nowMs) => {\n  const entry = glowHandlesMap.get(inst);\n  if (!entry) return;\n  updateGlow(entry.handles, inst, nowMs, inst.opacityMul, entry.themeRef.current);\n});\n\n/**\n * Resolves 'auto' theme to 'dark' | 'light' and keeps it in sync with\n * the OS preference via matchMedia.\n *\n * The useState initialiser runs synchronously so the resolved value is\n * available on the first render (no flash). The useEffect then attaches\n * the MQL listener and calls update() immediately to handle the case\n * where the OS preference changed between SSR and hydration.\n */\nfunction useResolvedTheme(theme: MetalFxTheme): 'dark' | 'light' {\n  const [resolved, setResolved] = useState<'dark' | 'light'>(() => {\n    if (theme !== 'auto') return theme;\n    if (typeof window === 'undefined' || !window.matchMedia) return 'dark';\n    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n  });\n\n  useEffect(() => {\n    if (theme !== 'auto') { setResolved(theme); return; }\n    if (typeof window === 'undefined' || !window.matchMedia) return;\n    const mql = window.matchMedia('(prefers-color-scheme: dark)');\n    const update = () => setResolved(mql.matches ? 'dark' : 'light');\n    update();\n    mql.addEventListener('change', update);\n    return () => mql.removeEventListener('change', update);\n  }, [theme]);\n\n  return resolved;\n}\n\n/**\n * Wraps any element with an animated metallic ring effect driven by a\n * single shared WebGL renderer. All visible MetalFx instances on the page\n * share one offscreen GL canvas; each instance composites a cropped/scaled\n * copy of it onto its own 2D canvas with a rounded hole punched through the\n * centre.\n */\nexport const MetalFx = forwardRef<HTMLDivElement, MetalFxProps>(function MetalFx(\n  {\n    children,\n    variant = 'button',\n    preset = 'chromatic',\n    theme = 'auto',\n    strength = 1,\n    paused = false,\n    borderRadius,\n    normalizeHostStyles = true,\n    reflectionTargets,\n    disableGlow = false,\n    shaderScale,\n    ringCssPx,\n    scale = 1,\n    className,\n    style,\n    ...rest\n  },\n  forwardedRef\n) {\n  // DOM refs — rootRef/canvasRef/glowHostRef/contentRef are for direct DOM access.\n  // instanceRef/glowHandlesRef hold engine objects that survive React re-renders.\n  // themeRef lets the glow callback read the current theme without a closure\n  // over a stale value — mutated during render, never triggers a re-render.\n  // initialWrapperRadiusRef caches the CSS border-radius read at mount time so\n  // measure() can fall back to it when no explicit borderRadius prop is given.\n  const rootRef = useRef<HTMLDivElement | null>(null);\n  const canvasRef = useRef<HTMLCanvasElement | null>(null);\n  const glowHostRef = useRef<HTMLDivElement | null>(null);\n  const contentRef = useRef<HTMLDivElement | null>(null);\n  const instanceRef = useRef<MetalFxInstance | null>(null);\n  const glowHandlesRef = useRef<ReturnType<typeof injectGlow> | null>(null);\n  const themeRef = useRef<'dark' | 'light'>('dark');\n  const initialWrapperRadiusRef = useRef<number>(0);\n\n  const [ready, setReady] = useState(false);\n  const resolvedTheme = useResolvedTheme(theme);\n  // Write during render (not in an effect) so the glow callback always sees\n  // the up-to-date theme on the very next tick.\n  themeRef.current = resolvedTheme;\n  const shape: 'pill' | 'circle' = variant === 'circle' ? 'circle' : 'pill';\n  const glowEnabled = !disableGlow;\n\n  useImperativeHandle(forwardedRef, () => rootRef.current as HTMLDivElement, []);\n\n  const resolveRadius = (w: number, h: number) => {\n    // variant='circle' is the user's explicit promise that the wrapped\n    // element should render as a circle. Always pick min(w,h)/2 so the\n    // engine produces a true circle even when the child's CSS border-radius\n    // is read in a different coordinate space than the bounding rect (the\n    // exact failure mode under CSS `zoom: 2`, where getComputedStyle\n    // returns source pixels but getBoundingClientRect returns zoomed ones).\n    if (shape === 'circle') return Math.min(w, h) / 2;\n\n    const raw = typeof borderRadius === 'number'\n      ? borderRadius\n      : (() => {\n          const childEl = contentRef.current?.firstElementChild as HTMLElement | null;\n          if (childEl) {\n            const parsed = parseFloat(getComputedStyle(childEl).borderTopLeftRadius);\n            if (Number.isFinite(parsed) && parsed > 0) return parsed;\n          }\n          return initialWrapperRadiusRef.current;\n        })();\n    return Math.min(raw, Math.min(w, h) / 2);\n  };\n\n  useEffect(() => { setSharedPreset(preset, resolvedTheme); }, [preset, resolvedTheme]);\n  // `paused` is per-instance: it freezes only this instance's 2D canvas while\n  // the shared GL loop keeps running for any other unpaused instance.\n  useEffect(() => {\n    const inst = instanceRef.current;\n    if (!inst) return;\n    updateInstance(inst, { paused });\n  }, [paused]);\n\n  // Re-sync optional shader/ring/scale overrides if they change at runtime.\n  useEffect(() => {\n    const inst = instanceRef.current;\n    if (!inst) return;\n    const patch: Partial<Parameters<typeof updateInstance>[1]> = {};\n    if (shaderScale !== undefined) patch.shaderScale = shaderScale;\n    if (ringCssPx !== undefined) patch.ringCssPx = ringCssPx;\n    if (scale !== undefined) patch.scale = scale;\n    if (Object.keys(patch).length > 0) updateInstance(inst, patch);\n  }, [shaderScale, ringCssPx, scale]);\n\n  // useLayoutEffect (not useEffect) so the instance is created and the canvas\n  // is sized synchronously before the browser paints — avoids a one-frame\n  // flash of the unsized canvas.\n  // biome-ignore lint/correctness/useExhaustiveDependencies: borderRadius changes handled by separate effect\n  useLayoutEffect(() => {\n    const canvas = canvasRef.current;\n    const root = rootRef.current;\n    const glowHost = glowHostRef.current;\n    if (!canvas || !root) return;\n\n    {\n      const computed = getComputedStyle(root);\n      const parsed = parseFloat(computed.borderTopLeftRadius);\n      initialWrapperRadiusRef.current = Number.isFinite(parsed) ? parsed : 0;\n    }\n\n    const measure = () => {\n      const rect = root.getBoundingClientRect();\n      const cssWidth = Math.max(1, Math.round(rect.width));\n      const cssHeight = Math.max(1, Math.round(rect.height));\n      return { cssWidth, cssHeight, cornerRadius: resolveRadius(cssWidth, cssHeight) };\n    };\n\n    const initial = measure();\n    instanceRef.current = createInstance({\n      hostCanvas: canvas,\n      cssWidth: initial.cssWidth,\n      cssHeight: initial.cssHeight,\n      cornerRadius: initial.cornerRadius,\n      kind: shape,\n      paused,\n      shaderScale,\n      ringCssPx,\n      scale,\n      onFirstCopy: () => setReady(true),\n    });\n    root.style.setProperty('--mfx-radius', `${initial.cornerRadius}px`);\n    root.style.borderRadius = `${initial.cornerRadius}px`;\n\n    if (glowHost) {\n      glowHandlesRef.current = injectGlow(glowHost, {\n        width: initial.cssWidth,\n        height: initial.cssHeight,\n        cornerRadius: initial.cornerRadius,\n        kind: shape,\n        scale,\n      });\n    }\n\n    let resizeRaf = 0;\n    const ro = new ResizeObserver(() => {\n      if (resizeRaf !== 0) return;\n      // RAF-debounce: coalesce multiple resize events within the same frame and\n      // skip any that fire while a frame is already queued.\n      resizeRaf = requestAnimationFrame(() => {\n        resizeRaf = 0;\n        const next = measure();\n        const inst = instanceRef.current;\n        if (!inst) return;\n        updateInstance(inst, { cssWidth: next.cssWidth, cssHeight: next.cssHeight, cornerRadius: next.cornerRadius });\n        root.style.setProperty('--mfx-radius', `${next.cornerRadius}px`);\n        root.style.borderRadius = `${next.cornerRadius}px`;\n        if (glowHost) {\n          glowHost.innerHTML = '';\n          glowHandlesRef.current = injectGlow(glowHost, {\n            width: next.cssWidth, height: next.cssHeight, cornerRadius: next.cornerRadius, kind: shape, scale,\n          });\n          if (inst && glowHandlesRef.current) {\n            glowHandlesMap.set(inst, { handles: glowHandlesRef.current, themeRef });\n          }\n        }\n      });\n    });\n    ro.observe(root);\n\n    // Skip GL compositing for off-screen instances — the loop checks inst.visible\n    // before copyShaderToInstance, so hidden instances cost nothing per frame.\n    // rootMargin: 64px starts rendering slightly before the element scrolls into view.\n    let io: IntersectionObserver | null = null;\n    if (typeof IntersectionObserver !== 'undefined') {\n      io = new IntersectionObserver(\n        (entries) => { const inst = instanceRef.current; if (!inst) return; for (const e of entries) setInstanceVisible(inst, e.isIntersecting); },\n        { rootMargin: '64px' }\n      );\n      io.observe(root);\n    }\n\n    if (instanceRef.current && glowHandlesRef.current) {\n      glowHandlesMap.set(instanceRef.current, { handles: glowHandlesRef.current, themeRef });\n      registerGlowInstance(instanceRef.current);\n    }\n\n    return () => {\n      ro.disconnect();\n      io?.disconnect();\n      if (resizeRaf !== 0) cancelAnimationFrame(resizeRaf);\n      const inst = instanceRef.current;\n      if (inst) {\n        glowHandlesMap.delete(inst);\n        unregisterGlowInstance(inst);\n        destroyInstance(inst);\n      }\n      instanceRef.current = null;\n      glowHandlesRef.current = null;\n      if (glowHost) glowHost.innerHTML = '';\n    };\n  }, [shape]);\n\n  // strength=1 maps directly to a full-opacity composite (opacityMul=1) for\n  // every variant. Per-preset toning lives in `shaderOpacity` inside each\n  // PresetMode, not here, so buttons and circles share the same headroom.\n  useEffect(() => {\n    const inst = instanceRef.current;\n    if (!inst) return;\n    updateInstance(inst, { opacityMul: Math.max(0, Math.min(1, strength)) });\n  }, [strength, variant]);\n\n  // onAfterFrame is wired here rather than at createInstance time so instances\n  // without reflectionTargets never schedule the reflection RAF.\n  // Reflections are dark-mode only — no DOM work in light mode.\n  useEffect(() => {\n    const inst = instanceRef.current;\n    const root = rootRef.current;\n    if (!inst || !root || !reflectionTargets || resolvedTheme !== 'dark') return;\n    inst.onAfterFrame = scheduleReflectionPaint;\n    const live = reflectionTargets.flatMap((r) => (r.current ? [r.current] : []));\n    for (const el of live) addReflectionTarget(el, inst, root);\n    return () => {\n      inst.onAfterFrame = undefined;\n      for (const el of live) removeReflectionTarget(el);\n    };\n  }, [reflectionTargets, resolvedTheme]);\n\n  // Separate from the main lifecycle effect so borderRadius / variant / theme\n  // changes re-sync the radius without destroying and recreating the instance.\n  // biome-ignore covers shape, which is derived from variant and identical to\n  // inst.kind — adding it would be correct but redundant.\n  // biome-ignore lint/correctness/useExhaustiveDependencies: trigger deps for radius re-sync\n  useEffect(() => {\n    const root = rootRef.current;\n    const inst = instanceRef.current;\n    if (!root || !inst) return;\n    const cornerRadius = resolveRadius(inst.cssWidth, inst.cssHeight);\n    updateInstance(inst, { cornerRadius });\n    root.style.setProperty('--mfx-radius', `${cornerRadius}px`);\n    root.style.borderRadius = `${cornerRadius}px`;\n  }, [borderRadius, resolvedTheme, variant, shape]);\n\n  // --mfx-strength is consumed by downstream CSS (e.g. content opacity rules).\n  // Spread style last so consumer inline styles can still override other props.\n  const wrapperStyle = useMemo<CSSProperties>(\n    () => ({\n      ...style,\n      ['--mfx-strength' as string]: String(Math.min(1, Math.max(0, strength))),\n      opacity: ready ? 1 : 0,\n      visibility: ready ? 'visible' : 'hidden',\n      transition: ready ? 'opacity 0.15s ease-out' : 'none',\n    }),\n    [style, strength, ready]\n  );\n\n  return (\n    <div\n      {...rest}\n      ref={rootRef}\n      className={className ? `metal-fx-root ${className}` : 'metal-fx-root'}\n      data-variant={variant}\n      data-shape={shape}\n      data-theme={resolvedTheme}\n      data-paused={paused ? 'true' : undefined}\n      data-normalize={normalizeHostStyles ? 'true' : 'false'}\n      style={wrapperStyle}\n    >\n      <canvas ref={canvasRef} className=\"metal-fx-canvas\" style={CANVAS_STYLE} />\n      <div className=\"metal-fx-inner\" aria-hidden=\"true\" style={INNER_STYLE} />\n      <div ref={glowHostRef} aria-hidden=\"true\" style={{ ...GLOW_HOST_STYLE, display: glowEnabled ? undefined : 'none' }} />\n      <div ref={contentRef} className=\"metal-fx-content\">{children}</div>\n    </div>\n  );\n});\n\nMetalFx.displayName = 'MetalFx';\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/renderer/core.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/renderer/core.ts",
          "type": "registry:component",
          "content": "/**\n * Shared WebGL renderer — one offscreen GL canvas drives all MetalFx instances.\n *\n * Architecture:\n *   1. A single offscreen GL canvas renders the plasma shader.\n *   2. Each instance owns a visible 2D canvas that receives a cropped/scaled\n *      copy of the GL output with an inner \"hole punch\" mask (ring effect).\n *   3. Glow sampling reads from a shared pixel buffer (gl.readPixels) that is\n *      refreshed at most every 200ms to avoid GPU pipeline flushes on every frame.\n *   4. The animation loop is capped at ~30fps — the blur + slow plasma motion\n *      makes higher rates imperceptible.\n */\nimport { CANONICAL_GL_SIZE, GL_DPR_CAP } from '../perfConfig';\nimport { PRESETS, type PresetMode } from '../presets';\nimport { compileShader, FRAG_SHADER_SRC, linkProgram, VERT_SHADER_SRC } from '../shaders';\nexport const CANONICAL_PILL_W = 140;\nexport const CANONICAL_PILL_H = 40;\nexport const PILL_SHADER_SCALE = 1.6;\nexport const CIRCLE_SHADER_SCALE = 1.3;\n\nexport interface ShaderRGB { r: number; g: number; b: number }\n\nexport interface MetalFxInstance {\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  cssWidth: number;\n  cssHeight: number;\n  cornerRadius: number;\n  kind: 'pill' | 'circle';\n  ringCssPx: number;\n  shaderScale: number;\n  opacityMul: number;\n  visible: boolean;\n  /** Per-instance freeze flag. When true the instance's 2D canvas keeps the\n   *  last copied frame; the shared GL loop continues for any other unpaused\n   *  instance. */\n  paused: boolean;\n  /** Set to true after the first successful copyShaderToInstance — so an\n   *  instance that mounts already paused still gets one frame painted before\n   *  it freezes (otherwise it would render a blank canvas). */\n  everCopied: boolean;\n  dpr: number;\n  /** Master scale multiplier for absolute-pixel internals (glow stroke\n   *  widths/blurs, reflection stroke band, etc.). 1 is the baseline. Set to\n   *  2 for a CSS-zoomed 2× hero so glow + reflection grow with the layout. */\n  scale: number;\n  onAfterFrame?: () => void;\n  /** One-shot callback fired after the very first copyShaderToInstance.\n   *  Auto-cleared by the loop so it never fires twice. */\n  onFirstCopy?: () => void;\n}\n\nexport interface SharedRenderer {\n  glCanvas: HTMLCanvasElement | OffscreenCanvas;\n  gl: WebGLRenderingContext;\n  program: WebGLProgram;\n  buffer: WebGLBuffer;\n  uniforms: Record<string, WebGLUniformLocation | null>;\n  preset: PresetMode;\n  presetDirty: boolean;\n  contextLost: boolean;\n  useOffscreen: boolean;\n  frameBitmap: ImageBitmap | null;\n  startMs: number;\n  pausedMs: number;\n  pausedAtMs: number | null;\n  rafId: number;\n  dpr: number;\n  instances: Set<MetalFxInstance>;\n  frameCount: number;\n  glowQueue: MetalFxInstance[];\n  glowIdx: number;\n  glowSkip: number;\n  glowPixels: Uint8Array;\n  glowPixelsW: number;\n  glowPixelsH: number;\n}\n\nexport let SHARED: SharedRenderer | null = null;\n\n// Called by ensureSharedRenderer on first init and by the contextrestored\n// listener to rebuild GL state after the browser reclaims the context.\nlet _onContextRestored: (() => void) | null = null;\nexport function setContextRestoredCallback(cb: (() => void) | null): void {\n  _onContextRestored = cb;\n}\n\nconst UNIFORM_NAMES = [\n  'u_resolution', 'u_time',\n  'u_color1', 'u_color2', 'u_color3', 'u_color4', 'u_color5', 'u_color6', 'u_color7',\n  'u_alpha1', 'u_alpha2', 'u_alpha3', 'u_alpha4', 'u_alpha5', 'u_alpha6', 'u_alpha7',\n  'u_intensity', 'u_scale', 'u_direction', 'u_softness',\n  'u_distortion', 'u_complexity', 'u_shape',\n  'u_vignette', 'u_vigOpacity', 'u_blur', 'u_shaderOpacity',\n];\n\nfunction buildGLPipeline(gl: WebGLRenderingContext): {\n  program: WebGLProgram; buffer: WebGLBuffer; uniforms: Record<string, WebGLUniformLocation | null>;\n} {\n  gl.enable(gl.BLEND);\n  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n  const vert = compileShader(gl, gl.VERTEX_SHADER, VERT_SHADER_SRC);\n  const frag = compileShader(gl, gl.FRAGMENT_SHADER, FRAG_SHADER_SRC);\n  const program = linkProgram(gl, vert, frag);\n  // biome-ignore lint/correctness/useHookAtTopLevel: WebGL method, not a React hook\n  gl.useProgram(program);\n\n  const buffer = gl.createBuffer();\n  if (!buffer) throw new Error('metal-fx: gl.createBuffer returned null');\n  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW);\n  const posLoc = gl.getAttribLocation(program, 'a_position');\n  gl.enableVertexAttribArray(posLoc);\n  gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);\n\n  const uniforms: Record<string, WebGLUniformLocation | null> = {};\n  for (const n of UNIFORM_NAMES) uniforms[n] = gl.getUniformLocation(program, n);\n\n  return { program, buffer, uniforms };\n}\n\nexport function ensureSharedRenderer(): SharedRenderer {\n  if (SHARED) return SHARED;\n\n  const dpr = Math.min(GL_DPR_CAP, typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1);\n  const size = Math.round(CANONICAL_GL_SIZE * dpr);\n  const useOffscreen = typeof OffscreenCanvas !== 'undefined';\n\n  let glCanvas: HTMLCanvasElement | OffscreenCanvas;\n  let gl: WebGLRenderingContext | null;\n\n  if (useOffscreen) {\n    glCanvas = new OffscreenCanvas(size, size);\n    gl = glCanvas.getContext('webgl', {\n      alpha: true, premultipliedAlpha: false, antialias: false,\n    }) as WebGLRenderingContext | null;\n  } else {\n    const htmlCanvas = document.createElement('canvas');\n    htmlCanvas.width = size;\n    htmlCanvas.height = size;\n    gl = (htmlCanvas.getContext('webgl', {\n      alpha: true, premultipliedAlpha: false, antialias: false, preserveDrawingBuffer: true,\n    }) ?? htmlCanvas.getContext('experimental-webgl')) as WebGLRenderingContext | null;\n    glCanvas = htmlCanvas;\n  }\n  if (!gl) throw new Error('metal-fx: WebGL not supported');\n\n  const { program, buffer, uniforms } = buildGLPipeline(gl);\n\n  const onContextLost = (e: Event) => { e.preventDefault(); if (SHARED?.glCanvas === glCanvas) SHARED.contextLost = true; };\n  const onContextRestored = () => {\n    if (!SHARED || SHARED.glCanvas !== glCanvas) return;\n    const rebuilt = buildGLPipeline(SHARED.gl);\n    SHARED.program = rebuilt.program;\n    SHARED.buffer = rebuilt.buffer;\n    SHARED.uniforms = rebuilt.uniforms;\n    SHARED.presetDirty = true;\n    SHARED.contextLost = false;\n    _onContextRestored?.();\n  };\n  glCanvas.addEventListener('webglcontextlost', onContextLost as EventListener, false);\n  glCanvas.addEventListener('webglcontextrestored', onContextRestored as EventListener, false);\n\n  SHARED = {\n    glCanvas, gl, program, buffer, uniforms,\n    preset: PRESETS.chromatic.modes.dark, presetDirty: true,\n    contextLost: false, useOffscreen, frameBitmap: null,\n    startMs: performance.now(), pausedMs: 0, pausedAtMs: null,\n    rafId: 0, dpr, instances: new Set(), frameCount: 0,\n    glowQueue: [], glowIdx: 0, glowSkip: 0,\n    glowPixels: new Uint8Array(size * size * 4),\n    glowPixelsW: size, glowPixelsH: size,\n  };\n  return SHARED;\n}\n\nexport function teardownSharedRenderer(): void {\n  if (!SHARED) return;\n  const { gl, program, buffer, frameBitmap } = SHARED;\n  try {\n    frameBitmap?.close();\n    gl.deleteBuffer(buffer);\n    gl.deleteProgram(program);\n    gl.getExtension('WEBGL_lose_context')?.loseContext();\n  } catch { /* swallow */ }\n  SHARED = null;\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/perfConfig.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/perfConfig.ts",
          "type": "registry:component",
          "content": "// ─── Frame rates ──────────────────────────────────────────────────────────\n\n// Main render loop: shader + canvas compositing. 66ms ≈ 15fps.\nexport const FRAME_INTERVAL_MS = 66;\n\n// Reflection repaint throttle. Matches main loop; CSS blur hides stepping.\nexport const REFLECTION_INTERVAL_MS = 66;\n\n// ─── Glow ─────────────────────────────────────────────────────────────────\n\n// gl.readPixels interval for luminance sampling. GPU→CPU sync is expensive.\nexport const GLOW_READBACK_INTERVAL_MS = 1500;\n\n// Only run the glow callback every Nth rendered frame. Each update triggers\n// Chrome to re-rasterize + re-blur 6 SVG paths through 2 masks.\nexport const GLOW_SKIP_FRAMES = 1;\n\n// Points sampled around the perimeter to find the brightest hotspot.\nexport const PERIM_SAMPLES = 16;\n\n// SVG path segment counts. Lower = shorter d-strings = less SVG parse work.\n// Blur filters smooth out any polygon faceting.\nexport const HALO_SEGMENTS = 16;\nexport const EXTRA_SEGMENTS = 8;\n\n// ─── GL canvas ────────────────────────────────────────────────────────────\n\n// Base pixel size of the offscreen GL canvas (before DPR scaling).\n// The plasma is inherently blurry — higher values waste fragment work.\nexport const CANONICAL_GL_SIZE = 96;\n\n// Cap devicePixelRatio for the GL canvas. 3x retina is wasted on soft plasma.\nexport const GL_DPR_CAP = 2;\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/presets.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/presets.ts",
          "type": "registry:component",
          "content": "/**\n * Bundled preset configurations for the metal effect.\n *\n * Direct ports of the three JSON files shipped alongside the canonical demo:\n *   • preset-chromatic-both-modes.json\n *   • preset-silver-both-modes.json\n *   • preset-gold-both-modes.json\n *\n * Each preset carries a `dark` and `light` mode block. Values are reproduced\n * byte-for-byte (including the `chromatic.dark.scale = 1.6` quirk that gives\n * the dark chromatic preset its noticeably chunkier features compared with\n * the other dark-mode entries).\n *\n * The fragment shader only consumes uniforms 1..5 of `palette`/`alphas` for\n * the Plasma effect, but the JSON ships 7 colors / alphas to stay\n * forward-compatible with effect 24 (Noise Flow Wide). We keep the full 7 so\n * a future variant could opt into other effects without re-importing the\n * preset definitions.\n */\n\nexport type PresetName = 'chromatic' | 'silver' | 'gold';\nexport type PresetTheme = 'dark' | 'light';\n\nexport interface PresetMode {\n  /** 7-stop palette, indexed against `u_color1..u_color7`. */\n  colors: [string, string, string, string, string, string, string];\n  /** Per-stop alpha weights (0..1). */\n  alphas: [number, number, number, number, number, number, number];\n  /** Drift angle (degrees). Multiplied by π/180 before upload. */\n  direction: number;\n  /** Time multiplier applied JS-side before passing into the shader. */\n  speed: number;\n  /** Plasma intensity (wave-field amplitude). */\n  intensity: number;\n  /** Noise zoom — smaller = chunkier features. */\n  scale: number;\n  /** Edge softness (effect 1 ignores; carried for parity). */\n  softness: number;\n  /** Warp strength on the field (0..1). */\n  distortion: number;\n  /** FBM octave / frequency multiplier. */\n  complexity: number;\n  /** Reserved (effect 1 ignores). */\n  shape: number;\n  /** 9-tap blur sample radius (0 = single tap). */\n  blur: number;\n  /** Vignette range (0..1). */\n  vignette: number;\n  /** Vignette darkening strength (0..1). */\n  vigOpacity: number;\n  /** Final alpha multiplier in the fragment shader (0..1). */\n  shaderOpacity: number;\n}\n\nexport interface Preset {\n  name: PresetName;\n  modes: Record<PresetTheme, PresetMode>;\n}\n\n/** preset-chromatic-both-modes.json */\nconst CHROMATIC: Preset = {\n  name: 'chromatic',\n  modes: {\n    dark: {\n      colors: ['#000000', '#aae8ff', '#c5fe9e', '#f7888d', '#0d0d0d', '#fffdc3', '#007cff'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      direction: 80,\n      speed: 1.2,\n      intensity: 2,\n      scale: 1.6,\n      softness: 0.18,\n      distortion: 0.3,\n      complexity: 0.68,\n      shape: 1,\n      blur: 1,\n      vignette: 0.26,\n      vigOpacity: 0.6,\n      shaderOpacity: 1,\n    },\n    light: {\n      colors: ['#ffffff', '#ffffff', '#ffffff', '#ffb3b3', '#adadad', '#f5ff70', '#007cff'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      direction: 80,\n      speed: 1.2,\n      intensity: 2,\n      scale: 2.5,\n      softness: 0.18,\n      distortion: 0.3,\n      complexity: 0.68,\n      shape: 1,\n      blur: 1,\n      vignette: 0.24,\n      vigOpacity: 0.16,\n      shaderOpacity: 1,\n    },\n  },\n};\n\n/** preset-silver-both-modes.json */\nconst SILVER: Preset = {\n  name: 'silver',\n  modes: {\n    dark: {\n      colors: ['#000000', '#dedede', '#747270', '#e5e5e5', '#0d0d0d', '#ffffff', '#e6e6e6'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      direction: 80,\n      speed: 1.2,\n      intensity: 2,\n      scale: 2.5,\n      softness: 0.18,\n      distortion: 0.3,\n      complexity: 0.68,\n      shape: 1,\n      blur: 1,\n      vignette: 0.26,\n      vigOpacity: 0.6,\n      shaderOpacity: 0.88,\n    },\n    light: {\n      colors: ['#f6f6f6', '#ffffff', '#ffffff', '#f7f7f7', '#c9c9c9', '#d0d0d0', '#d1d1d1'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      direction: 80,\n      speed: 1.2,\n      intensity: 2,\n      scale: 2.5,\n      softness: 0.18,\n      distortion: 0.3,\n      complexity: 0.68,\n      shape: 1,\n      blur: 1,\n      vignette: 0.2,\n      vigOpacity: 0.26,\n      shaderOpacity: 1,\n    },\n  },\n};\n\n/** preset-gold-both-modes.json */\nconst GOLD: Preset = {\n  name: 'gold',\n  modes: {\n    dark: {\n      colors: ['#000000', '#ffffff', '#ffffff', '#f7d488', '#0d0d0d', '#fffdc3', '#ffffff'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      direction: 80,\n      speed: 1.0,\n      intensity: 2,\n      scale: 2.5,\n      softness: 0.18,\n      distortion: 0.3,\n      complexity: 0.68,\n      shape: 1,\n      blur: 1,\n      vignette: 0.26,\n      vigOpacity: 0.6,\n      shaderOpacity: 0.92,\n    },\n    light: {\n      colors: ['#fff8e1', '#fffbe0', '#ffffff', '#fff6d6', '#d2c7a7', '#dcd2bc', '#f9f7e5'],\n      alphas: [1, 1, 1, 1, 1, 1, 1],\n      direction: 80,\n      speed: 1.2,\n      intensity: 2,\n      scale: 2.5,\n      softness: 0.18,\n      distortion: 0.3,\n      complexity: 0.68,\n      shape: 1,\n      blur: 1,\n      vignette: 0.22,\n      vigOpacity: 0.24,\n      shaderOpacity: 1,\n    },\n  },\n};\n\nexport const PRESETS: Record<PresetName, Preset> = {\n  chromatic: CHROMATIC,\n  silver: SILVER,\n  gold: GOLD,\n};\n\nexport { hexToRgb } from './color';\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/color.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/color.ts",
          "type": "registry:component",
          "content": "/** Converts `#rrggbb` (or `#rgb`) to a normalized `[r, g, b]` triple (0–1). */\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace('#', '');\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n  return [parseInt(h.slice(0, 2), 16) / 255, parseInt(h.slice(2, 4), 16) / 255, parseInt(h.slice(4, 6), 16) / 255];\n}\n\nexport function rgbToHsv(r: number, g: number, b: number): [number, number, number] {\n  r /= 255; g /= 255; b /= 255;\n  const max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min;\n  let h = 0;\n  const s = max === 0 ? 0 : d / max;\n  if (d !== 0) {\n    if (max === r) h = ((g - b) / d + 6) % 6;\n    else if (max === g) h = (b - r) / d + 2;\n    else h = (r - g) / d + 4;\n    h /= 6;\n  }\n  return [h, s, max];\n}\n\nexport function hsvToRgb(h: number, s: number, v: number): [number, number, number] {\n  const i = Math.floor(h * 6), f = h * 6 - i;\n  const p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s);\n  let r = 0, g = 0, b = 0;\n  switch (i % 6) {\n    case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break;\n    case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break;\n    case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break;\n  }\n  return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/shaders.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/shaders.ts",
          "type": "registry:component",
          "content": "/**\n * Vertex + fragment shader for the metal-fx effect.\n *\n * Source-of-truth: the `FRAG_SRC` block at L3626–4179 of the canonical\n * `Image loader/index.html` engine. The chromatic / silver / gold presets all\n * run `effectIndex: 1` (Plasma), so we ship ONLY that branch — the original\n * carries 24 effects plus a dot-mode raster grid that this library does not\n * expose. Everything else (warp, snoise, fbm, palette, paletteAlpha, vignette,\n * gamma) is preserved character-for-character so the visible output matches\n * `metal.html` 1:1.\n *\n * Uniforms:\n *   u_resolution      vec2  — destination pixel buffer (DPR-scaled)\n *   u_time            float — seconds since boot, JS-side multiplied by speed\n *   u_color1..u_color5 vec3 — palette stops (effect 1 uses 5; uniforms 6/7 are\n *                            still uploaded for forward-compat with effect 24)\n *   u_color6, u_color7 vec3 — extra stops, unused at effect 1\n *   u_alpha1..u_alpha7 float\n *   u_intensity       float — amplitude of the wave field\n *   u_scale           float — noise zoom (smaller = chunkier features)\n *   u_direction       float — drift angle (radians)\n *   u_softness        float — kept for shader parity (effect 1 ignores)\n *   u_distortion      float — warp strength on the sin band field\n *   u_complexity      float — fbm octaves + frequency multiplier\n *   u_shape           float — kept for shader parity (effect 1 ignores)\n *   u_vignette        float — vignette range (0..1)\n *   u_vigOpacity      float — vignette darkening strength (0..1)\n *   u_blur            float — sample-radius for the 9-tap blur (0..1)\n *   u_shaderOpacity   float — final alpha multiplier (0..1)\n */\nexport const VERT_SHADER_SRC = /* glsl */ `\n  attribute vec2 a_position;\n  void main() { gl_Position = vec4(a_position, 0.0, 1.0); }\n`;\n\nexport const FRAG_SHADER_SRC = /* glsl */ `\n  precision highp float;\n\n  uniform vec2 u_resolution;\n  uniform float u_time;\n  uniform vec3 u_color1, u_color2, u_color3, u_color4, u_color5, u_color6, u_color7;\n  uniform float u_alpha1, u_alpha2, u_alpha3, u_alpha4, u_alpha5, u_alpha6, u_alpha7;\n  uniform float u_intensity, u_scale, u_direction;\n  uniform float u_softness, u_distortion, u_complexity, u_shape;\n  uniform float u_vignette, u_vigOpacity, u_blur, u_shaderOpacity;\n\n  vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n  vec2 mod289v2(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n  vec3 permute(vec3 x) { return mod289((x * 34.0 + 1.0) * x); }\n\n  float snoise(vec2 v) {\n    const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n                        -0.577350269189626, 0.024390243902439);\n    vec2 i = floor(v + dot(v, C.yy));\n    vec2 x0 = v - i + dot(i, C.xx);\n    vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n    vec4 x12 = x0.xyxy + C.xxzz;\n    x12.xy -= i1;\n    i = mod289v2(i);\n    vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));\n    vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n    m = m * m; m = m * m;\n    vec3 x_ = 2.0 * fract(p * C.www) - 1.0;\n    vec3 h = abs(x_) - 0.5;\n    vec3 ox = floor(x_ + 0.5);\n    vec3 a0 = x_ - ox;\n    m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n    vec3 g;\n    g.x = a0.x * x0.x + h.x * x0.y;\n    g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n    return 130.0 * dot(m, g);\n  }\n\n  float fbm(vec2 p, float oct) {\n    float val = 0.0, amp = 0.5;\n    int n = int(oct);\n    for (int i = 0; i < 7; i++) {\n      if (i >= n) break;\n      val += amp * snoise(p);\n      p *= 2.0;\n      amp *= 0.5;\n    }\n    return val;\n  }\n\n  float nfbm(vec2 p) { return fbm(p, 3.0 + u_complexity * 4.0); }\n\n  /* 5-stop palette used by effect 1 (Plasma) — direct port of \\`palette\\` from\n   * the canonical engine. Stops at t = 0, 0.25, 0.5, 0.75, 1.0. */\n  vec3 palette(float t) {\n    t = clamp(t, 0.0, 1.0);\n    t = t * t * (3.0 - 2.0 * t);\n    float k = 64.0;\n    float w1 = u_alpha1 * exp(-k * t * t);\n    float w2 = u_alpha2 * exp(-k * (t - 0.25) * (t - 0.25));\n    float w3 = u_alpha3 * exp(-k * (t - 0.5)  * (t - 0.5));\n    float w4 = u_alpha4 * exp(-k * (t - 0.75) * (t - 0.75));\n    float w5 = u_alpha5 * exp(-k * (t - 1.0)  * (t - 1.0));\n    float total = w1 + w2 + w3 + w4 + w5 + 0.0001;\n    return (u_color1 * w1 + u_color2 * w2 + u_color3 * w3 +\n            u_color4 * w4 + u_color5 * w5) / total;\n  }\n\n  /* Per-pixel alpha that re-introduces transparency when the user dials any\n   * palette stop's alpha below 1. Same \\`paletteAlpha\\` from the canonical\n   * engine. With every preset shipping all-1 alphas, this returns ~1 for every\n   * pixel — but mirroring it keeps custom-preset behaviour identical. */\n  float paletteAlpha(float t) {\n    t = clamp(t, 0.0, 1.0);\n    t = t * t * (3.0 - 2.0 * t);\n    float k = 64.0;\n    float w1 = u_alpha1 * exp(-k * t * t);\n    float w2 = u_alpha2 * exp(-k * (t - 0.25) * (t - 0.25));\n    float w3 = u_alpha3 * exp(-k * (t - 0.5)  * (t - 0.5));\n    float w4 = u_alpha4 * exp(-k * (t - 0.75) * (t - 0.75));\n    float w5 = u_alpha5 * exp(-k * (t - 1.0)  * (t - 1.0));\n    float totalW = w1 + w2 + w3 + w4 + w5 + 0.0001;\n    float rawW = exp(-k * t * t)\n               + exp(-k * (t - 0.25) * (t - 0.25))\n               + exp(-k * (t - 0.5)  * (t - 0.5))\n               + exp(-k * (t - 0.75) * (t - 0.75))\n               + exp(-k * (t - 1.0)  * (t - 1.0))\n               + 0.0001;\n    return totalW / rawW;\n  }\n\n  vec2 warp(vec2 p, float t) {\n    float str = u_distortion * 2.0;\n    return vec2(\n      nfbm(p + vec2(t * 0.1, 0.0)),\n      nfbm(p + vec2(0.0, t * 0.12) + 5.0)\n    ) * str;\n  }\n\n  /* Plasma: four sine bands warped by an FBM field, mapped through the\n   * 5-stop palette. Identical to effect 1 in the canonical engine. */\n  vec3 computeEffect(vec2 uv, float aspect, float t, float dist, float cpx) {\n    vec2 p = (uv - 0.5) * u_scale;\n    p.x *= aspect;\n    p += vec2(cos(u_direction), sin(u_direction)) * t * 0.15;\n\n    float freq = 3.0 + cpx * 8.0;\n    float val = 0.0;\n    val += sin(p.x * freq + t);\n    val += sin(p.y * freq + t * 1.3);\n    val += sin((p.x + p.y) * freq * 0.7 + t * 0.7);\n    val += sin(length(p) * freq * 0.8 - t * 1.5);\n    vec2 w = warp(p, t);\n    val += (w.x + w.y) * dist;\n    val = val * 0.2 * u_intensity + 0.5;\n\n    return palette(clamp(val, 0.0, 1.0));\n  }\n\n  void main() {\n    vec2 uv = gl_FragCoord.xy / u_resolution;\n    float aspect = u_resolution.x / u_resolution.y;\n    float t = u_time;          // JS already multiplied u_time by preset.speed.\n    float dist = u_distortion;\n    float cpx = u_complexity;\n\n    /* 5-tap cross blur (center + cardinal offsets). The chromatic/silver/gold\n     * presets all ship with blur=1 so this path is always active. 5 taps\n     * instead of the canonical engine's 9 saves ~44% fragment work; the\n     * perceptual difference is nil because the output is already soft from\n     * the plasma's low spatial frequency and CSS blur on reflections. */\n    vec3 col;\n    if (u_blur < 0.01) {\n      col = computeEffect(uv, aspect, t, dist, cpx);\n    } else {\n      float r = u_blur * 0.02;\n      col  = computeEffect(uv,                  aspect, t, dist, cpx) * 0.4;\n      col += computeEffect(uv + vec2( r, 0.0),  aspect, t, dist, cpx) * 0.15;\n      col += computeEffect(uv + vec2(-r, 0.0),  aspect, t, dist, cpx) * 0.15;\n      col += computeEffect(uv + vec2(0.0,  r),  aspect, t, dist, cpx) * 0.15;\n      col += computeEffect(uv + vec2(0.0, -r),  aspect, t, dist, cpx) * 0.15;\n    }\n\n    /* Gamma punch — adds the contrast pop that defines the chromatic\n     * highlights. From the canonical engine: \\`col = pow(col, vec3(1.3))\\`. */\n    col = pow(col, vec3(1.3));\n\n    /* Vignette — soft edge darkening so corners read as recessed. The 40-px\n     * scale at the bottom of the formula is hard-coded in the canonical\n     * engine; we keep it for visual parity. */\n    float edgeDist = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));\n    float vigPx = 40.0 / min(u_resolution.x, u_resolution.y);\n    float vigRange = vigPx * (1.0 + u_vignette * 3.0);\n    float vig = edgeDist * edgeDist / (vigRange * vigRange);\n    vig = smoothstep(0.0, 1.0, vig);\n    col *= mix(1.0, vig, u_vignette * u_vigOpacity);\n\n    /* Per-pixel alpha. With all-1 alphas the formula collapses to ~1 but the\n     * computation matches the canonical engine so custom presets behave the\n     * same. */\n    float colorAlpha = (u_alpha1 + u_alpha2 + u_alpha3 + u_alpha4 + u_alpha5) / 5.0;\n    if (colorAlpha < 0.999) {\n      vec3 c1d = col - u_color1, c2d = col - u_color2, c3d = col - u_color3,\n           c4d = col - u_color4, c5d = col - u_color5;\n      float prox1 = exp(-8.0 * dot(c1d, c1d));\n      float prox2 = exp(-8.0 * dot(c2d, c2d));\n      float prox3 = exp(-8.0 * dot(c3d, c3d));\n      float prox4 = exp(-8.0 * dot(c4d, c4d));\n      float prox5 = exp(-8.0 * dot(c5d, c5d));\n      float pTotal = prox1 + prox2 + prox3 + prox4 + prox5 + 0.0001;\n      colorAlpha = (prox1 * u_alpha1 + prox2 * u_alpha2 + prox3 * u_alpha3 +\n                    prox4 * u_alpha4 + prox5 * u_alpha5) / pTotal;\n    }\n    float alpha = colorAlpha;\n\n    /* Touch the unused-at-effect-1 uniforms so GL drivers that complain about\n     * declared-but-unread uniforms (some Mali / Adreno builds do) keep them\n     * live. The contribution is provably zero. */\n    alpha += 0.0 * (u_softness + u_shape +\n                    u_alpha6 + u_alpha7 +\n                    u_color6.x + u_color7.x);\n\n    gl_FragColor = vec4(col, alpha * u_shaderOpacity);\n  }\n`;\n\n/** Compile a single shader stage. Throws with the GL info log on failure. */\nexport function compileShader(\n  gl: WebGLRenderingContext,\n  type: number,\n  source: string\n): WebGLShader {\n  const shader = gl.createShader(type);\n  if (!shader) throw new Error('metal-fx: gl.createShader returned null');\n  gl.shaderSource(shader, source);\n  gl.compileShader(shader);\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    const info = gl.getShaderInfoLog(shader);\n    gl.deleteShader(shader);\n    throw new Error(`metal-fx: shader compile failed: ${info ?? '(no info log)'}`);\n  }\n  return shader;\n}\n\n/** Link a vertex + fragment shader pair into a complete program. */\nexport function linkProgram(\n  gl: WebGLRenderingContext,\n  vert: WebGLShader,\n  frag: WebGLShader\n): WebGLProgram {\n  const program = gl.createProgram();\n  if (!program) throw new Error('metal-fx: gl.createProgram returned null');\n  gl.attachShader(program, vert);\n  gl.attachShader(program, frag);\n  gl.linkProgram(program);\n  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n    const info = gl.getProgramInfoLog(program);\n    gl.deleteProgram(program);\n    throw new Error(`metal-fx: program link failed: ${info ?? '(no info log)'}`);\n  }\n  return program;\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/renderer/loop.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/renderer/loop.ts",
          "type": "registry:component",
          "content": "/** Animation loop, per-frame compositing, and instance lifecycle. */\nimport { hexToRgb } from '../color';\nimport { FRAME_INTERVAL_MS, GLOW_SKIP_FRAMES } from '../perfConfig';\nimport { PRESETS, type PresetName, type PresetTheme } from '../presets';\nimport {\n  SHARED,\n  CANONICAL_PILL_W,\n  CANONICAL_PILL_H,\n  CIRCLE_SHADER_SCALE,\n  PILL_SHADER_SCALE,\n  ensureSharedRenderer,\n  setContextRestoredCallback,\n  teardownSharedRenderer,\n  type MetalFxInstance,\n} from './core';\nimport { ensureGlowPixels } from './sampling';\n\n// Restart the animation loop when the browser restores the GL context.\nsetContextRestoredCallback(() => {\n  if (SHARED && SHARED.instances.size > 0 && SHARED.pausedAtMs === null) {\n    startSharedLoop();\n  }\n});\n\nif (typeof document !== 'undefined') {\n  document.addEventListener('visibilitychange', () => {\n    if (!SHARED || SHARED.pausedAtMs !== null || SHARED.contextLost) return;\n    if (document.hidden) {\n      stopSharedLoop();\n    } else if (SHARED.instances.size > 0) {\n      startSharedLoop();\n    }\n  });\n}\n\n// ─── Instance lifecycle ───────────────────────────────────────────────────\n\ninterface CreateInstanceOptions {\n  hostCanvas: HTMLCanvasElement;\n  cssWidth: number;\n  cssHeight: number;\n  cornerRadius: number;\n  kind: 'pill' | 'circle';\n  shaderScale?: number;\n  ringCssPx?: number;\n  opacityMul?: number;\n  paused?: boolean;\n  scale?: number;\n  onAfterFrame?: () => void;\n  onFirstCopy?: () => void;\n}\n\nexport function createInstance(opts: CreateInstanceOptions): MetalFxInstance {\n  const renderer = ensureSharedRenderer();\n  const ctx = opts.hostCanvas.getContext('2d', { alpha: true });\n  if (!ctx) throw new Error('metal-fx: canvas 2D context unavailable');\n\n  const scale = opts.scale ?? 1;\n  const inst: MetalFxInstance = {\n    canvas: opts.hostCanvas, ctx,\n    cssWidth: opts.cssWidth, cssHeight: opts.cssHeight,\n    cornerRadius: opts.cornerRadius,\n    kind: opts.kind,\n    ringCssPx: opts.ringCssPx ?? (opts.kind === 'circle' ? 2 : 1) * scale,\n    shaderScale: opts.shaderScale ?? (opts.kind === 'circle' ? CIRCLE_SHADER_SCALE : PILL_SHADER_SCALE) * scale,\n    opacityMul: opts.opacityMul ?? 1,\n    visible: true,\n    paused: opts.paused ?? false,\n    everCopied: false,\n    dpr: typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1,\n    scale,\n    onAfterFrame: opts.onAfterFrame,\n    onFirstCopy: opts.onFirstCopy,\n  };\n  resizeInstanceCanvas(inst);\n  renderer.instances.add(inst);\n  if (renderer.rafId === 0 && renderer.pausedAtMs === null) startSharedLoop();\n  return inst;\n}\n\nexport function destroyInstance(inst: MetalFxInstance): void {\n  if (!SHARED) return;\n  SHARED.instances.delete(inst);\n  const qi = SHARED.glowQueue.indexOf(inst);\n  if (qi !== -1) SHARED.glowQueue.splice(qi, 1);\n  if (SHARED.instances.size === 0) { stopSharedLoop(); teardownSharedRenderer(); }\n}\n\nexport function registerGlowInstance(inst: MetalFxInstance): void {\n  if (!SHARED) return;\n  if (!SHARED.glowQueue.includes(inst)) SHARED.glowQueue.push(inst);\n}\n\nexport function unregisterGlowInstance(inst: MetalFxInstance): void {\n  if (!SHARED) return;\n  const i = SHARED.glowQueue.indexOf(inst);\n  if (i !== -1) SHARED.glowQueue.splice(i, 1);\n}\n\nexport function updateInstance(\n  inst: MetalFxInstance,\n  patch: Partial<Pick<MetalFxInstance, 'cssWidth' | 'cssHeight' | 'cornerRadius' | 'kind' | 'shaderScale' | 'ringCssPx' | 'opacityMul' | 'paused' | 'scale'>>\n): void {\n  let dirty = false;\n  if (patch.cssWidth !== undefined && patch.cssWidth !== inst.cssWidth) { inst.cssWidth = patch.cssWidth; dirty = true; }\n  if (patch.cssHeight !== undefined && patch.cssHeight !== inst.cssHeight) { inst.cssHeight = patch.cssHeight; dirty = true; }\n  if (patch.cornerRadius !== undefined) inst.cornerRadius = patch.cornerRadius;\n  if (patch.scale !== undefined) inst.scale = patch.scale;\n  if (patch.kind !== undefined && patch.kind !== inst.kind) {\n    inst.kind = patch.kind;\n    if (patch.shaderScale === undefined) inst.shaderScale = (patch.kind === 'circle' ? CIRCLE_SHADER_SCALE : PILL_SHADER_SCALE) * inst.scale;\n    if (patch.ringCssPx === undefined) inst.ringCssPx = (patch.kind === 'circle' ? 2 : 1) * inst.scale;\n  }\n  if (patch.shaderScale !== undefined) inst.shaderScale = patch.shaderScale;\n  if (patch.ringCssPx !== undefined) inst.ringCssPx = patch.ringCssPx;\n  if (patch.opacityMul !== undefined) inst.opacityMul = patch.opacityMul;\n  if (patch.paused !== undefined && patch.paused !== inst.paused) {\n    inst.paused = patch.paused;\n    // Unpausing should kick the loop if it had idled because every visible\n    // instance was paused.\n    if (!patch.paused && SHARED && SHARED.rafId === 0 && SHARED.pausedAtMs === null && !SHARED.contextLost) {\n      startSharedLoop();\n    }\n  }\n  if (dirty) resizeInstanceCanvas(inst);\n}\n\nexport function setInstanceVisible(inst: MetalFxInstance, visible: boolean): void {\n  inst.visible = visible;\n  if (visible && SHARED && SHARED.rafId === 0 && SHARED.pausedAtMs === null && !SHARED.contextLost) {\n    startSharedLoop();\n  }\n}\n\nexport function setSharedPreset(name: PresetName, theme: PresetTheme): void {\n  const s = ensureSharedRenderer();\n  s.preset = PRESETS[name].modes[theme];\n  s.presetDirty = true;\n}\n\nexport function pauseShared(): void {\n  if (!SHARED || SHARED.pausedAtMs !== null) return;\n  SHARED.pausedAtMs = performance.now();\n  stopSharedLoop();\n}\n\nexport function resumeShared(): void {\n  if (!SHARED || SHARED.pausedAtMs === null) return;\n  SHARED.pausedMs += performance.now() - SHARED.pausedAtMs;\n  SHARED.pausedAtMs = null;\n  if (SHARED.instances.size > 0) startSharedLoop();\n}\n\nexport function getSharedFrameCount(): number {\n  return SHARED?.frameCount ?? 0;\n}\n\n// ─── Glow callback ────────────────────────────────────────────────────────\n\nexport type GlowCallback = (inst: MetalFxInstance, nowMs: number) => void;\nlet _glowCallback: GlowCallback | null = null;\n\nexport function setGlowCallback(cb: GlowCallback | null): void {\n  _glowCallback = cb;\n}\n\n// ─── Internal rendering ───────────────────────────────────────────────────\n\nfunction resizeInstanceCanvas(inst: MetalFxInstance): void {\n  inst.dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n  const w = Math.max(1, Math.round(inst.cssWidth * inst.dpr));\n  const h = Math.max(1, Math.round(inst.cssHeight * inst.dpr));\n  if (inst.canvas.width !== w) inst.canvas.width = w;\n  if (inst.canvas.height !== h) inst.canvas.height = h;\n}\n\nfunction punchInnerHole(inst: MetalFxInstance): void {\n  const { ctx, dpr, canvas } = inst;\n  const stroke = inst.ringCssPx * dpr;\n  const w = canvas.width, h = canvas.height;\n  const innerR = Math.max(0, (inst.cornerRadius - inst.ringCssPx) * dpr);\n  ctx.save();\n  ctx.globalCompositeOperation = 'destination-out';\n  ctx.fillStyle = '#000';\n  ctx.beginPath();\n  ctx.roundRect(stroke, stroke, w - 2 * stroke, h - 2 * stroke, innerR);\n  ctx.fill();\n  ctx.restore();\n}\n\nfunction copyShaderToInstance(inst: MetalFxInstance): void {\n  if (!SHARED) return;\n  const src: CanvasImageSource = SHARED.frameBitmap ?? SHARED.glCanvas;\n  const dpr = inst.dpr;\n  const dw = inst.canvas.width, dh = inst.canvas.height;\n  if (dw < 1 || dh < 1) return;\n\n  const cw = SHARED.glCanvas.width, ch = SHARED.glCanvas.height;\n  const bdW = CANONICAL_PILL_W * dpr, bdH = CANONICAL_PILL_H * dpr;\n  let srcW = (dw * (cw / bdW)) / inst.shaderScale;\n  let srcH = (dh * (ch / bdH)) / inst.shaderScale;\n  if (srcW > cw) srcW = cw;\n  if (srcH > ch) srcH = ch;\n  const sx = Math.max(0, (cw - srcW) / 2);\n  const sy = Math.max(0, (ch - srcH) / 2);\n\n  inst.ctx.clearRect(0, 0, dw, dh);\n  if (inst.opacityMul < 1) inst.ctx.globalAlpha = inst.opacityMul;\n  inst.ctx.drawImage(src, sx, sy, srcW, srcH, 0, 0, dw, dh);\n  if (inst.opacityMul < 1) inst.ctx.globalAlpha = 1;\n\n  punchInnerHole(inst);\n  if (inst.onFirstCopy) { const cb = inst.onFirstCopy; inst.onFirstCopy = undefined; cb(); }\n  inst.onAfterFrame?.();\n}\n\nfunction uploadPresetUniforms(): void {\n  if (!SHARED) return;\n  const { gl, uniforms, preset, glCanvas } = SHARED;\n  if (uniforms.u_resolution) gl.uniform2f(uniforms.u_resolution, glCanvas.width, glCanvas.height);\n  for (let i = 0; i < 7; i++) {\n    const cLoc = uniforms[`u_color${i + 1}`];\n    if (cLoc) { const [r, g, b] = hexToRgb(preset.colors[i]); gl.uniform3f(cLoc, r, g, b); }\n    const aLoc = uniforms[`u_alpha${i + 1}`];\n    if (aLoc) gl.uniform1f(aLoc, preset.alphas[i]);\n  }\n  if (uniforms.u_intensity) gl.uniform1f(uniforms.u_intensity, preset.intensity);\n  if (uniforms.u_scale) gl.uniform1f(uniforms.u_scale, preset.scale);\n  if (uniforms.u_direction) gl.uniform1f(uniforms.u_direction, (preset.direction * Math.PI) / 180);\n  if (uniforms.u_softness) gl.uniform1f(uniforms.u_softness, preset.softness);\n  if (uniforms.u_distortion) gl.uniform1f(uniforms.u_distortion, preset.distortion);\n  if (uniforms.u_complexity) gl.uniform1f(uniforms.u_complexity, preset.complexity);\n  if (uniforms.u_shape) gl.uniform1f(uniforms.u_shape, preset.shape);\n  if (uniforms.u_vignette) gl.uniform1f(uniforms.u_vignette, preset.vignette);\n  if (uniforms.u_vigOpacity) gl.uniform1f(uniforms.u_vigOpacity, preset.vigOpacity);\n  if (uniforms.u_blur) gl.uniform1f(uniforms.u_blur, preset.blur);\n  if (uniforms.u_shaderOpacity) gl.uniform1f(uniforms.u_shaderOpacity, preset.shaderOpacity);\n  SHARED.presetDirty = false;\n}\n\nfunction renderSharedFrame(now: number): void {\n  if (!SHARED) return;\n  const { gl, uniforms, preset, glCanvas } = SHARED;\n  const t = ((now - SHARED.startMs - SHARED.pausedMs) / 1000) * preset.speed;\n\n  gl.viewport(0, 0, glCanvas.width, glCanvas.height);\n  gl.clearColor(0, 0, 0, 0);\n  gl.clear(gl.COLOR_BUFFER_BIT);\n\n  if (SHARED.presetDirty) uploadPresetUniforms();\n  if (uniforms.u_time) gl.uniform1f(uniforms.u_time, t);\n\n  gl.drawArrays(gl.TRIANGLES, 0, 6);\n  SHARED.frameCount++;\n}\n\nlet lastFrameMs = 0;\n\nfunction tick(now: number): void {\n  if (!SHARED) return;\n  if (SHARED.contextLost) { SHARED.rafId = 0; return; }\n\n  // Loop stays alive while at least one visible instance still has work to do\n  // — i.e. it's either unpaused (needs a fresh copy each frame) or paused but\n  // hasn't yet painted its first frame (initial-mount-paused case).\n  let anyWork = false;\n  for (const inst of SHARED.instances) {\n    if (inst.visible && (!inst.paused || !inst.everCopied)) { anyWork = true; break; }\n  }\n  if (!anyWork) { SHARED.rafId = 0; return; }\n\n  SHARED.rafId = requestAnimationFrame(tick);\n  if (now - lastFrameMs < FRAME_INTERVAL_MS) return;\n  lastFrameMs = now;\n\n  renderSharedFrame(now);\n\n  if (SHARED.useOffscreen) {\n    if (SHARED.glowQueue.length > 0) ensureGlowPixels();\n    SHARED.frameBitmap?.close();\n    SHARED.frameBitmap = (SHARED.glCanvas as OffscreenCanvas).transferToImageBitmap();\n  }\n\n  for (const inst of SHARED.instances) {\n    if (!inst.visible) continue;\n    if (inst.paused && inst.everCopied) continue;\n    copyShaderToInstance(inst);\n    inst.everCopied = true;\n  }\n\n  if (_glowCallback && SHARED.glowQueue.length > 0 && ++SHARED.glowSkip % GLOW_SKIP_FRAMES === 0) {\n    const queue = SHARED.glowQueue;\n    if (SHARED.glowIdx >= queue.length) SHARED.glowIdx = 0;\n    const inst = queue[SHARED.glowIdx];\n    // Skip glow frames for paused instances so their halo also freezes\n    // (otherwise the catch-light would keep travelling on a frozen ring).\n    if (inst.visible && !inst.paused) _glowCallback(inst, now);\n    SHARED.glowIdx++;\n  }\n}\n\nfunction startSharedLoop(): void {\n  if (!SHARED || SHARED.rafId !== 0) return;\n  SHARED.rafId = requestAnimationFrame(tick);\n}\n\nfunction stopSharedLoop(): void {\n  if (!SHARED) return;\n  if (SHARED.rafId !== 0) cancelAnimationFrame(SHARED.rafId);\n  SHARED.rafId = 0;\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/renderer/sampling.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/renderer/sampling.ts",
          "type": "registry:component",
          "content": "/**\n * Pixel readback and luminance/colour sampling from the shared GL canvas.\n *\n * All glow luminance/color sampling reads from a shared pixel buffer\n * (SHARED.glowPixels). The buffer is refreshed via gl.readPixels at most\n * every GLOW_READBACK_INTERVAL_MS to avoid the expensive GPU→CPU pipeline\n * flush on every frame. The plasma shader evolves slowly so 200ms-stale\n * data is visually indistinguishable.\n */\nimport { GLOW_READBACK_INTERVAL_MS } from '../perfConfig';\nimport { SHARED, CANONICAL_PILL_W, CANONICAL_PILL_H, type MetalFxInstance, type ShaderRGB } from './core';\nlet _lastReadbackMs = 0;\n\nexport function ensureGlowPixels(): void {\n  if (!SHARED) return;\n  const now = performance.now();\n  if (now - _lastReadbackMs < GLOW_READBACK_INTERVAL_MS) return;\n  _lastReadbackMs = now;\n  const { gl, glCanvas } = SHARED;\n  const cw = glCanvas.width, ch = glCanvas.height;\n  if (SHARED.glowPixelsW !== cw || SHARED.glowPixelsH !== ch) {\n    SHARED.glowPixelsW = cw;\n    SHARED.glowPixelsH = ch;\n    SHARED.glowPixels = new Uint8Array(cw * ch * 4);\n  }\n  gl.readPixels(0, 0, cw, ch, gl.RGBA, gl.UNSIGNED_BYTE, SHARED.glowPixels);\n}\n\n/**\n * Map per-instance CSS-px glow coordinates to the shared GL pixel buffer.\n *\n * The GL canvas is shared across all instances. Each instance \"sees\" a\n * different crop of it (computed identically to copyShaderToInstance).\n * This function reverses that mapping: given a CSS-px coordinate on the\n * instance, it returns the (bx, by) index into SHARED.glowPixels.\n *\n * readPixels stores rows bottom-up (GL convention) so Y is flipped.\n */\nconst _map = { bx: 0, by: 0 };\n\nfunction mapToGlowBuf(inst: MetalFxInstance, cssPxX: number, cssPxY: number): typeof _map {\n  if (!SHARED) { _map.bx = 0; _map.by = 0; return _map; }\n  const { glCanvas } = SHARED;\n  const cw = glCanvas.width, ch = glCanvas.height;\n  const dpr = inst.dpr;\n  const dw = inst.cssWidth * dpr, dh = inst.cssHeight * dpr;\n  const bdW = CANONICAL_PILL_W * dpr, bdH = CANONICAL_PILL_H * dpr;\n  let srcW = (dw * (cw / bdW)) / inst.shaderScale;\n  let srcH = (dh * (ch / bdH)) / inst.shaderScale;\n  if (srcW > cw) srcW = cw;\n  if (srcH > ch) srcH = ch;\n  const sx = (cw - srcW) / 2;\n  const sy = (ch - srcH) / 2;\n  const glX = sx + (cssPxX / inst.cssWidth) * srcW;\n  const glY = sy + (cssPxY / inst.cssHeight) * srcH;\n  _map.bx = Math.round(glX);\n  _map.by = Math.round(ch - 1 - glY);\n  return _map;\n}\n\nconst _sr = { r: 0, g: 0, b: 0, lum: 0, count: 0 };\n\nfunction sampleRegion(\n  buf: Uint8Array, W: number, H: number,\n  bx: number, by: number, radius: number\n): typeof _sr {\n  const r = Math.max(1, radius | 0);\n  const x0 = Math.max(0, bx - r), x1 = Math.min(W, bx + r + 1);\n  const y0 = Math.max(0, by - r), y1 = Math.min(H, by + r + 1);\n  _sr.r = 0; _sr.g = 0; _sr.b = 0; _sr.lum = 0; _sr.count = 0;\n  for (let py = y0; py < y1; py++) {\n    const row = py * W;\n    for (let px = x0; px < x1; px++) {\n      const i = (row + px) * 4;\n      _sr.r += buf[i]; _sr.g += buf[i + 1]; _sr.b += buf[i + 2];\n      _sr.lum += (0.2126 * buf[i] + 0.7152 * buf[i + 1] + 0.0722 * buf[i + 2]) / 255;\n      _sr.count++;\n    }\n  }\n  return _sr;\n}\n\nconst _rgb: ShaderRGB = { r: 255, g: 255, b: 255 };\n\nexport function sampleShaderLumAt(inst: MetalFxInstance, cssPxX: number, cssPxY: number, radius: number): number {\n  if (!SHARED) return 0;\n  ensureGlowPixels();\n  const m = mapToGlowBuf(inst, cssPxX, cssPxY);\n  const s = sampleRegion(SHARED.glowPixels, SHARED.glowPixelsW, SHARED.glowPixelsH, m.bx, m.by, radius);\n  return s.count > 0 ? s.lum / s.count : 0;\n}\n\nexport function sampleShaderRGBAt(inst: MetalFxInstance, cssPxX: number, cssPxY: number, radius: number): ShaderRGB {\n  if (!SHARED) { _rgb.r = 255; _rgb.g = 255; _rgb.b = 255; return _rgb; }\n  ensureGlowPixels();\n  const m = mapToGlowBuf(inst, cssPxX, cssPxY);\n  const s = sampleRegion(SHARED.glowPixels, SHARED.glowPixelsW, SHARED.glowPixelsH, m.bx, m.by, radius);\n  if (s.count === 0) { _rgb.r = 255; _rgb.g = 255; _rgb.b = 255; return _rgb; }\n  _rgb.r = s.r / s.count; _rgb.g = s.g / s.count; _rgb.b = s.b / s.count;\n  return _rgb;\n}\n\nexport function sampleShaderRGBChromatic(inst: MetalFxInstance, cssPxX: number, cssPxY: number, radius: number): ShaderRGB {\n  if (!SHARED) { _rgb.r = 255; _rgb.g = 255; _rgb.b = 255; return _rgb; }\n  ensureGlowPixels();\n  const m = mapToGlowBuf(inst, cssPxX, cssPxY);\n  const { glowPixels: buf, glowPixelsW: W, glowPixelsH: H } = SHARED;\n  const r = Math.max(1, radius | 0);\n  const x0 = Math.max(0, m.bx - r), x1 = Math.min(W, m.bx + r + 1);\n  const y0 = Math.max(0, m.by - r), y1 = Math.min(H, m.by + r + 1);\n  let bestScore = -1;\n  _rgb.r = 255; _rgb.g = 255; _rgb.b = 255;\n  for (let py = y0; py < y1; py++) {\n    const row = py * W;\n    for (let px = x0; px < x1; px++) {\n      const i = (row + px) * 4;\n      const rr = buf[i], gg = buf[i + 1], bb = buf[i + 2];\n      const maxC = Math.max(rr, gg, bb), minC = Math.min(rr, gg, bb);\n      const sat = maxC > 0 ? (maxC - minC) / maxC : 0;\n      const score = sat * (0.35 + 0.65 * (maxC / 255));\n      if (score > bestScore) { bestScore = score; _rgb.r = rr; _rgb.g = gg; _rgb.b = bb; }\n    }\n  }\n  return _rgb;\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/glow/glow.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/glow/glow.ts",
          "type": "registry:component",
          "content": "/**\n * SVG glow overlay — a luminance-driven halo that tracks the brightest point\n * on the shader's perimeter.\n *\n * How it works:\n *   1. Samples luminance at N points around the component's perimeter.\n *   2. A state machine tracks which perimeter point is brightest, with dwell\n *      timers and fade-in/out transitions when relocating to a new hotspot.\n *   3. Static SVG path elements (blurred strokes at multiple radii) are\n *      positioned at the current hotspot via CSS transform.\n *   4. The stroke color is tinted to match the shader's color at that point.\n */\nimport { HALO_SEGMENTS, EXTRA_SEGMENTS } from '../perfConfig';\nimport type { MetalFxInstance, ShaderRGB } from '../renderer/core';\nimport { sampleShaderLumAt, sampleShaderRGBAt, sampleShaderRGBChromatic } from '../renderer/sampling';\nimport { type Tween, ease, tween, tweenStart, tweenTick } from '../tween';\nimport { hsvToRgb, rgbToHsv } from '../color';\nimport {\n  type GlowOptions,\n  type PerimSample,\n  type Pt,\n  buildPerimTable,\n  buildStaticBlobPath,\n  buildSvgMarkup,\n  rrPerim,\n  sampleAtArc,\n  shapePerim,\n  smoothstep,\n  tangentAngleAtArc,\n} from './geometry';\n\n// ─── Constants ────────────────────────────────────────────────────────────\n\nconst FADE_RATE = 0.00875;\nconst LO = 0.08, HI = 0.32;\nconst RELOCATE_DELTA = 0.05;\nconst MIN_DWELL_MS = 3000;\nconst PEAK_OP = 0.85, BASE_OP = 0.34;\nconst RELOC_FADE_MS = 1500;\nconst WANDER_RANGE = 15, WANDER_LERP = 0.0075, WANDER_RETARGET = 120;\nconst INSET = 1.5;\nconst HALO_HALFLEN = 7.8;\nconst EXTRA_HALFLEN = 9.13952, EXTRA_OUTWARD = 1.0;\nconst EXTRA_SCALE = 1 / 3;\nconst HALO_OP_MUL = 0.8;\nconst EXTRA_INTENSITY = 3.51;\nconst TINT_HOLD_MS = 2000, TINT_FADE_MS = 400;\nconst LT_SAT_BOOST = 2.625, LT_VAL_MULT = 1.008, LT_MIN_VAL = 0.31;\nconst REF_W = 140, REF_H = 40, REF_R = 20;\n\n// ─── Types ────────────────────────────────────────────────────────────────\n\nexport type { GlowOptions } from './geometry';\n\nexport interface GlowHandles {\n  svg: SVGSVGElement;\n  haloGroup: SVGGElement;\n  haloInner: SVGGElement;\n  extraGroup: SVGGElement;\n  extraInner: SVGGElement;\n  fadeCircle: SVGCircleElement;\n  width: number; height: number; cornerRadius: number; kind: 'pill' | 'circle';\n  /** Master scale used at injection time so per-frame position math\n   *  (INSET / EXTRA_OUTWARD) stays consistent with the strokes already\n   *  baked into the SVG markup. */\n  scale: number;\n  perim: PerimSample[];\n  currentIdx: number; appearedAt: number; glowOpacity: number;\n  relocTween: Tween | null; relocNextIdx: number;\n  wanderS: number; wanderTargetS: number; wanderFrames: number;\n  tintFrom: ShaderRGB; tintTarget: ShaderRGB; tintTween: Tween | null; tintHoldUntil: number;\n  lastHaloStroke: string; lastExtraStroke: string;\n}\n\nlet glowIdSeq = 0;\nconst _pt: Pt = { x: 0, y: 0 };\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\nexport function injectGlow(container: HTMLElement, opts: GlowOptions): GlowHandles {\n  const p = `mfxg_${++glowIdSeq}`;\n  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n  svg.setAttribute('class', 'metal-fx-glow-svg');\n  svg.setAttribute('preserveAspectRatio', 'none');\n  svg.setAttribute('viewBox', `0 0 ${opts.width} ${opts.height}`);\n  svg.innerHTML = buildSvgMarkup(opts, p);\n  container.appendChild(svg);\n\n  const q = (id: string) => svg.querySelector(`#${p}_${id}`) as SVGElement;\n  const haloGroup = q('h') as SVGGElement;\n  const haloInner = q('hI') as SVGGElement;\n  const extraGroup = q('e') as SVGGElement;\n  const extraInner = q('eI') as SVGGElement;\n  const fadeCircle = q('fc') as SVGCircleElement;\n\n  const ratio = shapePerim(opts.width, opts.height, opts.cornerRadius, opts.kind) / rrPerim(REF_W, REF_H, REF_R);\n  const haloHL = Math.max(1, HALO_HALFLEN * ratio);\n  const extraHL = Math.max(0.6, EXTRA_HALFLEN * EXTRA_SCALE * ratio);\n  const haloD = buildStaticBlobPath(haloHL, HALO_SEGMENTS);\n  const extraD = buildStaticBlobPath(extraHL, EXTRA_SEGMENTS);\n\n  const haloPaths = [q('pXl'), q('pLg'), q('pMd'), q('pSm')] as SVGPathElement[];\n  const extraPaths = [q('eO'), q('eC')] as SVGPathElement[];\n  for (const path of haloPaths) path.setAttribute('d', haloD);\n  for (const path of extraPaths) path.setAttribute('d', extraD);\n\n  haloInner.style.transformOrigin = '0 0';\n  extraInner.style.transformOrigin = '0 0';\n  haloInner.style.willChange = 'transform';\n  extraInner.style.willChange = 'transform';\n  haloInner.style.transition = 'transform 100ms linear';\n  extraInner.style.transition = 'transform 100ms linear';\n\n  haloGroup.style.willChange = 'opacity';\n  extraGroup.style.willChange = 'opacity';\n  haloGroup.style.transition = 'opacity 100ms linear';\n  extraGroup.style.transition = 'opacity 100ms linear';\n\n  fadeCircle.style.willChange = 'transform';\n\n  return {\n    svg, haloGroup, haloInner, extraGroup, extraInner, fadeCircle,\n    width: opts.width, height: opts.height, cornerRadius: opts.cornerRadius, kind: opts.kind,\n    scale: opts.scale ?? 1,\n    perim: buildPerimTable(opts),\n    currentIdx: 0, appearedAt: 0, glowOpacity: 0,\n    relocTween: null, relocNextIdx: -1,\n    wanderS: 0, wanderTargetS: 0, wanderFrames: 0,\n    tintFrom: { r: 255, g: 255, b: 255 }, tintTarget: { r: 255, g: 255, b: 255 }, tintTween: null, tintHoldUntil: 0,\n    lastHaloStroke: '', lastExtraStroke: '',\n  };\n}\n\n// ─── Per-frame update ─────────────────────────────────────────────────────\n\nexport function updateGlow(h: GlowHandles, inst: MetalFxInstance, nowMs: number, strengthMul: number, theme: 'dark' | 'light' = 'dark'): void {\n  const { width: W, height: H, cornerRadius: R, perim } = h;\n  if (perim.length === 0) return;\n\n  const halfWin = 2;\n\n  let maxLum = -1, maxIdx = h.currentIdx, curLum = 0;\n  for (let i = 0; i < perim.length; i++) {\n    const pt = perim[i];\n    const lum = sampleShaderLumAt(inst, pt.x, pt.y, halfWin);\n    if (lum > maxLum) { maxLum = lum; maxIdx = i; }\n    if (i === h.currentIdx) curLum = lum;\n  }\n\n  const dwellActive = h.appearedAt > 0 && nowMs - h.appearedAt < MIN_DWELL_MS;\n  const targetOp = BASE_OP + (PEAK_OP - BASE_OP) * smoothstep(LO, HI, curLum);\n  const rivalDominates = !dwellActive && maxLum - curLum > RELOCATE_DELTA;\n\n  if (!h.relocTween || h.relocTween.done) {\n    if (h.appearedAt === 0) {\n      h.currentIdx = maxIdx; h.appearedAt = nowMs;\n      h.wanderS = 0; h.wanderTargetS = 0; h.wanderFrames = 0;\n      h.relocTween = tween(0, targetOp, RELOC_FADE_MS, ease.smoothstep);\n      tweenStart(h.relocTween, nowMs);\n    } else if (h.relocTween?.done && h.relocTween.to === 0) {\n      h.currentIdx = h.relocNextIdx; h.appearedAt = nowMs;\n      h.wanderS = 0; h.wanderTargetS = 0; h.wanderFrames = 0;\n      const np = perim[h.currentIdx];\n      const nl = sampleShaderLumAt(inst, np.x, np.y, halfWin);\n      const fadeInTarget = BASE_OP + (PEAK_OP - BASE_OP) * smoothstep(LO, HI, nl);\n      h.relocTween = tween(0, fadeInTarget, RELOC_FADE_MS, ease.smoothstep);\n      tweenStart(h.relocTween, nowMs);\n    } else if (rivalDominates) {\n      h.relocNextIdx = maxIdx;\n      h.relocTween = tween(h.glowOpacity, 0, RELOC_FADE_MS, ease.smoothstep);\n      tweenStart(h.relocTween, nowMs);\n    } else {\n      h.glowOpacity += (targetOp - h.glowOpacity) * FADE_RATE;\n    }\n  }\n\n  if (h.relocTween) {\n    h.glowOpacity = tweenTick(h.relocTween, nowMs);\n  }\n  h.glowOpacity = Math.max(0, Math.min(1, h.glowOpacity));\n\n  const ratio = shapePerim(W, H, R, h.kind) / rrPerim(REF_W, REF_H, REF_R);\n  const wanderRange = WANDER_RANGE * ratio;\n  if (h.wanderFrames++ >= WANDER_RETARGET) { h.wanderTargetS = (Math.random() * 2 - 1) * wanderRange; h.wanderFrames = 0; }\n  h.wanderS += (h.wanderTargetS - h.wanderS) * WANDER_LERP;\n\n  const blobArc = perim[h.currentIdx].arc + h.wanderS;\n\n  // INSET / EXTRA_OUTWARD are absolute SVG-unit offsets; multiply by the\n  // master scale so the catch-light sits at the right perpendicular distance\n  // when the host element is rendered at non-1× layout (e.g. CSS zoom: 2).\n  const insetS = INSET * h.scale;\n  sampleAtArc(blobArc, W, H, R, insetS, 0, h.kind, _pt);\n  const blobX = _pt.x, blobY = _pt.y;\n  const tangent = tangentAngleAtArc(blobArc, W, H, R, insetS, h.kind);\n  const tx = `translate(${blobX.toFixed(3)}px,${blobY.toFixed(3)}px) rotate(${tangent.toFixed(4)}rad)`;\n  h.haloInner.style.transform = tx;\n\n  const extraOut = EXTRA_OUTWARD * ratio * h.scale;\n  sampleAtArc(blobArc, W, H, R, insetS, extraOut, h.kind, _pt);\n  h.extraInner.style.transform = `translate(${_pt.x.toFixed(3)}px,${_pt.y.toFixed(3)}px) rotate(${tangent.toFixed(4)}rad)`;\n  h.fadeCircle.style.transform = `translate(${_pt.x.toFixed(3)}px,${_pt.y.toFixed(3)}px)`;\n\n  const light = theme === 'light';\n  const samp = light\n    ? sampleShaderRGBChromatic(inst, blobX, blobY, halfWin)\n    : sampleShaderRGBAt(inst, blobX, blobY, halfWin);\n\n  if (!h.tintTween) {\n    h.tintFrom = { ...samp }; h.tintTarget = { ...samp };\n    h.tintTween = tween(0, 1, TINT_FADE_MS);\n    tweenStart(h.tintTween, nowMs);\n    h.tintHoldUntil = light ? 0 : nowMs + TINT_HOLD_MS;\n  } else if (h.tintTween.done) {\n    if (light) {\n      h.tintFrom = {\n        r: h.tintFrom.r + (h.tintTarget.r - h.tintFrom.r) * h.tintTween.val,\n        g: h.tintFrom.g + (h.tintTarget.g - h.tintFrom.g) * h.tintTween.val,\n        b: h.tintFrom.b + (h.tintTarget.b - h.tintFrom.b) * h.tintTween.val,\n      };\n      h.tintTarget = { ...samp };\n      h.tintTween = tween(0, 1, TINT_FADE_MS);\n      tweenStart(h.tintTween, nowMs);\n    } else if (nowMs >= h.tintHoldUntil) {\n      h.tintFrom = { ...h.tintTarget };\n      h.tintTarget = { ...samp };\n      h.tintTween = tween(0, 1, TINT_FADE_MS);\n      tweenStart(h.tintTween, nowMs);\n      h.tintHoldUntil = nowMs + TINT_HOLD_MS;\n    }\n  }\n  tweenTick(h.tintTween!, nowMs);\n  const ft = h.tintTween!.val;\n\n  let tR: number, tG: number, tB: number;\n  if (light) {\n    tR = Math.round(h.tintFrom.r + (h.tintTarget.r - h.tintFrom.r) * ft);\n    tG = Math.round(h.tintFrom.g + (h.tintTarget.g - h.tintFrom.g) * ft);\n    tB = Math.round(h.tintFrom.b + (h.tintTarget.b - h.tintFrom.b) * ft);\n  } else {\n    const hR = h.tintFrom.r + (h.tintTarget.r - h.tintFrom.r) * ft;\n    const hG = h.tintFrom.g + (h.tintTarget.g - h.tintFrom.g) * ft;\n    const hB = h.tintFrom.b + (h.tintTarget.b - h.tintFrom.b) * ft;\n    const peak = Math.max(hR, hG, hB) || 1;\n    tR = Math.round(255 * (hR / peak)); tG = Math.round(255 * (hG / peak)); tB = Math.round(255 * (hB / peak));\n  }\n\n  const tinted = `rgb(${tR},${tG},${tB})`;\n  if (tinted !== h.lastHaloStroke) { h.lastHaloStroke = tinted; h.haloInner.style.stroke = tinted; }\n\n  if (light) {\n    const hsv = rgbToHsv(tR, tG, tB);\n    const [er, eg, eb] = hsvToRgb(hsv[0], Math.min(1, hsv[1] * LT_SAT_BOOST), Math.max(LT_MIN_VAL, hsv[2] * LT_VAL_MULT));\n    const extraTinted = `rgb(${er},${eg},${eb})`;\n    if (extraTinted !== h.lastExtraStroke) { h.lastExtraStroke = extraTinted; h.extraInner.style.stroke = extraTinted; }\n  } else if (h.lastExtraStroke !== '#ffffff') {\n    h.lastExtraStroke = '#ffffff'; h.extraInner.style.stroke = '#ffffff';\n  }\n\n  const m = Math.max(0, Math.min(1, strengthMul));\n  h.haloGroup.style.opacity = (h.glowOpacity * HALO_OP_MUL * m).toFixed(3);\n  h.extraGroup.style.opacity = Math.min(1, h.glowOpacity * EXTRA_INTENSITY * m).toFixed(3);\n}\n\nexport function resizeGlow(handles: GlowHandles, container: HTMLElement, opts: GlowOptions): GlowHandles {\n  for (const svg of Array.from(container.querySelectorAll('.metal-fx-glow-svg'))) {\n    if (svg.parentNode === container) container.removeChild(svg);\n  }\n  void handles;\n  return injectGlow(container, opts);\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/tween.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/tween.ts",
          "type": "registry:component",
          "content": "export type EaseFn = (t: number) => number;\n\nexport const ease = {\n  linear: (t: number) => t,\n  smoothstep: (t: number) => t * t * (3 - 2 * t),\n} as const;\n\nexport interface Tween {\n  from: number;\n  to: number;\n  dur: number;\n  ease: EaseFn;\n  startMs: number;\n  val: number;\n  done: boolean;\n}\n\nexport function tween(from: number, to: number, dur: number, e: EaseFn = ease.linear): Tween {\n  return { from, to, dur, ease: e, startMs: -1, val: from, done: false };\n}\n\nexport function tweenStart(tw: Tween, nowMs: number): void {\n  tw.startMs = nowMs;\n  tw.val = tw.from;\n  tw.done = false;\n}\n\nexport function tweenTick(tw: Tween, nowMs: number): number {\n  if (tw.done || tw.startMs < 0) return tw.val;\n  const t = Math.min(1, (nowMs - tw.startMs) / tw.dur);\n  tw.val = tw.from + (tw.to - tw.from) * tw.ease(t);\n  if (t >= 1) tw.done = true;\n  return tw.val;\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/glow/geometry.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/glow/geometry.ts",
          "type": "registry:component",
          "content": "/**\n * Pure geometry + SVG markup for the glow overlay.\n *\n * Perimeter math (rounded-rect / circle arc-length sampling), blob path\n * generation, SVG filter/mask construction, and HSV colour helpers.\n * No state — every function is a pure transform.\n */\nimport { PERIM_SAMPLES } from '../perfConfig';\n\nconst INSET = 1.5;\nconst EXTRA_SCALE = 1 / 3;\nconst EXTRA_STROKE_OUTER = 4.0 * EXTRA_SCALE;\nconst EXTRA_STROKE_CORE = 2.0 * EXTRA_SCALE;\nconst EXTRA_BLUR_OUTER = 2.0 * EXTRA_SCALE;\nconst EXTRA_BLUR_CORE = 1.35 * EXTRA_SCALE;\nconst EXTRA_FADE_R = 13.0 * EXTRA_SCALE;\n\nexport { PERIM_SAMPLES };\n\nexport interface GlowOptions {\n  width: number;\n  height: number;\n  cornerRadius: number;\n  kind: 'pill' | 'circle';\n  /** Master multiplier for absolute SVG units (stroke widths, blur,\n   *  fade-circle radius). 1 is the canonical 1× rendering. Set to 2 when\n   *  the host element is rendered at a 2× layout (e.g. CSS zoom: 2) so\n   *  the glow grows proportionally. */\n  scale?: number;\n}\nexport interface Pt { x: number; y: number }\nexport interface PerimSample extends Pt { arc: number }\n\nexport function rrPerim(w: number, h: number, r: number): number {\n  const rr = Math.max(0, Math.min(r, Math.min(w, h) / 2));\n  return 2 * Math.max(0, w - 2 * rr) + 2 * Math.max(0, h - 2 * rr) + 2 * Math.PI * rr;\n}\n\nexport function shapePerim(w: number, h: number, r: number, kind: 'pill' | 'circle'): number {\n  if (kind === 'circle') return 2 * Math.PI * Math.max(0, Math.min(r, Math.min(w, h) / 2));\n  return rrPerim(w, h, r);\n}\n\nexport function sampleAtArc(s: number, w: number, h: number, r: number, inset: number, outward: number, kind: 'pill' | 'circle', out?: Pt): Pt {\n  const o = out || { x: 0, y: 0 };\n  const rr = Math.max(0, Math.min(r, Math.min(w, h) / 2));\n  if (kind === 'circle') {\n    const perim = 2 * Math.PI * rr;\n    if (perim <= 0.0001) { o.x = w * 0.5; o.y = h * 0.5; return o; }\n    s = ((s % perim) + perim) % perim;\n    const theta = -Math.PI / 2 + (s / perim) * Math.PI * 2;\n    const rad = Math.max(0, rr - inset + outward);\n    o.x = w * 0.5 + rad * Math.cos(theta);\n    o.y = h * 0.5 + rad * Math.sin(theta);\n    return o;\n  }\n  const topLen = Math.max(0, w - 2 * rr), sideLen = Math.max(0, h - 2 * rr);\n  const arcLen = (Math.PI * rr) / 2;\n  const perim = 2 * (topLen + sideLen) + 4 * arcLen;\n  s = ((s % perim) + perim) % perim;\n  const rad = Math.max(0, rr - inset + outward);\n  let d = s;\n  if (d < topLen) { o.x = rr + d; o.y = inset - outward; return o; }\n  d -= topLen;\n  if (d < arcLen) {\n    const theta = -Math.PI / 2 + (arcLen > 0 ? d / arcLen : 0) * (Math.PI / 2);\n    o.x = (w - rr) + rad * Math.cos(theta); o.y = rr + rad * Math.sin(theta); return o;\n  }\n  d -= arcLen;\n  if (d < sideLen) { o.x = w - inset + outward; o.y = rr + d; return o; }\n  d -= sideLen;\n  if (d < arcLen) {\n    const theta = (arcLen > 0 ? d / arcLen : 0) * (Math.PI / 2);\n    o.x = (w - rr) + rad * Math.cos(theta); o.y = (h - rr) + rad * Math.sin(theta); return o;\n  }\n  d -= arcLen;\n  if (d < topLen) { o.x = w - rr - d; o.y = h - inset + outward; return o; }\n  d -= topLen;\n  if (d < arcLen) {\n    const theta = Math.PI / 2 + (arcLen > 0 ? d / arcLen : 0) * (Math.PI / 2);\n    o.x = rr + rad * Math.cos(theta); o.y = (h - rr) + rad * Math.sin(theta); return o;\n  }\n  d -= arcLen;\n  if (d < sideLen) { o.x = inset - outward; o.y = h - rr - d; return o; }\n  d -= sideLen;\n  const theta = Math.PI + (arcLen > 0 ? d / arcLen : 0) * (Math.PI / 2);\n  o.x = rr + rad * Math.cos(theta); o.y = rr + rad * Math.sin(theta);\n  return o;\n}\n\nexport function buildStaticBlobPath(halfLen: number, segments: number): string {\n  const step = (halfLen * 2) / segments;\n  let d = '';\n  for (let i = 0; i <= segments; i++) {\n    const x = -halfLen + i * step;\n    d += (i === 0 ? 'M ' : 'L ') + x.toFixed(3) + ' 0 ';\n  }\n  return d;\n}\n\nconst _ta: Pt = { x: 0, y: 0 };\nconst _tb: Pt = { x: 0, y: 0 };\n\nexport function tangentAngleAtArc(s: number, w: number, h: number, r: number, inset: number, kind: 'pill' | 'circle'): number {\n  const eps = 0.1;\n  sampleAtArc(s - eps, w, h, r, inset, 0, kind, _ta);\n  sampleAtArc(s + eps, w, h, r, inset, 0, kind, _tb);\n  return Math.atan2(_tb.y - _ta.y, _tb.x - _ta.x);\n}\n\nexport function smoothstep(a: number, b: number, x: number): number {\n  if (a === b) return x < a ? 0 : 1;\n  const t = Math.max(0, Math.min(1, (x - a) / (b - a)));\n  return t * t * (3 - 2 * t);\n}\n\nexport function buildPerimTable(opts: GlowOptions): PerimSample[] {\n  const perim = shapePerim(opts.width, opts.height, opts.cornerRadius, opts.kind);\n  const insetS = INSET * (opts.scale ?? 1);\n  const table: PerimSample[] = [];\n  for (let i = 0; i < PERIM_SAMPLES; i++) {\n    const arc = (i / PERIM_SAMPLES) * perim;\n    const pt = sampleAtArc(arc, opts.width, opts.height, opts.cornerRadius, insetS, 0, opts.kind);\n    table.push({ x: pt.x, y: pt.y, arc });\n  }\n  return table;\n}\n\nexport function buildSvgMarkup(opts: GlowOptions, p: string): string {\n  const { width: W, height: H, cornerRadius: R } = opts;\n  const s = opts.scale ?? 1;\n  const ringInset = opts.kind === 'circle' ? 2 : 1;\n  const innerR = Math.max(0, R - ringInset);\n  // Filter region grows with scale so blurred strokes don't get clipped at\n  // bigger sizes. The 200/540/440 baseline matches the canonical 1× pill.\n  const fX = (-200 * s).toFixed(0), fY = fX;\n  const fW = (540 * s).toFixed(0), fH = (440 * s).toFixed(0);\n  const fRect = `x=\"${fX}\" y=\"${fY}\" width=\"${fW}\" height=\"${fH}\"`;\n  const fr = `${fRect} filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"`;\n  // Stroke widths and blur stdDeviations are absolute SVG units; multiply\n  // by `s` so they remain proportional when viewBox grows with the host.\n  const sw = (n: number) => (n * s).toFixed(3);\n  const sd = (n: number) => (n * s).toFixed(3);\n  return [\n    '<defs>',\n    `<filter id=\"${p}_bXl\" ${fr}><feGaussianBlur stdDeviation=\"${sd(8.4)}\"/></filter>`,\n    `<filter id=\"${p}_bLg\" ${fr}><feGaussianBlur stdDeviation=\"${sd(4.8)}\"/></filter>`,\n    `<filter id=\"${p}_bMd\" ${fr}><feGaussianBlur stdDeviation=\"${sd(2.1)}\"/></filter>`,\n    `<filter id=\"${p}_bSm\" ${fr}><feGaussianBlur stdDeviation=\"${sd(0.9)}\"/></filter>`,\n    `<filter id=\"${p}_ebO\" ${fr}><feGaussianBlur stdDeviation=\"${sd(EXTRA_BLUR_OUTER)}\"/></filter>`,\n    `<filter id=\"${p}_ebC\" ${fr}><feGaussianBlur stdDeviation=\"${sd(EXTRA_BLUR_CORE)}\"/></filter>`,\n    `<radialGradient id=\"${p}_fg\" cx=\"0.5\" cy=\"0.5\" r=\"0.5\"><stop offset=\"0\" stop-color=\"white\"/><stop offset=\"0.30\" stop-color=\"white\"/><stop offset=\"0.65\" stop-color=\"#404040\"/><stop offset=\"1\" stop-color=\"black\"/></radialGradient>`,\n    `<mask id=\"${p}_fm\" maskUnits=\"userSpaceOnUse\" ${fRect}><rect ${fRect} fill=\"black\"/><circle id=\"${p}_fc\" cx=\"0\" cy=\"0\" r=\"${(EXTRA_FADE_R * s).toFixed(3)}\" fill=\"url(#${p}_fg)\"/></mask>`,\n    `<mask id=\"${p}_rm\" maskUnits=\"userSpaceOnUse\" ${fRect}><rect ${fRect} fill=\"#808080\"/><rect x=\"0\" y=\"0\" width=\"${W}\" height=\"${H}\" rx=\"${R}\" ry=\"${R}\" fill=\"white\"/><rect x=\"${ringInset}\" y=\"${ringInset}\" width=\"${W - ringInset * 2}\" height=\"${H - ringInset * 2}\" rx=\"${innerR}\" ry=\"${innerR}\" fill=\"black\"/></mask>`,\n    '</defs>',\n    // Safari clips mask to the masked element's bbox; our horizontal strokes\n    // have zero height, so the mask becomes a sliver. These spacer rects\n    // inflate the bbox to the full filter region.\n    `<g id=\"${p}_h\" mask=\"url(#${p}_rm)\" opacity=\"0\">`,\n    `<rect ${fRect} fill=\"none\" pointer-events=\"none\"/>`,\n    `<g id=\"${p}_hI\" stroke=\"white\">`,\n    `<path id=\"${p}_pXl\" stroke-width=\"${sw(26.4)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"0.385\" filter=\"url(#${p}_bXl)\"/>`,\n    `<path id=\"${p}_pLg\" stroke-width=\"${sw(15.6)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"0.595\" filter=\"url(#${p}_bLg)\"/>`,\n    `<path id=\"${p}_pMd\" stroke-width=\"${sw(7.2)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"0.70\" filter=\"url(#${p}_bMd)\"/>`,\n    `<path id=\"${p}_pSm\" stroke-width=\"${sw(3.0)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"0.70\" filter=\"url(#${p}_bSm)\"/>`,\n    '</g></g>',\n    `<g id=\"${p}_e\" mask=\"url(#${p}_rm)\" opacity=\"0\">`,\n    `<rect ${fRect} fill=\"none\" pointer-events=\"none\"/>`,\n    `<g mask=\"url(#${p}_fm)\">`,\n    `<g id=\"${p}_eI\" stroke=\"white\">`,\n    `<path id=\"${p}_eO\" stroke-width=\"${sw(EXTRA_STROKE_OUTER)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"0.85\" filter=\"url(#${p}_ebO)\"/>`,\n    `<path id=\"${p}_eC\" stroke-width=\"${sw(EXTRA_STROKE_CORE)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"1.0\" filter=\"url(#${p}_ebC)\"/>`,\n    '</g></g></g>',\n  ].join('');\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/reflection/paint.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/reflection/paint.ts",
          "type": "registry:component",
          "content": "/** Proximity reflection — public API and per-frame paint loop. */\nimport type { MetalFxInstance } from '../renderer/core';\nimport {\n  ATTACH_RANGE_PX,\n  BASE_ALPHA,\n  BOOST_ALPHA,\n  BORDER_HILITE_ALPHA,\n  BORDER_HILITE_PX,\n  FILL_CIRCLE_ATTENUATION,\n  FILL_EXTRA_ALPHA,\n  FILL_OPACITY_MUL,\n  GLOBAL_ATTENUATION,\n  GRAD_FAR,\n  GRAD_MID,\n  GRAD_NEAR,\n  OVERLAP_MIN_PX,\n  INTENSITY_MULT,\n  MAX_ALPHA_STACK,\n  RANGE_PX,\n  REF_DRAW_CSS_W,\n  REFLECTION_BLOCKED_TAGS,\n  STROKE_CSS_PX,\n  STROKE_EXTRA_ALPHA,\n  type ReflectionTarget,\n} from './constants';\nimport {\n  type BoxRect,\n  type DrawDst,\n  drawBorderHighlight,\n  isHorizontalNeighbour,\n  isVerticalNeighbour,\n  maskedFillPasses,\n  maskedStrokePasses,\n  shortestRectDistance,\n} from './geometry';\nimport { attachObservers, detachObservers, readCornerRadius, readHairlineSpec } from './observers';\n\nexport type { ReflectionTarget } from './constants';\n\nconst targets: Set<ReflectionTarget> = new Set();\n\nexport function addReflectionTarget(\n  el: HTMLElement,\n  anchor: MetalFxInstance,\n  anchorEl: HTMLElement\n): ReflectionTarget | null {\n  if (typeof document === 'undefined') return null;\n  if (REFLECTION_BLOCKED_TAGS.has(el.tagName)) return null;\n  for (const existing of targets) {\n    if (existing.el === el) return existing;\n  }\n\n  const wrap = document.createElement('div');\n  wrap.setAttribute('data-metal-fx-reflection', '');\n  wrap.setAttribute('aria-hidden', 'true');\n\n  const canvas = document.createElement('canvas');\n  canvas.className = 'metal-fx-reflection-canvas';\n  const ctx = canvas.getContext('2d', { alpha: true });\n  if (!ctx) return null;\n\n  const strokeCanvas = document.createElement('canvas');\n  strokeCanvas.className = 'metal-fx-reflection-stroke-canvas';\n  const strokeCtx = strokeCanvas.getContext('2d', { alpha: true });\n  if (!strokeCtx) return null;\n\n  wrap.appendChild(canvas);\n  wrap.appendChild(strokeCanvas);\n\n  const cs = getComputedStyle(el);\n  let appliedPositionRelative = false;\n  if (cs.position === 'static') {\n    el.style.position = 'relative';\n    appliedPositionRelative = true;\n  }\n  let appliedIsolation = false;\n  if (cs.isolation !== 'isolate') {\n    el.style.isolation = 'isolate';\n    appliedIsolation = true;\n  }\n  el.setAttribute('data-metal-fx-reflect-host', '');\n  el.insertBefore(wrap, el.firstChild);\n\n  const initialSpec = readHairlineSpec(el);\n  const target: ReflectionTarget = {\n    el,\n    anchor,\n    anchorEl,\n    wrap,\n    canvas,\n    ctx,\n    strokeCanvas,\n    strokeCtx,\n    cornerRadius: readCornerRadius(el),\n    hairlineWidth: initialSpec.width,\n    hairlineOuterCssPx: initialSpec.outerCssPx,\n    appliedPositionRelative,\n    appliedIsolation,\n    resizeObserver: null,\n    mutationObserver: null,\n  };\n  attachObservers(target);\n  targets.add(target);\n  return target;\n}\n\nexport function removeReflectionTarget(el: HTMLElement): void {\n  for (const target of targets) {\n    if (target.el === el) {\n      detachObservers(target);\n      target.canvas.width = 0;\n      target.canvas.height = 0;\n      target.strokeCanvas.width = 0;\n      target.strokeCanvas.height = 0;\n      if (target.wrap.parentNode === target.el) {\n        target.el.removeChild(target.wrap);\n      }\n      target.el.removeAttribute('data-metal-fx-reflect-host');\n      if (target.appliedPositionRelative) target.el.style.position = '';\n      if (target.appliedIsolation) target.el.style.isolation = '';\n      targets.delete(target);\n      return;\n    }\n  }\n}\n\nexport function paintReflections(): void {\n  if (targets.size === 0) return;\n  const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n\n  const anchorRects = new Map<HTMLElement, DOMRect>();\n\n  for (const t of targets) {\n    const tRect = t.el.getBoundingClientRect();\n    let aRect = anchorRects.get(t.anchorEl);\n    if (!aRect) {\n      aRect = t.anchorEl.getBoundingClientRect();\n      anchorRects.set(t.anchorEl, aRect);\n    }\n    if (tRect.width < 1 || tRect.height < 1) continue;\n    if (aRect.width < 1 || aRect.height < 1) continue;\n\n    if (\n      !isHorizontalNeighbour(aRect, tRect, OVERLAP_MIN_PX, ATTACH_RANGE_PX) &&\n      !isVerticalNeighbour(aRect, tRect, OVERLAP_MIN_PX, ATTACH_RANGE_PX)\n    ) {\n      if (t.canvas.width !== 1) { t.canvas.width = 1; t.canvas.height = 1; }\n      if (t.strokeCanvas.width !== 1) { t.strokeCanvas.width = 1; t.strokeCanvas.height = 1; }\n      continue;\n    }\n\n    const anchorCanvas = t.anchor.canvas;\n    const sw = anchorCanvas.width | 0;\n    const sh = anchorCanvas.height | 0;\n    if (sw < 4 || sh < 4) continue;\n\n    const acx = (aRect.left + aRect.right) * 0.5;\n    const acy = (aRect.top + aRect.bottom) * 0.5;\n    const tcx = (tRect.left + tRect.right) * 0.5;\n    const tcy = (tRect.top + tRect.bottom) * 0.5;\n    const dx = acx - tcx;\n    const dy = acy - tcy;\n\n    const edgeGapH = Math.max(aRect.left - tRect.right, tRect.left - aRect.right, 0);\n    const edgeGapV = Math.max(aRect.top - tRect.bottom, tRect.top - aRect.bottom, 0);\n    const isHorizontalLayout = edgeGapH >= edgeGapV;\n\n    const dist = shortestRectDistance(aRect, tRect);\n    let proximity = 1 - Math.min(1, dist / RANGE_PX);\n    proximity = proximity * proximity * (3 - 2 * proximity);\n    const intensity = BASE_ALPHA + (BOOST_ALPHA - BASE_ALPHA) * proximity;\n\n    const reflectionAlpha = Math.min(\n      MAX_ALPHA_STACK,\n      intensity * INTENSITY_MULT * GLOBAL_ATTENUATION\n    );\n\n    // Effective scale of the host element. Anything drawn on the reflection\n    // canvas (strokes, border-highlight) is in DEVICE pixels, so it doesn't\n    // automatically grow when the host is rendered at non-1× layout (CSS\n    // zoom: 2, etc.). Multiply absolute-pixel constants by the anchor's\n    // scale so the reflection scales together with the metal effect itself.\n    const sScale = t.anchor.scale ?? 1;\n    const hairlineCssPx = Math.max(STROKE_CSS_PX * sScale, t.hairlineWidth);\n    const strokeBandPx = Math.max(1, Math.round(hairlineCssPx * dpr));\n    const borderHighlightPx = Math.max(\n      1,\n      Math.round(Math.max(BORDER_HILITE_PX * sScale, t.hairlineWidth) * dpr)\n    );\n\n    const overscanCssPx = t.hairlineOuterCssPx;\n    t.wrap.style.inset = `${-overscanCssPx}px`;\n    t.wrap.style.borderRadius = `${Math.max(0, t.cornerRadius)}px`;\n\n    const tw = Math.max(1, Math.round((tRect.width + overscanCssPx * 2) * dpr));\n    const th = Math.max(1, Math.round((tRect.height + overscanCssPx * 2) * dpr));\n    if (t.canvas.width !== tw) t.canvas.width = tw;\n    if (t.canvas.height !== th) t.canvas.height = th;\n    if (t.strokeCanvas.width !== tw) t.strokeCanvas.width = tw;\n    if (t.strokeCanvas.height !== th) t.strokeCanvas.height = th;\n\n    const ctx = t.ctx;\n    ctx.setTransform(1, 0, 0, 1, 0, 0);\n    ctx.clearRect(0, 0, tw, th);\n    const strokeCtx = t.strokeCtx;\n    strokeCtx.setTransform(1, 0, 0, 1, 0, 0);\n    strokeCtx.clearRect(0, 0, tw, th);\n\n    const bandDevPx = Math.min(RANGE_PX * dpr, Math.max(tw, th));\n    let g0x: number, g0y: number, g1x: number, g1y: number;\n    if (isHorizontalLayout) {\n      g0x = dx > 0 ? tw : 0; g1x = dx > 0 ? tw - bandDevPx : bandDevPx;\n      g0y = th * 0.5; g1y = th * 0.5;\n    } else {\n      g0y = dy > 0 ? th : 0; g1y = dy > 0 ? th - bandDevPx : bandDevPx;\n      g0x = tw * 0.5; g1x = tw * 0.5;\n    }\n    const grad = ctx.createLinearGradient(g0x, g0y, g1x, g1y);\n    grad.addColorStop(0, `rgba(0,0,0,${GRAD_NEAR})`);\n    grad.addColorStop(0.5, `rgba(0,0,0,${GRAD_MID})`);\n    grad.addColorStop(1, `rgba(0,0,0,${GRAD_FAR})`);\n\n    const anchorCssW = sw / dpr;\n    const refWdpr = Math.max(1, Math.round(REF_DRAW_CSS_W * Math.max(0.1, anchorCssW / 140) * dpr));\n\n    let drawX: number, drawY: number, drawW: number, drawH: number;\n    let flipX = false, flipY = false;\n    if (isHorizontalLayout) {\n      const overlapTop = Math.max(aRect.top, tRect.top);\n      const overlapBot = Math.min(aRect.bottom, tRect.bottom);\n      flipX = true;\n      drawX = dx > 0 ? tw - refWdpr : 0;\n      drawY = Math.round((overlapTop - tRect.top + overscanCssPx) * dpr);\n      drawW = refWdpr;\n      drawH = Math.max(1, Math.round((overlapBot - overlapTop) * dpr));\n    } else {\n      const overlapLeft = Math.max(aRect.left, tRect.left);\n      const overlapRight = Math.min(aRect.right, tRect.right);\n      flipY = true;\n      drawX = Math.round((overlapLeft - tRect.left + overscanCssPx) * dpr);\n      drawY = dy > 0 ? th - refWdpr : 0;\n      drawW = Math.max(1, Math.round((overlapRight - overlapLeft) * dpr));\n      drawH = refWdpr;\n    }\n    const drawDst: DrawDst = { x: drawX, y: drawY, w: drawW, h: drawH, flipX, flipY };\n\n    const strokeBox: BoxRect = { x: 0, y: 0, w: tw, h: th, r: Math.max(0, t.cornerRadius * dpr) };\n\n    const fillReflectionAlpha = Math.min(\n      MAX_ALPHA_STACK,\n      reflectionAlpha * FILL_EXTRA_ALPHA * FILL_OPACITY_MUL * FILL_CIRCLE_ATTENUATION\n    );\n    maskedFillPasses(ctx, anchorCanvas, sw, sh, tw, th, fillReflectionAlpha, grad, drawDst, strokeBox, dpr);\n\n    maskedStrokePasses(\n      strokeCtx, anchorCanvas, sw, sh, tw, th,\n      strokeBox, reflectionAlpha, strokeBandPx, grad, STROKE_EXTRA_ALPHA, drawDst\n    );\n\n    drawBorderHighlight(\n      strokeCtx, strokeBox, borderHighlightPx,\n      g0x, g0y, g1x, g1y,\n      Math.min(0.85, BORDER_HILITE_ALPHA * reflectionAlpha)\n    );\n\n    ctx.globalCompositeOperation = 'source-over';\n    strokeCtx.globalCompositeOperation = 'source-over';\n  }\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/reflection/constants.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/reflection/constants.ts",
          "type": "registry:component",
          "content": "/**\n * Canonical constants and types for proximity reflections.\n *\n * Verbatim from `Image loader/index.html` L5851-5915. Shared across\n * the observer, geometry, and paint modules.\n */\nimport type { MetalFxInstance } from '../renderer/core';\n\nexport const RANGE_PX = 12;\nexport const ATTACH_RANGE_PX = 32;\nexport const OVERLAP_MIN_PX = 1;\nexport const BASE_ALPHA = 0.55;\nexport const BOOST_ALPHA = 1.0;\nexport const GRAD_NEAR = 1.0;\nexport const GRAD_MID = 0.85;\nexport const GRAD_FAR = 0.0;\nexport const INTENSITY_MULT = 1.3;\nexport const MAX_ALPHA_STACK = 3.6;\nexport const GLOBAL_ATTENUATION = 0.7;\nexport const STROKE_CSS_PX = 1;\nexport const STROKE_EXTRA_ALPHA = 0.52;\nexport const BORDER_HILITE_PX = 1.0;\nexport const BORDER_HILITE_ALPHA = 0.044;\nexport const REF_DRAW_CSS_W = 235;\nexport const FILL_EXTRA_ALPHA = 2.535;\nexport const FILL_OPACITY_MUL = 0.7;\nexport const FILL_CIRCLE_ATTENUATION = 0.5;\n\nexport const REFLECTION_BLOCKED_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT', 'OPTION']);\n\nexport interface ReflectionTarget {\n  el: HTMLElement;\n  anchor: MetalFxInstance;\n  anchorEl: HTMLElement;\n  wrap: HTMLDivElement;\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  strokeCanvas: HTMLCanvasElement;\n  strokeCtx: CanvasRenderingContext2D;\n  cornerRadius: number;\n  hairlineWidth: number;\n  hairlineOuterCssPx: number;\n  appliedPositionRelative: boolean;\n  appliedIsolation: boolean;\n  resizeObserver: ResizeObserver | null;\n  mutationObserver: MutationObserver | null;\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/reflection/geometry.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/reflection/geometry.ts",
          "type": "registry:component",
          "content": "/**\n * Canvas 2D drawing primitives for proximity reflections.\n *\n * All the low-level compositing passes — rounded-rect paths, ring clips,\n * fill/stroke multi-pass alpha stacking, mirror-flip drawImage, and the\n * border-highlight gradient stroke.\n */\nimport { RANGE_PX } from './constants';\n\n// ─── Layout helpers ───────────────────────────────────────────────────────\n\nexport function shortestRectDistance(a: DOMRect, b: DOMRect): number {\n  const dx = Math.max(a.left - b.right, b.left - a.right, 0);\n  const dy = Math.max(a.top - b.bottom, b.top - a.bottom, 0);\n  return Math.sqrt(dx * dx + dy * dy);\n}\n\nexport function isHorizontalNeighbour(anchorRect: DOMRect, targetRect: DOMRect, overlapMin: number, attachRange: number): boolean {\n  const verticalOverlap =\n    Math.min(anchorRect.bottom, targetRect.bottom) -\n    Math.max(anchorRect.top, targetRect.top);\n  if (verticalOverlap < overlapMin) return false;\n  const horizontalGap = Math.max(\n    anchorRect.left - targetRect.right,\n    targetRect.left - anchorRect.right,\n    0\n  );\n  if (horizontalGap > attachRange) return false;\n  return true;\n}\n\nexport function isVerticalNeighbour(anchorRect: DOMRect, targetRect: DOMRect, overlapMin: number, attachRange: number): boolean {\n  const horizontalOverlap =\n    Math.min(anchorRect.right, targetRect.right) -\n    Math.max(anchorRect.left, targetRect.left);\n  if (horizontalOverlap < overlapMin) return false;\n  const verticalGap = Math.max(\n    anchorRect.top - targetRect.bottom,\n    targetRect.top - anchorRect.bottom,\n    0\n  );\n  return verticalGap <= attachRange;\n}\n\n// ─── Path helpers ─────────────────────────────────────────────────────────\n\nexport function roundRectPath(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  w: number,\n  h: number,\n  r: number\n): void {\n  const rr = Math.max(0, Math.min(r, w * 0.5, h * 0.5));\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const native = (ctx as any).roundRect;\n  if (typeof native === 'function') {\n    native.call(ctx, x, y, w, h, rr);\n    return;\n  }\n  ctx.moveTo(x + rr, y);\n  ctx.lineTo(x + w - rr, y);\n  ctx.quadraticCurveTo(x + w, y, x + w, y + rr);\n  ctx.lineTo(x + w, y + h - rr);\n  ctx.quadraticCurveTo(x + w, y + h, x + w - rr, y + h);\n  ctx.lineTo(x + rr, y + h);\n  ctx.quadraticCurveTo(x, y + h, x, y + h - rr);\n  ctx.lineTo(x, y + rr);\n  ctx.quadraticCurveTo(x, y, x + rr, y);\n}\n\n// ─── Draw source (mirror flip) ───────────────────────────────────────────\n\nexport interface DrawDst {\n  x: number;\n  y: number;\n  w: number;\n  h: number;\n  flipX: boolean;\n  flipY: boolean;\n}\n\nexport function drawSource(\n  ctx: CanvasRenderingContext2D,\n  src: CanvasImageSource,\n  sw: number,\n  sh: number,\n  dst: DrawDst\n): void {\n  if (!dst.flipX && !dst.flipY) {\n    ctx.drawImage(src, 0, 0, sw, sh, dst.x, dst.y, dst.w, dst.h);\n    return;\n  }\n  ctx.save();\n  if (dst.flipX) {\n    ctx.translate(dst.x + dst.w, 0);\n    ctx.scale(-1, 1);\n  }\n  if (dst.flipY) {\n    ctx.translate(0, dst.y + dst.h);\n    ctx.scale(1, -1);\n  }\n  ctx.drawImage(\n    src,\n    0,\n    0,\n    sw,\n    sh,\n    dst.flipX ? 0 : dst.x,\n    dst.flipY ? 0 : dst.y,\n    dst.w,\n    dst.h\n  );\n  ctx.restore();\n}\n\n// ─── Clip + compositing passes ────────────────────────────────────────────\n\nexport interface BoxRect {\n  x: number;\n  y: number;\n  w: number;\n  h: number;\n  r: number;\n}\n\nconst FILL_BLUR_CSS_PX = 4;\n\nfunction fillRingClip(\n  ctx: CanvasRenderingContext2D,\n  x: number, y: number, w: number, h: number,\n  radiusDevPx: number, bandDevPx: number\n): void {\n  if (w <= 2 * bandDevPx || h <= 2 * bandDevPx) {\n    ctx.beginPath();\n    roundRectPath(ctx, x, y, w, h, radiusDevPx);\n    ctx.clip();\n    return;\n  }\n  ctx.beginPath();\n  roundRectPath(ctx, x, y, w, h, radiusDevPx);\n  roundRectPath(ctx, x + bandDevPx, y + bandDevPx, w - 2 * bandDevPx, h - 2 * bandDevPx, Math.max(0, radiusDevPx - bandDevPx));\n  ctx.clip('evenodd');\n}\n\nexport function maskedFillPasses(\n  ctx: CanvasRenderingContext2D,\n  src: CanvasImageSource,\n  sw: number, sh: number,\n  tw: number, th: number,\n  totalAlpha: number,\n  grad: CanvasGradient,\n  dst: DrawDst,\n  fillBox: BoxRect,\n  dpr: number\n): void {\n  const fillBandDevPx = Math.max(1, Math.round((RANGE_PX + FILL_BLUR_CSS_PX * 3) * dpr));\n  let remaining = Math.max(0, totalAlpha);\n  let firstChunk = true;\n  for (let i = 0; i < 3 && remaining > 1e-4; i++) {\n    const a = Math.min(1, remaining);\n    ctx.save();\n    fillRingClip(ctx, fillBox.x, fillBox.y, fillBox.w, fillBox.h, fillBox.r, fillBandDevPx);\n    ctx.globalCompositeOperation = firstChunk ? 'source-over' : 'lighter';\n    firstChunk = false;\n    ctx.globalAlpha = a;\n    drawSource(ctx, src, sw, sh, dst);\n    ctx.globalAlpha = 1;\n    ctx.globalCompositeOperation = 'destination-in';\n    ctx.fillStyle = grad;\n    ctx.fillRect(0, 0, tw, th);\n    ctx.restore();\n    remaining -= a;\n  }\n}\n\nfunction insideStrokeEvenOddClip(\n  ctx: CanvasRenderingContext2D,\n  x: number, y: number, w: number, h: number,\n  radiusDevPx: number, strokeDevPx: number\n): void {\n  const r = strokeDevPx | 0;\n  if (r < 1 || w <= 2 * r || h <= 2 * r) {\n    ctx.beginPath();\n    roundRectPath(ctx, x, y, w, h, radiusDevPx);\n    ctx.clip();\n    return;\n  }\n  ctx.beginPath();\n  roundRectPath(ctx, x, y, w, h, radiusDevPx);\n  roundRectPath(ctx, x + r, y + r, w - 2 * r, h - 2 * r, Math.max(0, radiusDevPx - r));\n  ctx.clip('evenodd');\n}\n\nexport function maskedStrokePasses(\n  ctx: CanvasRenderingContext2D,\n  src: CanvasImageSource,\n  sw: number, sh: number,\n  tw: number, th: number,\n  strokeBox: BoxRect,\n  intensity: number,\n  strokeBandPx: number,\n  grad: CanvasGradient,\n  strokeExtraAlpha: number,\n  dst: DrawDst\n): void {\n  let remaining = intensity * strokeExtraAlpha;\n  let firstChunk = true;\n  for (let i = 0; i < 3 && remaining > 1e-4; i++) {\n    const a = Math.min(1, remaining);\n    ctx.save();\n    insideStrokeEvenOddClip(ctx, strokeBox.x, strokeBox.y, strokeBox.w, strokeBox.h, strokeBox.r, strokeBandPx);\n    ctx.globalCompositeOperation = firstChunk ? 'source-over' : 'lighter';\n    firstChunk = false;\n    ctx.globalAlpha = a;\n    drawSource(ctx, src, sw, sh, dst);\n    ctx.globalAlpha = 1;\n    ctx.globalCompositeOperation = 'destination-in';\n    ctx.fillStyle = grad;\n    ctx.fillRect(0, 0, tw, th);\n    ctx.restore();\n    remaining -= a;\n  }\n}\n\nexport function drawBorderHighlight(\n  ctx: CanvasRenderingContext2D,\n  strokeBox: BoxRect,\n  strokeDevPx: number,\n  g0x: number, g0y: number,\n  g1x: number, g1y: number,\n  alpha: number\n): void {\n  const grad = ctx.createLinearGradient(g0x, g0y, g1x, g1y);\n  grad.addColorStop(0, `rgba(255,255,255,${alpha.toFixed(3)})`);\n  grad.addColorStop(0.5, `rgba(255,255,255,${(alpha * 0.45).toFixed(3)})`);\n  grad.addColorStop(1, 'rgba(255,255,255,0)');\n\n  ctx.save();\n  insideStrokeEvenOddClip(ctx, strokeBox.x, strokeBox.y, strokeBox.w, strokeBox.h, strokeBox.r, strokeDevPx);\n  ctx.globalCompositeOperation = 'lighter';\n  ctx.lineWidth = strokeDevPx * 2;\n  ctx.strokeStyle = grad;\n  ctx.beginPath();\n  roundRectPath(ctx, strokeBox.x, strokeBox.y, strokeBox.w, strokeBox.h, strokeBox.r);\n  ctx.stroke();\n  ctx.restore();\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/reflection/observers.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/reflection/observers.ts",
          "type": "registry:component",
          "content": "/**\n * Style observation for reflection targets.\n *\n * Reads corner radii and hairline specs from computed styles, and\n * attaches ResizeObserver / MutationObserver so values stay fresh\n * without per-frame getComputedStyle calls.\n */\nimport type { ReflectionTarget } from './constants';\n\nexport function readCornerRadius(el: HTMLElement): number {\n  const cs = getComputedStyle(el);\n  const radii = [\n    parseFloat(cs.borderTopLeftRadius) || 0,\n    parseFloat(cs.borderTopRightRadius) || 0,\n    parseFloat(cs.borderBottomRightRadius) || 0,\n    parseFloat(cs.borderBottomLeftRadius) || 0,\n  ].filter((v) => v > 0);\n  return radii.length ? Math.min.apply(null, radii) : 0;\n}\n\n/**\n * Read the visible \"hairline\" geometry of the host so the 1-px stroke\n * reflection sits exactly on the host's existing ring.\n *\n * Returns the visible thickness (`width`) and the OUTWARD extent past the\n * padding-box edge (`outerCssPx`) — the wrap is overscanned by `outerCssPx`\n * on every side so its outer rim lines up with the host's visible silhouette.\n *\n * Source contributions:\n *   - CSS `border-*-width` (max across the 4 sides)\n *   - smallest `inset` `box-shadow` with spread > 0\n *   - smallest outset `box-shadow` with spread > 0\n */\nexport function readHairlineSpec(el: HTMLElement): { width: number; outerCssPx: number } {\n  const cs = getComputedStyle(el);\n  const borderMax = Math.max(\n    parseFloat(cs.borderTopWidth) || 0,\n    parseFloat(cs.borderRightWidth) || 0,\n    parseFloat(cs.borderBottomWidth) || 0,\n    parseFloat(cs.borderLeftWidth) || 0\n  );\n\n  let smallestInsetSpread = 0;\n  let smallestOutsetSpread = 0;\n  const shadow = cs.boxShadow;\n  if (shadow && shadow !== 'none') {\n    const safe = shadow.replace(/rgba?\\([^)]*\\)/g, (m) => m.replace(/,/g, '\\u0000'));\n    const parts = safe.split(/,\\s*/);\n    let inset = Infinity;\n    let outset = Infinity;\n    for (const part of parts) {\n      const nums = part.match(/-?\\d+(?:\\.\\d+)?px/g);\n      if (!nums || nums.length < 4) continue;\n      const spread = parseFloat(nums[3]);\n      if (!(spread > 0)) continue;\n      if (/\\binset\\b/.test(part)) {\n        if (spread < inset) inset = spread;\n      } else if (spread < outset) {\n        outset = spread;\n      }\n    }\n    if (Number.isFinite(inset)) smallestInsetSpread = inset;\n    if (Number.isFinite(outset)) smallestOutsetSpread = outset;\n  }\n\n  const outerCssPx = Math.max(borderMax, smallestOutsetSpread);\n  const width =\n    Math.max(borderMax, smallestInsetSpread, smallestOutsetSpread) || 1;\n\n  return { width, outerCssPx };\n}\n\nfunction refreshTargetStyles(t: ReflectionTarget): void {\n  t.cornerRadius = readCornerRadius(t.el);\n  const spec = readHairlineSpec(t.el);\n  t.hairlineWidth = spec.width;\n  t.hairlineOuterCssPx = spec.outerCssPx;\n}\n\nexport function attachObservers(t: ReflectionTarget): void {\n  if (typeof ResizeObserver !== 'undefined') {\n    t.resizeObserver = new ResizeObserver(() => refreshTargetStyles(t));\n    t.resizeObserver.observe(t.el);\n  }\n  if (typeof MutationObserver !== 'undefined') {\n    t.mutationObserver = new MutationObserver(() => refreshTargetStyles(t));\n    t.mutationObserver.observe(t.el, {\n      attributes: true,\n      attributeFilter: ['style', 'class'],\n    });\n  }\n}\n\nexport function detachObservers(t: ReflectionTarget): void {\n  t.resizeObserver?.disconnect();\n  t.resizeObserver = null;\n  t.mutationObserver?.disconnect();\n  t.mutationObserver = null;\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/engine/reflection/reflectionScheduler.ts",
          "target": "@components/effects/metal-fx-v1/upstream/engine/reflection/reflectionScheduler.ts",
          "type": "registry:component",
          "content": "/**\n * Auxiliary RAF driver for *target-side* work (currently: dark-mode reflections).\n *\n * Reflections run at 15 fps — the CSS blur(4px) on the fill canvas hides\n * temporal stepping completely. The scheduler coalesces rapid calls and\n * skips frames that arrive faster than the target interval.\n */\nimport { REFLECTION_INTERVAL_MS } from '../perfConfig';\nimport { paintReflections } from './paint';\n\nlet scheduled = false;\nlet lastReflectionMs = 0;\n\nexport function scheduleReflectionPaint(): void {\n  if (scheduled) return;\n  scheduled = true;\n  if (typeof requestAnimationFrame === 'undefined') return;\n  requestAnimationFrame((now) => {\n    scheduled = false;\n    if (now - lastReflectionMs < REFLECTION_INTERVAL_MS) return;\n    lastReflectionMs = now;\n    paintReflections();\n  });\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/styles.ts",
          "target": "@components/effects/metal-fx-v1/upstream/styles.ts",
          "type": "registry:component",
          "content": "const STYLE_ID = 'metal-fx-styles';\n\nconst CSS = /* css */ `\n.metal-fx-root {\n  position: relative;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  isolation: isolate;\n  overflow: visible;\n  background: #272727;\n  color: #f8f8f8;\n}\n.metal-fx-root[data-theme='light'] {\n  background: #ffffff;\n  color: #1d1d1d;\n}\n\n.metal-fx-root::before {\n  content: '';\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  pointer-events: none;\n  z-index: 2;\n  box-shadow: inset 0 0 50px 0 rgba(255, 255, 255, 0.02);\n}\n.metal-fx-root[data-theme='light']::before {\n  box-shadow: inset 0 0 50px 0 rgba(0, 0, 0, 0.02);\n}\n\n.metal-fx-root::after {\n  content: '';\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  pointer-events: none;\n  z-index: 4;\n  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);\n}\n.metal-fx-root[data-theme='light']::after {\n  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06);\n}\n/* Circle variant gets a thicker outer rim than the button variant. */\n.metal-fx-root[data-variant='circle']::after {\n  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.1);\n}\n.metal-fx-root[data-theme='light'][data-variant='circle']::after {\n  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.06);\n}\n\n.metal-fx-canvas {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  display: block;\n  z-index: 0;\n  pointer-events: none;\n  border-radius: inherit;\n}\n\n/* The inner spacer — defines the inset geometry where the metal ring meets\n   the interior (3 px for Button, 1-2 px for Circle) and carries the Circle dark\n   hairline ('box-shadow: inset' rules below). Intentionally transparent so\n   the wrapper's background propagates through to the punched shader centre,\n   giving consumers a single surface tone to override. See \"Single-surface\n   background\" in the file header for the rationale. */\n.metal-fx-inner {\n  position: absolute;\n  inset: 3px;\n  border-radius: inherit;\n  z-index: 1;\n  pointer-events: none;\n}\n\n.metal-fx-root[data-variant='button'][data-shape='pill'] .metal-fx-inner {\n  border-radius: calc(var(--mfx-radius, 20px) - 3px);\n}\n.metal-fx-root[data-variant='button'][data-shape='circle'] .metal-fx-inner {\n  border-radius: calc(var(--mfx-radius, 16px) - 3px);\n}\n.metal-fx-root[data-variant='circle'][data-shape='pill'] .metal-fx-inner {\n  inset: 0;\n  border-radius: var(--mfx-radius, 20px);\n  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45);\n}\n.metal-fx-root[data-variant='circle'][data-shape='circle'] .metal-fx-inner {\n  inset: 0;\n  border-radius: var(--mfx-radius, 16px);\n  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45);\n}\n/* Circle-variant hairline alpha — light mode.\n   Source-of-truth: index.html L2261-2267. The 0.45-alpha black inset that\n   reads as a single-pixel frame against the dark interior is too heavy\n   on a #ffffff inner: it ends up looking like a hard 2-px black ring\n   against the iridescent shader. Suppressed entirely (alpha 0) — the\n   shader's own iridescent rim already defines the silhouette in light\n   mode, so an extra dark hairline only competes with it. The rule is\n   kept (rather than deleted) as a tunable hook in case a future variant\n   wants to re-introduce a soft edge. NOTE: we keep the dark-mode inset\n   and border-radius values because — unlike index.html — our renderer\n   does NOT overscan the canvas in light mode, so there is no 1-px gap\n   between inner element and shader to compensate for. */\n.metal-fx-root[data-theme='light'][data-variant='circle'][data-shape='pill'] .metal-fx-inner,\n.metal-fx-root[data-theme='light'][data-variant='circle'][data-shape='circle'] .metal-fx-inner {\n  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0);\n}\n\n/* ─── Combined glow SVG (z=3) ──────────────────────────────────────────────\n   Single SVG per instance that holds BOTH the wide-halo group\n   (#mfx_haloTravel) and the catch-light group (#mfx_extraTravel), exactly\n   mirroring canonical's _buildGlowSvgInner (index.html L8078). One\n   mix-blend-mode: screen lifts the combined composite onto the shader\n   ring; per-frame opacity attributes on each inner group still drive the\n   independent fade-in / fade-out cycles for the halo and the catch-light.\n\n   Why a single SVG: the circle variant anchors halo + catch-light at the same\n   perimeter point, so they overlap in the bright zone. Two separately-\n   screened SVGs would double-screen the overlap (A + B + C - AB - AC -\n   BC + ABC instead of A + B + C - AB - AC once both groups composite\n   in source-over inside one SVG and then screen against the host once).\n   That overlap looked muted versus canonical specifically on the circle\n   variant where both layers travel together.\n\n   Source-of-truth opacity: #btnGlowSvg drops to 0.7 in dark and 0.2746 in\n   light (index.html L632/L643). */\n.metal-fx-glow-svg {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  overflow: visible;\n  z-index: 3;\n  pointer-events: none;\n  opacity: 0.7;\n}\n.metal-fx-root[data-theme='light'] .metal-fx-glow-svg {\n  /* Light-mode 1-px overscan mirrors .btn-glow-svg in metal.html so the\n     halo stays glued to the visible silhouette (the shader ring there sits\n     1 px outside the host's padding box). */\n  inset: -1px;\n  width: calc(100% + 2px);\n  height: calc(100% + 2px);\n  mix-blend-mode: multiply;\n  /* Source-of-truth: html[data-theme=\"light\"] #btnGlowSvg { opacity: 0.2746 }\n     → −35 % from 0.4225 from the original 0.7 dark-mode opacity. */\n  opacity: 0.2746;\n  filter: saturate(5.355) brightness(0.78);\n}\n/* Circle light-mode small variants (e.g. 36×36 send button): the geometrically\n   shrunk halo loses density when multiplied against #ffffff. Mirror the\n   canonical override at index.html L2316 — bump saturation + drop brightness\n   so the small glow holds together visually. */\n.metal-fx-root[data-variant='circle'][data-shape='circle'][data-theme='light'] .metal-fx-glow-svg {\n  filter: saturate(7.5) brightness(0.6);\n}\n\n/* The wrapped child — hoisted into z=5 so it sits above every overlay, with\n   normalized chrome so consumer button styles don't fight the metal frame. */\n.metal-fx-content {\n  position: relative;\n  z-index: 5;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 100%;\n  pointer-events: none;\n}\n.metal-fx-content > * {\n  pointer-events: auto;\n}\n.metal-fx-root[data-normalize='true'] .metal-fx-content > * {\n  background: transparent !important;\n  border: 0 !important;\n  outline: 0 !important;\n  box-shadow: none !important;\n  /* Sizing: we deliberately DO NOT force \\`width: 100%; height: 100%\\` on the\n     child here. That used to be the contract (\"the wrapper is the visible\n     button surface; the child stretches to fill it\"), but it created a cyclic\n     percentage dependency: the wrapper is \\`inline-flex\\` with no intrinsic\n     size, .metal-fx-content is \\`width/height: 100%\\` of the wrapper, and the\n     child was \\`100%\\` of .metal-fx-content. With nothing breaking the cycle,\n     icon-only / class-sized children collapsed.\n\n     The new contract: the child sizes itself (intrinsic content, CSS class,\n     or inline style — all work), and the wrapper's \\`inline-flex\\` wraps it\n     tightly. Consumers who want a metal frame BIGGER than the child (e.g.\n     padding around an icon) size <MetalFx style={{ width, height }}> AND\n     explicitly set width/height on the child to fill (or accept that the\n     child renders at its intrinsic size, centered).\n\n     Typography is intentionally NOT touched. We used to apply\n     \\`color: inherit; font: inherit;\\` here to \"match\" the wrapper, but\n     \\`font: inherit\\` is a shorthand that overrides font-family, font-size,\n     font-weight, AND line-height on the child — which (a) shrank the\n     button height (line-height changes propagate through the flex\n     content box) and (b) scaled em-based icons / font-icons inside the\n     child to whatever the wrapper inherited. The wrapper now stays out\n     of the child's typography entirely; consumers who want typographic\n     normalization can apply it themselves on the child element. */\n}\n\n[data-metal-fx-reflection] {\n  position: absolute;\n  inset: 0;\n  pointer-events: none;\n  border-radius: inherit;\n  overflow: hidden;\n  z-index: 0;\n  isolation: isolate;\n}\n.metal-fx-reflection-canvas {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  display: block;\n  filter: blur(4px) saturate(1.2) brightness(1.58);\n}\n.metal-fx-reflection-stroke-canvas {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  display: block;\n  filter: saturate(1.35) brightness(1.75);\n}\n/* Hosts that participate as reflection targets need positioning + isolation\n   so the wrap composites only against the host (not the parent stack). The\n   wrap injects these inline as well, but stating them here keeps reflections\n   working on hosts that already have other inline styles applied. */\n[data-metal-fx-reflect-host] {\n  isolation: isolate;\n}\n`;\n\nlet injected = false;\n\nexport function ensureStylesInjected(): void {\n  if (injected) return;\n  if (typeof document === 'undefined') return;\n  if (document.getElementById(STYLE_ID)) { injected = true; return; }\n  const style = document.createElement('style');\n  style.id = STYLE_ID;\n  style.textContent = CSS;\n  document.head.appendChild(style);\n  injected = true;\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/upstream/types.ts",
          "target": "@components/effects/metal-fx-v1/upstream/types.ts",
          "type": "registry:component",
          "content": "import type { CSSProperties, ReactNode, HTMLAttributes, RefObject } from 'react';\n\n/**\n * Variant for the metal effect.\n * - 'button' (default): pill-shaped 134×40 baseline with shaderScale 1.6\n * - 'circle': compact 32×32 circle baseline with shaderScale 1.3\n *\n * In practice the wrapped child's measured dimensions drive the visible size —\n * the variant only controls the shader sampling scale and ring thickness.\n */\nexport type MetalFxVariant = 'button' | 'circle';\n\n/**\n * Theme mode for the metal effect.\n *\n * - `auto` (default): follows the user's `prefers-color-scheme` and updates\n *   live when the OS / browser theme changes (also gracefully falls back to\n *   `dark` during SSR or when `matchMedia` is unavailable).\n * - `dark`: pin to the dark-mode tunings regardless of system preference.\n * - `light`: pin to the light-mode tunings regardless of system preference.\n *\n * Drive this from your app's theme state if you have a manual toggle that\n * doesn't follow the OS — otherwise `auto` is the right default.\n */\nexport type MetalFxTheme = 'dark' | 'light' | 'auto';\n\n/**\n * Bundled preset names. Each preset ships both a dark and light mode block.\n */\nexport type MetalFxPreset = 'chromatic' | 'silver' | 'gold';\n\n/**\n * Props for the MetalFx React component.\n */\nexport interface MetalFxProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n  /**\n   * The single host element to wrap with the metal effect. Must be a single\n   * React node (button, anchor, div, ...). MetalFx measures this element each\n   * frame via `ResizeObserver` and paints its canvas + glow on top.\n   */\n  children: ReactNode;\n\n  /**\n   * Variant — controls the shader sampling scale + ring width.\n   * - `button` (default): pill-style ring at 1 px wide, scale 1.6\n   * - `circle`: compact circle with a 2 px ring, scale 1.3\n   */\n  variant?: MetalFxVariant;\n\n  /**\n   * Color preset. All three presets ship both dark and light mode tunings —\n   * `theme` picks the right side at runtime.\n   * @default 'chromatic'\n   */\n  preset?: MetalFxPreset;\n\n  /**\n   * Theme mode. `'auto'` (default) resolves via\n   * `matchMedia('(prefers-color-scheme: dark)')` and switches live when the\n   * OS theme changes. Pass `'dark'` or `'light'` to pin a specific mode.\n   * @default 'auto'\n   */\n  theme?: MetalFxTheme;\n\n  /**\n   * Effect strength (0..1). Multiplies the shader bitmap opacity and the glow\n   * SVG alpha. The shader continues to animate at full intensity at any value;\n   * only the rendered alpha onto the host is scaled. Lighter values let the\n   * underlying child surface show through more strongly.\n   * @default 1\n   */\n  strength?: number;\n\n  /**\n   * Pause the shader animation. The visible canvas keeps the last painted\n   * frame so the metal silhouette stays on screen.\n   * @default false\n   */\n  paused?: boolean;\n\n  /**\n   * Optional explicit border radius (CSS px). When omitted, MetalFx reads the\n   * computed border-radius of the wrapped child each resize.\n   */\n  borderRadius?: number;\n\n  /**\n   * When true, MetalFx normalizes the host element's outer chrome (border /\n   * outline / box-shadow) so user-provided component styles don't clash with\n   * the metal ring. Inner fills, typography, and content remain untouched.\n   * @default true\n   */\n  normalizeHostStyles?: boolean;\n\n  /**\n   * Neighbour elements that should receive a soft proximity reflection of the\n   * metal effect. Reflections only render when the resolved theme is `dark` —\n   * pass-through in light mode (no DOM scan, no per-frame work).\n   *\n   * Pass refs to the sibling DOM elements you want to receive the reflection\n   * (chips next to a send button, search field next to an Upgrade pill, ...).\n   */\n  reflectionTargets?: ReadonlyArray<RefObject<HTMLElement | null>>;\n\n  /**\n   * Disable the wandering halo overlay. The shader ring still renders.\n   * @default false\n   */\n  disableGlow?: boolean;\n\n  /**\n   * Override the shader sampling scale. Larger values zoom into the shared\n   * shader (visibly bigger pattern features); smaller values zoom out.\n   * Defaults to the variant's baseline (1.6 for `'button'`, 1.3 for\n   * `'circle'`) multiplied by `scale`.\n   */\n  shaderScale?: number;\n\n  /**\n   * Override the ring thickness in CSS pixels. Defaults to the variant's\n   * baseline (1 for `'button'`, 2 for `'circle'`) multiplied by `scale`.\n   */\n  ringCssPx?: number;\n\n  /**\n   * Master scale multiplier for every absolute-pixel constant the engine\n   * uses internally. Set this when you render the wrapped element at a\n   * non-1× size (e.g. inside a CSS `zoom: 2` container, or when you've\n   * doubled all your Tailwind sizes by hand). It scales:\n   *   - shader sampling (so pattern features grow proportionally)\n   *   - ring thickness on the canvas\n   *   - glow SVG stroke widths, blur radii, fade-circle radius, and the\n   *     small inset/outward offsets that position the catch-light\n   *   - reflection canvas stroke band, border-highlight thickness, and the\n   *     reference draw width baseline\n   * @default 1\n   */\n  scale?: number;\n\n  /**\n   * Forwarded class name for the wrapper element.\n   */\n  className?: string;\n\n  /**\n   * Forwarded inline styles for the wrapper element.\n   */\n  style?: CSSProperties;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/effects/metal-fx-v1/LICENSE",
          "target": "@components/effects/metal-fx-v1/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Jakub Antalik\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/effects/metal-fx-v1/SOURCE.json",
          "target": "@components/effects/metal-fx-v1/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"metal-fx\",\n  \"repository\": \"https://github.com/Jakubantalik/metal-fx\",\n  \"revision\": \"be1bf89c63056521a4e8224f368768314c9006f7\",\n  \"packageVersion\": \"1.0.4\",\n  \"license\": \"MIT\",\n  \"copiedPath\": \"upstream/\",\n  \"sourcePath\": \"src/\",\n  \"copiedFiles\": [\"src/**\"],\n  \"relationship\": \"Public v1 source still exposed by the current Libraries.dev Metal playground, with a stale WebGL context-event guard for React development remounts. The top-level client facade re-exports its complete API.\"\n}\n"
        }
      ],
      "categories": [
        "Libraries.dev"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "metal-fx",
      "type": "registry:block",
      "title": "Metal Fx",
      "description": "metal fx",
      "dependencies": [
        "@paper-design/shaders@0.0.80",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/effects/metal-fx.tsx",
          "target": "@components/effects/metal-fx.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nexport * from \"./metal-fx/upstream\"\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/index.ts",
          "target": "@components/effects/metal-fx/upstream/index.ts",
          "type": "registry:component",
          "content": "export { MetalFx } from './MetalFx';\nexport { MetalText, METAL_TEXT_DEFAULTS, type TextInnerShadow } from './MetalText';\nexport { MetalBadge, METAL_BADGE_DEFAULTS, type MetalBadgeCore } from './MetalBadge';\nexport { useMetalBend } from './useMetalBend';\nexport { BEND, BEND_DEFAULTS, setBendConfig, resetBendConfig, type BendConfig } from './engine/bend/config';\nexport { useMetalTextReflection } from './useMetalTextReflection';\nexport { paintTextRun, textMaskDataUrl } from './engine/textMask';\n\nexport type {\n  MetalFxProps,\n  MetalFxVariant,\n  MetalFxTheme,\n  MetalFxPreset,\n  MetalFxReflectionTarget,\n} from './types';\n\n// Power-user surface: expose the engine primitives so consumers building\n// non-React integrations can drive the same renderer.\nexport {\n  PRESETS,\n  SHAPE_NONE,\n  SHAPE_CIRCLE,\n  SHAPE_DAISY,\n  SHAPE_DIAMOND,\n  SHAPE_METABALLS,\n  FIT_NONE,\n  FIT_CONTAIN,\n  FIT_COVER,\n  hexToRgb,\n  hexToRgba,\n  type Preset,\n  type PresetMode,\n  type PresetName,\n  type PresetTheme,\n} from './engine/presets';\n\nexport {\n  createInstance,\n  destroyInstance,\n  updateInstance,\n  setSharedPreset,\n  setSharedPresetMode,\n  getSharedPreset,\n  setInstanceDeform,\n  redrawInstance,\n  pauseShared,\n  resumeShared,\n} from './engine/renderer/loop';\n\nexport type { MetalFxInstance, DeformFn, DeformLayers, MaskFn } from './engine/renderer/core';\nexport { RIM_DEFAULTS, type RimOptions } from './engine/rim';\nexport { isMetalFxSupported } from './engine/renderer/core';\n\n// Live glow tuning — mutable singleton read by the glow engine every frame.\nexport {\n  GLOW,\n  GLOW_DEFAULTS,\n  GLOW_MARKUP_KEYS,\n  setGlowConfig,\n  resetGlowConfig,\n  subscribeGlowConfig,\n  type GlowConfig,\n} from './engine/glow/config';\n\n// Cursor light: glint under the pointer + catch-light facing it.\nexport {\n  CURSOR_LIGHT,\n  CURSOR_LIGHT_DEFAULTS,\n  setCursorLightConfig,\n  resetCursorLightConfig,\n  setCursorSprite,\n  type CursorLightConfig,\n  type CursorSprite,\n} from './engine/cursor/light';\n\n// Cursor-as-occluder for proximity reflections.\nexport {\n  REFLECTION_OCCLUDER,\n  REFLECTION_OCCLUDER_DEFAULTS,\n  setReflectionOccluderConfig,\n  resetReflectionOccluderConfig,\n  type ReflectionOccluderConfig,\n} from './engine/reflection/paint';\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/MetalFx.tsx",
          "target": "@components/effects/metal-fx/upstream/MetalFx.tsx",
          "type": "registry:component",
          "content": "import {\n  forwardRef,\n  useEffect,\n  useImperativeHandle,\n  useLayoutEffect,\n  useMemo,\n  useRef,\n  useState,\n  type CSSProperties,\n} from 'react';\nimport type { MetalFxInstance } from './engine/renderer/core';\nimport {\n  createInstance,\n  destroyInstance,\n  registerGlowInstance,\n  setGlowCallback,\n  setInstanceVisible,\n  setSharedPreset,\n  unregisterGlowInstance,\n  updateInstance,\n  refreshInstanceDpr,\n} from './engine/renderer/loop';\nimport { carryGlowState, injectGlow, updateGlow, updateGlowMask, type GlowOptions } from './engine/glow/glow';\nimport { attachCursorLight, detachCursorLight } from './engine/cursor/light';\nimport { RIM_DEFAULTS, injectRim, removeRim, updateRim, type RimHandles, type RimOptions } from './engine/rim';\nimport { subscribeGlowConfig } from './engine/glow/config';\nimport { addReflectionTarget, removeReflectionTarget } from './engine/reflection/paint';\nimport { isMetalFxSupported } from './engine/renderer/core';\nimport { scheduleReflectionPaint } from './engine/reflection/reflectionScheduler';\nimport { ensureStylesInjected } from './styles';\nimport type { MetalFxProps, MetalFxTheme } from './types';\n\n// Runs at module scope so styles exist before the first component render,\n// even in SSR-hydration scenarios where effects haven't fired yet.\nensureStylesInjected();\n\n// Hoisted to avoid allocating new objects on every render.\nconst CANVAS_STYLE: CSSProperties = { position: 'absolute', inset: 0, width: '100%', height: '100%' };\nconst INNER_STYLE: CSSProperties = { position: 'absolute', inset: 3 };\nconst GLOW_HOST_STYLE: CSSProperties = { position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 3, borderRadius: 'inherit' };\n// Rim sits above the metal and the glow, below the content.\nconst RIM_HOST_STYLE: CSSProperties = { position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 4 };\n\n// Maps each live instance to its SVG glow handles and a theme ref.\n// Keyed by instance (not component) because the same component can be\n// remounted with a new instance after shape/glowEnabled changes.\nconst glowHandlesMap = new Map<MetalFxInstance, { handles: ReturnType<typeof injectGlow>; themeRef: { current: 'dark' | 'light' } }>();\n// Opt-in introspection for the demo's dev tooling: with\n// `globalThis.__MFX_DEBUG__ = true` the live instance → glow map is exposed\n// as `globalThis.__mfxGlow` on the next mount. Never set in production.\nfunction exposeGlowDebug(): void {\n  const g = globalThis as { __MFX_DEBUG__?: boolean; __mfxGlow?: unknown };\n  if (g.__MFX_DEBUG__) g.__mfxGlow = glowHandlesMap;\n}\n\n// Bridge between the shared animation loop and per-instance glow SVGs.\n// The loop module doesn't import glow directly — it invokes this callback\n// for one queued instance per frame (round-robin), keeping render work\n// proportional to frame budget regardless of instance count.\nsetGlowCallback((inst, nowMs) => {\n  const entry = glowHandlesMap.get(inst);\n  if (!entry) return false;\n  return updateGlow(entry.handles, inst, nowMs, inst.opacityMul * inst.glowGain, entry.themeRef.current);\n});\n\n/**\n * Resolves 'auto' theme to 'dark' | 'light' and keeps it in sync with\n * the OS preference via matchMedia.\n *\n * The useState initialiser runs synchronously so the resolved value is\n * available on the first render (no flash). The useEffect then attaches\n * the MQL listener and calls update() immediately to handle the case\n * where the OS preference changed between SSR and hydration.\n */\nfunction useResolvedTheme(theme: MetalFxTheme): 'dark' | 'light' {\n  const [resolved, setResolved] = useState<'dark' | 'light'>(() => {\n    if (theme !== 'auto') return theme;\n    if (typeof window === 'undefined' || !window.matchMedia) return 'dark';\n    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n  });\n\n  useEffect(() => {\n    if (theme !== 'auto') { setResolved(theme); return; }\n    if (typeof window === 'undefined' || !window.matchMedia) return;\n    const mql = window.matchMedia('(prefers-color-scheme: dark)');\n    const update = () => setResolved(mql.matches ? 'dark' : 'light');\n    update();\n    mql.addEventListener('change', update);\n    return () => mql.removeEventListener('change', update);\n  }, [theme]);\n\n  return resolved;\n}\n\n/**\n * Wraps any element with an animated metallic ring effect driven by a\n * single shared WebGL renderer. All visible MetalFx instances on the page\n * share one offscreen GL canvas; each instance composites a cropped/scaled\n * copy of it onto its own 2D canvas with a rounded hole punched through the\n * centre.\n */\nexport const MetalFx = forwardRef<HTMLDivElement, MetalFxProps>(function MetalFx(\n  {\n    children,\n    variant = 'button',\n    preset = 'chromatic',\n    theme = 'auto',\n    strength = 1,\n    glowGain = 1,\n    paused = false,\n    borderRadius,\n    normalizeHostStyles = true,\n    reflectionTargets,\n    disableGlow = false,\n    innerShadow,\n    shaderScale,\n    ringCssPx,\n    scale = 1,\n    mask,\n    glowMode = 'mask',\n    className,\n    style,\n    ...rest\n  },\n  forwardedRef\n) {\n  // DOM refs — rootRef/canvasRef/glowHostRef/contentRef are for direct DOM access.\n  // instanceRef/glowHandlesRef hold engine objects that survive React re-renders.\n  // themeRef lets the glow callback read the current theme without a closure\n  // over a stale value — mutated during render, never triggers a re-render.\n  // initialWrapperRadiusRef caches the CSS border-radius read at mount time so\n  // measure() can fall back to it when no explicit borderRadius prop is given.\n  const rootRef = useRef<HTMLDivElement | null>(null);\n  const canvasRef = useRef<HTMLCanvasElement | null>(null);\n  const glowHostRef = useRef<HTMLDivElement | null>(null);\n  const rimHostRef = useRef<HTMLDivElement | null>(null);\n  const rimHandlesRef = useRef<RimHandles | null>(null);\n  const contentRef = useRef<HTMLDivElement | null>(null);\n  const instanceRef = useRef<MetalFxInstance | null>(null);\n  const glowHandlesRef = useRef<ReturnType<typeof injectGlow> | null>(null);\n  const themeRef = useRef<'dark' | 'light'>('dark');\n  const initialWrapperRadiusRef = useRef<number>(0);\n\n  const [ready, setReady] = useState(false);\n  const resolvedTheme = useResolvedTheme(theme);\n  // No WebGL2 → no engine. Every effect below bails on this, and the render\n  // falls through to the plain child so the button is never lost.\n  const supported = useMemo(() => isMetalFxSupported(), []);\n  // Write during render (not in an effect) so the glow callback always sees\n  // the up-to-date theme on the very next tick.\n  themeRef.current = resolvedTheme;\n  const shape: 'pill' | 'circle' = variant === 'circle' ? 'circle' : 'pill';\n  const glowEnabled = !disableGlow;\n\n  useImperativeHandle(forwardedRef, () => rootRef.current as HTMLDivElement, []);\n\n  const resolveRadius = (w: number, h: number) => {\n    // variant='circle' is the user's explicit promise that the wrapped\n    // element should render as a circle. Always pick min(w,h)/2 so the\n    // engine produces a true circle even when the child's CSS border-radius\n    // is read in a different coordinate space than the bounding rect (the\n    // exact failure mode under CSS `zoom: 2`, where getComputedStyle\n    // returns source pixels but getBoundingClientRect returns zoomed ones).\n    if (shape === 'circle') return Math.min(w, h) / 2;\n\n    const raw = typeof borderRadius === 'number'\n      ? borderRadius\n      : (() => {\n          const childEl = contentRef.current?.firstElementChild as HTMLElement | null;\n          if (childEl) {\n            const parsed = parseFloat(getComputedStyle(childEl).borderTopLeftRadius);\n            if (Number.isFinite(parsed) && parsed > 0) return parsed;\n          }\n          return initialWrapperRadiusRef.current;\n        })();\n    return Math.min(raw, Math.min(w, h) / 2);\n  };\n\n  useEffect(() => { if (supported) setSharedPreset(preset, resolvedTheme); }, [preset, resolvedTheme, supported]);\n  useEffect(() => {\n    const inst = instanceRef.current;\n    if (inst) updateInstance(inst, { mask: mask ?? null });\n  }, [mask]);\n  // `paused` is per-instance: it freezes only this instance's 2D canvas while\n  // the shared GL loop keeps running for any other unpaused instance.\n  useEffect(() => {\n    const inst = instanceRef.current;\n    if (!inst) return;\n    updateInstance(inst, { paused });\n  }, [paused]);\n\n  // Re-sync optional shader/ring/scale overrides if they change at runtime.\n  useEffect(() => {\n    const inst = instanceRef.current;\n    if (!inst) return;\n    const patch: Partial<Parameters<typeof updateInstance>[1]> = {};\n    if (shaderScale !== undefined) patch.shaderScale = shaderScale;\n    if (ringCssPx !== undefined) patch.ringCssPx = ringCssPx;\n    if (scale !== undefined) patch.scale = scale;\n    if (Object.keys(patch).length > 0) updateInstance(inst, patch);\n  }, [shaderScale, ringCssPx, scale]);\n\n  // useLayoutEffect (not useEffect) so the instance is created and the canvas\n  // is sized synchronously before the browser paints — avoids a one-frame\n  // flash of the unsized canvas.\n  // biome-ignore lint/correctness/useExhaustiveDependencies: borderRadius changes handled by separate effect\n  useLayoutEffect(() => {\n    const canvas = canvasRef.current;\n    const root = rootRef.current;\n    const glowHost = glowHostRef.current;\n    if (!canvas || !root || !supported) return;\n\n    {\n      const computed = getComputedStyle(root);\n      const parsed = parseFloat(computed.borderTopLeftRadius);\n      initialWrapperRadiusRef.current = Number.isFinite(parsed) ? parsed : 0;\n    }\n\n    const measure = () => {\n      const rect = root.getBoundingClientRect();\n      const cssWidth = Math.max(1, Math.round(rect.width));\n      const cssHeight = Math.max(1, Math.round(rect.height));\n      return { cssWidth, cssHeight, cornerRadius: resolveRadius(cssWidth, cssHeight) };\n    };\n\n    const initial = measure();\n    instanceRef.current = createInstance({\n      onComposite: () => {\n        const inst = instanceRef.current;\n        const h = glowHandlesRef.current;\n        if (inst && h) updateGlowMask(h, inst.deform);\n        const r = rimHandlesRef.current;\n        if (inst && r) updateRim(r, inst.deform);\n      },\n      hostCanvas: canvas,\n      cssWidth: initial.cssWidth,\n      cssHeight: initial.cssHeight,\n      cornerRadius: initial.cornerRadius,\n      kind: shape,\n      paused,\n      shaderScale,\n      ringCssPx,\n      scale,\n      mask: mask ?? null,\n      onFirstCopy: () => setReady(true),\n    });\n    root.style.setProperty('--mfx-radius', `${initial.cornerRadius}px`);\n    root.style.borderRadius = `${initial.cornerRadius}px`;\n\n    // Custom-mask instances feed the glow a point set inside the glyphs and\n    // the mask itself as an image, so the halo sits *on the metal* and is\n    // clipped to it — not to a ring band that doesn't exist.\n    const glowMaskData = (w: number, h: number): Pick<GlowOptions, 'samplePoints' | 'maskDataUrl'> => {\n      if (!mask || glowMode === 'ring') return {};\n      const dpr = window.devicePixelRatio || 1;\n      const c = document.createElement('canvas');\n      c.width = Math.max(1, Math.round(w * dpr)); c.height = Math.max(1, Math.round(h * dpr));\n      const g = c.getContext('2d');\n      if (!g) return {};\n      g.fillStyle = '#fff';\n      mask(g, c.width, c.height, dpr);\n      const d = g.getImageData(0, 0, c.width, c.height).data;\n      const pts: Array<{ x: number; y: number }> = [];\n      const step = Math.max(1, Math.round(2 * dpr)); // ~2 CSS px grid\n      for (let y = step >> 1; y < c.height; y += step) {\n        for (let x = step >> 1; x < c.width; x += step) {\n          if (d[(y * c.width + x) * 4 + 3] > 128) pts.push({ x: x / dpr, y: y / dpr });\n        }\n      }\n      return { samplePoints: pts, maskDataUrl: c.toDataURL('image/png') };\n    };\n\n    if (glowHost) {\n      glowHandlesRef.current = injectGlow(glowHost, {\n        width: initial.cssWidth,\n        height: initial.cssHeight,\n        cornerRadius: initial.cornerRadius,\n        kind: shape,\n        scale,\n        ...glowMaskData(initial.cssWidth, initial.cssHeight),\n      });\n    }\n\n    const rebuildGlow = (dims: { cssWidth: number; cssHeight: number; cornerRadius: number }) => {\n      if (!glowHost) return;\n      const prev = glowHandlesRef.current;\n      glowHost.innerHTML = '';\n      glowHandlesRef.current = injectGlow(glowHost, {\n        width: dims.cssWidth, height: dims.cssHeight, cornerRadius: dims.cornerRadius, kind: shape, scale,\n        ...glowMaskData(dims.cssWidth, dims.cssHeight),\n      });\n      // A rebuild is a fresh, invisible glow. Carry the old one's state over so\n      // a resize doesn't read as \"the glow vanished, then came back elsewhere\".\n      if (prev) carryGlowState(prev, glowHandlesRef.current);\n      const inst = instanceRef.current;\n      if (inst && glowHandlesRef.current) {\n        glowHandlesMap.set(inst, { handles: glowHandlesRef.current, themeRef });\n      }\n    };\n\n    const rimOpts = (): RimOptions | null => {\n      if (!innerShadow) return null;\n      return innerShadow === true ? RIM_DEFAULTS : { ...RIM_DEFAULTS, ...innerShadow };\n    };\n    const rebuildRim = (dims: { cssWidth: number; cssHeight: number; cornerRadius: number }) => {\n      const host = rimHostRef.current;\n      const inst = instanceRef.current;\n      removeRim(rimHandlesRef.current);\n      rimHandlesRef.current = null;\n      const o = rimOpts();\n      if (!host || !inst || !o) return;\n      rimHandlesRef.current = injectRim(host, { width: dims.cssWidth, height: dims.cssHeight, cornerRadius: dims.cornerRadius, kind: shape, ring: inst.ringCssPx }, o);\n    };\n    rebuildRim(initial);\n\n    let resizeRaf = 0;\n    // Last dimensions the glow was built for. ResizeObserver fires on any box\n    // change — including ones that leave the size identical (re-layout, font\n    // load, a parent's transform) — and rebuilding the glow for those restarts\n    // it from invisible, which reads as the halo blinking out with no fade.\n    let builtW = initial.cssWidth, builtH = initial.cssHeight, builtR = initial.cornerRadius;\n    const ro = new ResizeObserver(() => {\n      if (resizeRaf !== 0) return;\n      // RAF-debounce: coalesce multiple resize events within the same frame and\n      // skip any that fire while a frame is already queued.\n      resizeRaf = requestAnimationFrame(() => {\n        resizeRaf = 0;\n        const next = measure();\n        const inst = instanceRef.current;\n        if (!inst) return;\n        const same = Math.abs(next.cssWidth - builtW) < 0.5 && Math.abs(next.cssHeight - builtH) < 0.5\n          && Math.abs(next.cornerRadius - builtR) < 0.5;\n        if (same) return;\n        builtW = next.cssWidth; builtH = next.cssHeight; builtR = next.cornerRadius;\n        updateInstance(inst, { cssWidth: next.cssWidth, cssHeight: next.cssHeight, cornerRadius: next.cornerRadius });\n        root.style.setProperty('--mfx-radius', `${next.cornerRadius}px`);\n        root.style.borderRadius = `${next.cornerRadius}px`;\n        rebuildGlow(next);\n        rebuildRim(next);\n      });\n    });\n    ro.observe(root);\n\n    // Browser zoom changes the DPR but not the CSS box, so the observer above\n    // stays quiet and every raster (metal, glow, rim) would stay at the old\n    // resolution. A resolution query fires once per DPR change; re-arm it\n    // for the new value each time.\n    let dprMql: MediaQueryList | null = null;\n    const onDpr = () => {\n      const inst = instanceRef.current;\n      if (inst && refreshInstanceDpr(inst)) { const next = measure(); rebuildGlow(next); rebuildRim(next); }\n      watchDpr();\n    };\n    const watchDpr = () => {\n      dprMql?.removeEventListener('change', onDpr);\n      dprMql = typeof window.matchMedia === 'function' ? window.matchMedia(`(resolution: ${window.devicePixelRatio || 1}dppx)`) : null;\n      dprMql?.addEventListener('change', onDpr);\n    };\n    watchDpr();\n\n    // Glow markup params (stroke widths, blurs, blob lengths) are baked into\n    // the SVG, so a live config change to one of them means a rebuild. Runtime\n    // params are read per-frame and need nothing here.\n    const unsubGlow = subscribeGlowConfig((markupChanged) => {\n      if (markupChanged && instanceRef.current) rebuildGlow(measure());\n    });\n\n    // Skip GL compositing for off-screen instances — the loop checks inst.visible\n    // before copyShaderToInstance, so hidden instances cost nothing per frame.\n    // rootMargin: 64px starts rendering slightly before the element scrolls into view.\n    let io: IntersectionObserver | null = null;\n    if (typeof IntersectionObserver !== 'undefined') {\n      io = new IntersectionObserver(\n        (entries) => { const inst = instanceRef.current; if (!inst) return; for (const e of entries) setInstanceVisible(inst, e.isIntersecting); },\n        { rootMargin: '64px' }\n      );\n      io.observe(root);\n    }\n\n    if (instanceRef.current && glowHandlesRef.current) {\n      glowHandlesMap.set(instanceRef.current, { handles: glowHandlesRef.current, themeRef });\n      registerGlowInstance(instanceRef.current);\n    }\n    attachCursorLight();\n    exposeGlowDebug();\n\n    return () => {\n      detachCursorLight();\n      removeRim(rimHandlesRef.current);\n      rimHandlesRef.current = null;\n      ro.disconnect();\n      dprMql?.removeEventListener('change', onDpr);\n      io?.disconnect();\n      unsubGlow();\n      if (resizeRaf !== 0) cancelAnimationFrame(resizeRaf);\n      const inst = instanceRef.current;\n      if (inst) {\n        glowHandlesMap.delete(inst);\n        unregisterGlowInstance(inst);\n        destroyInstance(inst);\n      }\n      instanceRef.current = null;\n      glowHandlesRef.current = null;\n      if (glowHost) glowHost.innerHTML = '';\n    };\n  }, [shape]);\n\n  // strength=1 maps directly to a full-opacity composite (opacityMul=1) for\n  // every variant. Per-preset toning lives in `shaderOpacity` inside each\n  // PresetMode, not here, so buttons and circles share the same headroom.\n  useEffect(() => {\n    const inst = instanceRef.current;\n    if (!inst) return;\n    updateInstance(inst, { opacityMul: Math.max(0, Math.min(1, strength)), glowGain: Math.max(0, glowGain) });\n  }, [strength, glowGain, variant]);\n\n  // onAfterFrame is wired here rather than at createInstance time so instances\n  // without reflectionTargets never schedule the reflection RAF.\n  // Reflections are dark-mode only — no DOM work in light mode.\n  useEffect(() => {\n    const inst = instanceRef.current;\n    const root = rootRef.current;\n    if (!inst || !root || !reflectionTargets || resolvedTheme !== 'dark') return;\n    inst.onAfterFrame = scheduleReflectionPaint;\n    const live = reflectionTargets.flatMap((r) => {\n      const ref = 'current' in r ? r : r.ref;\n      const strength = 'current' in r ? 1 : (r.strength ?? 1);\n      return ref.current ? [{ el: ref.current, strength }] : [];\n    });\n    for (const { el, strength } of live) addReflectionTarget(el, inst, root, strength);\n    return () => {\n      inst.onAfterFrame = undefined;\n      for (const { el } of live) removeReflectionTarget(el);\n    };\n  }, [reflectionTargets, resolvedTheme]);\n\n  // Separate from the main lifecycle effect so borderRadius / variant / theme\n  // changes re-sync the radius without destroying and recreating the instance.\n  // biome-ignore covers shape, which is derived from variant and identical to\n  // inst.kind — adding it would be correct but redundant.\n  // biome-ignore lint/correctness/useExhaustiveDependencies: trigger deps for radius re-sync\n  useEffect(() => {\n    const root = rootRef.current;\n    const inst = instanceRef.current;\n    if (!root || !inst) return;\n    const cornerRadius = resolveRadius(inst.cssWidth, inst.cssHeight);\n    updateInstance(inst, { cornerRadius });\n    root.style.setProperty('--mfx-radius', `${cornerRadius}px`);\n    root.style.borderRadius = `${cornerRadius}px`;\n  }, [borderRadius, resolvedTheme, variant, shape]);\n\n  // --mfx-strength is consumed by downstream CSS (e.g. content opacity rules).\n  // Spread style last so consumer inline styles can still override other props.\n  const wrapperStyle = useMemo<CSSProperties>(\n    () => ({\n      ...style,\n      ['--mfx-strength' as string]: String(Math.min(1, Math.max(0, strength))),\n      opacity: ready ? 1 : 0,\n      visibility: ready ? 'visible' : 'hidden',\n      transition: ready ? 'opacity 0.15s ease-out' : 'none',\n    }),\n    [style, strength, ready]\n  );\n\n  if (!supported) {\n    // Graceful degradation: the wrapped element with its own styling intact —\n    // no normalisation, no canvas, no glow. Consumers can style\n    // `[data-metal-fx-unsupported]` if they want a static stand-in ring.\n    return (\n      <div\n        {...rest}\n        ref={rootRef}\n        className={className ? `metal-fx-fallback ${className}` : 'metal-fx-fallback'}\n        data-metal-fx-unsupported=\"\"\n        style={{ display: 'inline-flex', ...style }}\n      >\n        {children}\n      </div>\n    );\n  }\n\n  return (\n    <div\n      {...rest}\n      ref={rootRef}\n      className={className ? `metal-fx-root ${className}` : 'metal-fx-root'}\n      data-variant={variant}\n      data-shape={shape}\n      data-theme={resolvedTheme}\n      data-paused={paused ? 'true' : undefined}\n      data-normalize={normalizeHostStyles ? 'true' : 'false'}\n      style={wrapperStyle}\n    >\n      <canvas ref={canvasRef} className=\"metal-fx-canvas\" style={CANVAS_STYLE} />\n      <div className=\"metal-fx-inner\" aria-hidden=\"true\" style={INNER_STYLE} />\n      <div ref={glowHostRef} aria-hidden=\"true\" style={{ ...GLOW_HOST_STYLE, display: glowEnabled ? undefined : 'none' }} />\n      {innerShadow ? <div ref={rimHostRef} aria-hidden=\"true\" style={RIM_HOST_STYLE} /> : null}\n      <div ref={contentRef} className=\"metal-fx-content\">{children}</div>\n    </div>\n  );\n});\n\nMetalFx.displayName = 'MetalFx';\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/renderer/core.ts",
          "target": "@components/effects/metal-fx/upstream/engine/renderer/core.ts",
          "type": "registry:component",
          "content": "/**\n * Shared WebGL renderer — one offscreen GL canvas drives all MetalFx instances.\n *\n * Architecture:\n *   1. A single offscreen GL canvas renders the plasma shader.\n *   2. Each instance owns a visible 2D canvas that receives a cropped/scaled\n *      copy of the GL output with an inner \"hole punch\" mask (ring effect).\n *   3. Glow sampling reads from a shared pixel buffer (gl.readPixels) that is\n *      refreshed at most every 200ms to avoid GPU pipeline flushes on every frame.\n *   4. The animation loop is capped at ~30fps — the blur + slow plasma motion\n *      makes higher rates imperceptible.\n */\nimport { CANONICAL_GL_SIZE, GL_DPR_CAP } from '../perfConfig';\nimport { PRESETS, type PresetMode } from '../presets';\nimport { compileShader, FRAG_SHADER_SRC, linkProgram, VERT_SHADER_SRC } from '../shaders';\nexport const CANONICAL_PILL_W = 140;\nexport const CANONICAL_PILL_H = 40;\nexport const PILL_SHADER_SCALE = 1.6;\nexport const CIRCLE_SHADER_SCALE = 1.3;\n\nexport interface ShaderRGB { r: number; g: number; b: number }\n\n/**\n * Vector deformation hook. Maps a point in the instance's CSS-px box (origin\n * top-left, before any overscan) to its displaced position, writing into\n * `out`. When an instance carries one, the ring mask is built from displaced\n * rounded-rect outlines instead of `roundRect`, so stretch stays anti-aliased\n * at any magnitude — unlike a pixel displacement filter.\n */\nexport type DeformFn = (x: number, y: number, out: { x: number; y: number }) => void;\n\n/**\n * Extra layers drawn into the canvas while deforming — things that live on\n * CSS boxes (root background, `::after` rim, `.metal-fx-inner` hairline) and\n * therefore can't follow a vector deformation on their own.\n */\nexport interface DeformLayers {\n  /** Fill colour behind the ring (the root background), or null. */\n  fill?: string | null;\n  /** Inset stroke drawn over the ring. `inset` is the band's inner edge from\n   *  the outer outline; `width` the band thickness; CSS px. */\n  rim?: { inset: number; width: number; color: string } | null;\n  /** Thin stroke at `inset` from the outer outline, under the ring. */\n  hairline?: { inset: number; width: number; color: string } | null;\n}\n\n/**\n * Custom alpha mask. Paints opaque shapes in *device* px onto a context whose\n * origin is the instance's box top-left; the engine keeps the shader only\n * where the mask painted (`destination-in`). Replaces the ring punch — use it\n * for metal-filled text or glyphs.\n */\nexport type MaskFn = (ctx: CanvasRenderingContext2D, w: number, h: number, dpr: number) => void;\n\nexport interface MetalFxInstance {\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  cssWidth: number;\n  cssHeight: number;\n  cornerRadius: number;\n  kind: 'pill' | 'circle';\n  ringCssPx: number;\n  shaderScale: number;\n  opacityMul: number;\n  /** Extra multiplier on the glow only (halo + catch-light), default 1. Lets\n   *  a dim shader (low `opacityMul`) still carry a visible glow. */\n  glowGain: number;\n  visible: boolean;\n  /** Per-instance freeze flag. When true the instance's 2D canvas keeps the\n   *  last copied frame; the shared GL loop continues for any other unpaused\n   *  instance. */\n  paused: boolean;\n  /** Set to true after the first successful copyShaderToInstance — so an\n   *  instance that mounts already paused still gets one frame painted before\n   *  it freezes (otherwise it would render a blank canvas). */\n  everCopied: boolean;\n  /** The shader frame this instance froze on when paused. While paused every\n   *  composite (a bend redraw, a resize) draws from this copy, so the ring\n   *  keeps its still texture while the shared loop runs on for others. */\n  frozen: HTMLCanvasElement | null;\n  dpr: number;\n  /** Master scale multiplier for absolute-pixel internals (glow stroke\n   *  widths/blurs, reflection stroke band, etc.). 1 is the baseline. Set to\n   *  2 for a CSS-zoomed 2× hero so glow + reflection grow with the layout. */\n  scale: number;\n  onAfterFrame?: () => void;\n  /** Fired after every composite, synchronously — for layers that must track\n   *  the ring exactly (the glow's mask while deforming). */\n  onComposite?: () => void;\n  /** One-shot callback fired after the very first copyShaderToInstance.\n   *  Auto-cleared by the loop so it never fires twice. */\n  onFirstCopy?: () => void;\n  /** See `MaskFn`. Takes precedence over the ring punch and over `deform`. */\n  mask: MaskFn | null;\n  /** Unmasked copy of the metal sheet for masked instances — what a mirror\n   *  facing the glyphs would see (the stripes, not three thin letters).\n   *  Allocated on demand when a glyph reflection target asks for it. */\n  rawCanvas: HTMLCanvasElement | null;\n  wantRaw: boolean;\n  /** Ring-only copy while a deform is active. The bend draws the host's\n   *  fill / rim / hairline into the main canvas so they bend along; a\n   *  reflection that mirrored that would jump from \"ring\" to \"filled disc\"\n   *  the moment the bend starts. Allocated on demand by reflection targets. */\n  ringCanvas: HTMLCanvasElement | null;\n  wantRing: boolean;\n  /** See `DeformFn`. Null = rigid rounded-rect mask. */\n  deform: DeformFn | null;\n  deformLayers: DeformLayers | null;\n  /** Canvas margin beyond the CSS box, CSS px, so displaced geometry that\n   *  bulges outward isn't clipped. 0 unless deforming. */\n  overscan: number;\n  /** Pointer acting as a light source: the outline point nearest the cursor\n   *  (box-local CSS px) and a 0..1 proximity weight. Set by the cursor-light\n   *  tracker; the glow's hotspot faces it. Null when the pointer is away. */\n  cursorLight: { x: number; y: number; w: number } | null;\n  /** Set by the glow callback when its envelope is mid-fade: the loop then\n   *  ticks the glow every animation frame instead of every shader frame, so\n   *  a 300 ms fade gets ~20 steps rather than 4. */\n  glowFast: boolean;\n}\n\nexport interface SharedRenderer {\n  glCanvas: HTMLCanvasElement | OffscreenCanvas;\n  gl: WebGL2RenderingContext;\n  program: WebGLProgram;\n  buffer: WebGLBuffer;\n  uniforms: Record<string, WebGLUniformLocation | null>;\n  /** 1×1 placeholder bound to `u_image`; see buildGLPipeline. */\n  dummyTexture: WebGLTexture | null;\n  preset: PresetMode;\n  presetDirty: boolean;\n  contextLost: boolean;\n  useOffscreen: boolean;\n  frameBitmap: ImageBitmap | null;\n  startMs: number;\n  pausedMs: number;\n  pausedAtMs: number | null;\n  rafId: number;\n  dpr: number;\n  instances: Set<MetalFxInstance>;\n  frameCount: number;\n  glowQueue: MetalFxInstance[];\n  glowIdx: number;\n  glowSkip: number;\n  glowPixels: Uint8Array;\n  glowPixelsW: number;\n  glowPixelsH: number;\n}\n\nexport let SHARED: SharedRenderer | null = null;\n\nlet _supported: boolean | null = null;\n/**\n * Whether this browser can run the engine (WebGL2). Cached after the first\n * call. Consumers get this for free through `<MetalFx>`, which renders its\n * children plain when unsupported instead of throwing.\n */\nexport function isMetalFxSupported(): boolean {\n  if (_supported !== null) return _supported;\n  if (typeof document === 'undefined') return (_supported = false);\n  try {\n    const c = document.createElement('canvas');\n    const gl = c.getContext('webgl2') as WebGL2RenderingContext | null;\n    _supported = !!gl;\n    gl?.getExtension('WEBGL_lose_context')?.loseContext();\n  } catch {\n    _supported = false;\n  }\n  return _supported;\n}\n\n// Called by ensureSharedRenderer on first init and by the contextrestored\n// listener to rebuild GL state after the browser reclaims the context.\nlet _onContextRestored: (() => void) | null = null;\nexport function setContextRestoredCallback(cb: (() => void) | null): void {\n  _onContextRestored = cb;\n}\n\nconst UNIFORM_NAMES = [\n  // Fragment stage (Paper liquidMetal)\n  'u_resolution', 'u_time', 'u_pixelRatio',\n  'u_colorBack', 'u_colorTint',\n  'u_repetition', 'u_softness', 'u_shiftRed', 'u_shiftBlue',\n  'u_distortion', 'u_contour', 'u_angle', 'u_shape', 'u_isImage', 'u_image',\n  // Vertex stage (Paper sizing)\n  'u_originX', 'u_originY', 'u_worldWidth', 'u_worldHeight',\n  'u_fit', 'u_scale', 'u_rotation', 'u_offsetX', 'u_offsetY',\n  'u_imageAspectRatio',\n];\n\n/**\n * Paper's shader writes premultiplied color (`color *= opacity` before the\n * backdrop composite), so the blend func has to be ONE / 1-SRC_ALPHA. Pairing\n * premultiplied output with the classic SRC_ALPHA factor double-darkens every\n * partially-transparent pixel — which on a 1px ring is the whole thing.\n */\nfunction buildGLPipeline(gl: WebGL2RenderingContext): {\n  program: WebGLProgram;\n  buffer: WebGLBuffer;\n  uniforms: Record<string, WebGLUniformLocation | null>;\n  dummyTexture: WebGLTexture | null;\n} {\n  gl.enable(gl.BLEND);\n  gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\n  const vert = compileShader(gl, gl.VERTEX_SHADER, VERT_SHADER_SRC);\n  const frag = compileShader(gl, gl.FRAGMENT_SHADER, FRAG_SHADER_SRC);\n  const program = linkProgram(gl, vert, frag);\n  // biome-ignore lint/correctness/useHookAtTopLevel: WebGL method, not a React hook\n  gl.useProgram(program);\n\n  const buffer = gl.createBuffer();\n  if (!buffer) throw new Error('metal-fx: gl.createBuffer returned null');\n  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW);\n  const posLoc = gl.getAttribLocation(program, 'a_position');\n  gl.enableVertexAttribArray(posLoc);\n  // Paper declares `a_position` as vec4; feeding 2 floats leaves z=0, w=1,\n  // which is exactly the full-screen quad the shader expects.\n  gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);\n\n  const uniforms: Record<string, WebGLUniformLocation | null> = {};\n  for (const n of UNIFORM_NAMES) uniforms[n] = gl.getUniformLocation(program, n);\n\n  // `u_image` is dead at u_isImage=false, but an unbound sampler2D is\n  // undefined behaviour and renders black on some drivers. Bind 1×1 opaque\n  // black to texture unit 0 and leave it there for the life of the program.\n  const dummyTexture = gl.createTexture();\n  if (dummyTexture) {\n    gl.activeTexture(gl.TEXTURE0);\n    gl.bindTexture(gl.TEXTURE_2D, dummyTexture);\n    gl.texImage2D(\n      gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,\n      new Uint8Array([0, 0, 0, 255])\n    );\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n    if (uniforms.u_image) gl.uniform1i(uniforms.u_image, 0);\n  }\n\n  return { program, buffer, uniforms, dummyTexture };\n}\n\nexport function ensureSharedRenderer(): SharedRenderer {\n  if (SHARED) return SHARED;\n\n  const dpr = Math.min(GL_DPR_CAP, typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1);\n  const size = Math.round(CANONICAL_GL_SIZE * dpr);\n  const useOffscreen = typeof OffscreenCanvas !== 'undefined';\n\n  let glCanvas: HTMLCanvasElement | OffscreenCanvas;\n  let gl: WebGL2RenderingContext | null;\n\n  // WebGL2 is required, not preferred: Paper's shaders are `#version 300 es`\n  // and use textureSize/fwidth/textureGrad. There is no WebGL1 fallback path.\n  if (useOffscreen) {\n    glCanvas = new OffscreenCanvas(size, size);\n    gl = glCanvas.getContext('webgl2', {\n      alpha: true, premultipliedAlpha: true, antialias: false,\n    }) as WebGL2RenderingContext | null;\n  } else {\n    const htmlCanvas = document.createElement('canvas');\n    htmlCanvas.width = size;\n    htmlCanvas.height = size;\n    gl = htmlCanvas.getContext('webgl2', {\n      alpha: true, premultipliedAlpha: true, antialias: false, preserveDrawingBuffer: true,\n    }) as WebGL2RenderingContext | null;\n    glCanvas = htmlCanvas;\n  }\n  if (!gl) throw new Error('metal-fx: WebGL2 not supported');\n\n  const { program, buffer, uniforms, dummyTexture } = buildGLPipeline(gl);\n\n  const onContextLost = (e: Event) => { e.preventDefault(); if (SHARED) SHARED.contextLost = true; };\n  const onContextRestored = () => {\n    if (!SHARED) return;\n    const rebuilt = buildGLPipeline(SHARED.gl);\n    SHARED.program = rebuilt.program;\n    SHARED.buffer = rebuilt.buffer;\n    SHARED.uniforms = rebuilt.uniforms;\n    SHARED.dummyTexture = rebuilt.dummyTexture;\n    SHARED.presetDirty = true;\n    SHARED.contextLost = false;\n    _onContextRestored?.();\n  };\n  glCanvas.addEventListener('webglcontextlost', onContextLost as EventListener, false);\n  glCanvas.addEventListener('webglcontextrestored', onContextRestored as EventListener, false);\n\n  SHARED = {\n    glCanvas, gl, program, buffer, uniforms, dummyTexture,\n    preset: PRESETS.chromatic.modes.dark, presetDirty: true,\n    contextLost: false, useOffscreen, frameBitmap: null,\n    startMs: performance.now(), pausedMs: 0, pausedAtMs: null,\n    rafId: 0, dpr, instances: new Set(), frameCount: 0,\n    glowQueue: [], glowIdx: 0, glowSkip: 0,\n    glowPixels: new Uint8Array(size * size * 4),\n    glowPixelsW: size, glowPixelsH: size,\n  };\n  return SHARED;\n}\n\nexport function teardownSharedRenderer(): void {\n  if (!SHARED) return;\n  const { gl, program, buffer, frameBitmap, dummyTexture } = SHARED;\n  try {\n    frameBitmap?.close();\n    gl.deleteBuffer(buffer);\n    gl.deleteProgram(program);\n    if (dummyTexture) gl.deleteTexture(dummyTexture);\n    gl.getExtension('WEBGL_lose_context')?.loseContext();\n  } catch { /* swallow */ }\n  SHARED = null;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/perfConfig.ts",
          "target": "@components/effects/metal-fx/upstream/engine/perfConfig.ts",
          "type": "registry:component",
          "content": "// ─── Frame rates ──────────────────────────────────────────────────────────\n\n// Main render loop: shader + canvas compositing. 66ms ≈ 15fps.\nexport const FRAME_INTERVAL_MS = 66;\n\n// Reflection repaint throttle. Matches main loop; CSS blur hides stepping.\nexport const REFLECTION_INTERVAL_MS = 66;\n\n// ─── Glow ─────────────────────────────────────────────────────────────────\n\n// gl.readPixels interval for luminance sampling. GPU→CPU sync is expensive.\nexport const GLOW_READBACK_INTERVAL_MS = 1500;\n\n// Only run the glow callback every Nth rendered frame. Each update triggers\n// Chrome to re-rasterize + re-blur 6 SVG paths through 2 masks.\nexport const GLOW_SKIP_FRAMES = 1;\n\n// Points sampled around the perimeter to find the brightest hotspot.\nexport const PERIM_SAMPLES = 16;\n\n// SVG path segment counts. Lower = shorter d-strings = less SVG parse work.\n// Blur filters smooth out any polygon faceting.\nexport const HALO_SEGMENTS = 16;\nexport const EXTRA_SEGMENTS = 8;\n\n// ─── GL canvas ────────────────────────────────────────────────────────────\n\n// Base pixel size of the offscreen GL canvas (before DPR scaling).\n// The plasma is inherently blurry — higher values waste fragment work.\nexport const CANONICAL_GL_SIZE = 96;\n\n// Cap devicePixelRatio for the GL canvas. 3x retina is wasted on soft plasma.\nexport const GL_DPR_CAP = 2;\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/presets.ts",
          "target": "@components/effects/metal-fx/upstream/engine/presets.ts",
          "type": "registry:component",
          "content": "/**\n * Bundled preset configurations for the metal effect.\n *\n * These sit on top of Paper Shaders' `liquidMetal`, so the parameter set is\n * Paper's, not the old plasma engine's. Baseline values come from Paper's own\n * `fullScreenPreset` (\"Backdrop\") — the `shape: 'none'` variant, which fills\n * the frame with the material instead of masking it to a circle/daisy/diamond.\n * That's the mode we want: metal-fx carves the ring itself on the 2D canvas\n * (`punchInnerHole`), so the shader should hand us a full sheet of metal.\n *\n * A note on color, because it is the big behavioural change from the plasma\n * engine: Paper hardcodes the stripe endpoints inside the shader to\n * near-white (.98,.98,1.) and near-black (.1,.1,.1). There is no palette to\n * feed. All three presets therefore render the *same* silver material and\n * differ only in `colorTint`, which the shader applies as a colour-burn pass\n * weighted by the tint's alpha. `chromatic` is consequently an approximation\n * — the old 5-stop rainbow is not reproducible here.\n *\n * `colorBack` is composited *under* the material at its own alpha. Keep it\n * fully transparent for ring use, otherwise the punched-out centre fills in.\n *\n * `speed` is applied JS-side to `u_time` before upload (cheaper than a\n * uniform, and it matches how Paper's own mount drives time).\n */\n\nexport type PresetName = 'chromatic' | 'silver' | 'gold';\nexport type PresetTheme = 'dark' | 'light';\n\n/** Paper's `LiquidMetalShapes`. Only `none` fills the frame. */\nexport const SHAPE_NONE = 0;\nexport const SHAPE_CIRCLE = 1;\nexport const SHAPE_DAISY = 2;\nexport const SHAPE_DIAMOND = 3;\nexport const SHAPE_METABALLS = 4;\n\n/** Paper's `ShaderFitOptions`. */\nexport const FIT_NONE = 0;\nexport const FIT_CONTAIN = 1;\nexport const FIT_COVER = 2;\n\nexport interface PresetMode {\n  /** Backdrop RGBA as `#rrggbb` or `#rrggbbaa`. Composited under the metal. */\n  colorBack: string;\n  /** Tint RGBA as `#rrggbb` or `#rrggbbaa`. Applied as colour-burn; the alpha\n   *  channel is the blend amount, not an opacity. */\n  colorTint: string;\n  /** Time multiplier applied JS-side before `u_time` is uploaded. */\n  speed: number;\n  /** Stripe density (1..10). */\n  repetition: number;\n  /** Stripe transition blur, 0 = hard edge (0..1). */\n  softness: number;\n  /** R-channel dispersion (-1..1). */\n  shiftRed: number;\n  /** B-channel dispersion (-1..1). */\n  shiftBlue: number;\n  /** Simplex-noise warp over the stripe field (0..1). */\n  distortion: number;\n  /** How strongly the pattern follows the shape edge (0..1). */\n  contour: number;\n  /** Pattern drift direction in degrees (0..360). */\n  angle: number;\n  /** Mask shape. `SHAPE_NONE` fills the frame — the right choice for a ring. */\n  shape: number;\n  /** Overall zoom (0.01..4). */\n  scale: number;\n  /** Overall rotation in degrees (0..360). */\n  rotation: number;\n  /** Graphic centre offset (-1..1). */\n  offsetX: number;\n  offsetY: number;\n  /** Reference point for positioning the world box (0..1). */\n  originX: number;\n  originY: number;\n  /** Virtual size before fitting. 0 = use the canvas dimension. */\n  worldWidth: number;\n  worldHeight: number;\n  /** FIT_NONE / FIT_CONTAIN / FIT_COVER. */\n  fit: number;\n  /** Global alpha applied when the shared frame is copied onto an instance.\n   *  Paper's shader has no equivalent uniform, so this is a JS-side multiply\n   *  in `copyShaderToInstance` rather than something the GPU applies. */\n  shaderOpacity: number;\n}\n\nexport interface Preset {\n  name: PresetName;\n  modes: Record<PresetTheme, PresetMode>;\n}\n\n/** Paper `fullScreenPreset` values, minus the opaque `#AAAAAC` backdrop. */\nconst BASE: Omit<PresetMode, 'colorTint' | 'shaderOpacity'> = {\n  colorBack: '#00000000',\n  speed: 1,\n  repetition: 1.5,\n  softness: 0.05,\n  shiftRed: 0.3,\n  shiftBlue: 0.3,\n  distortion: 0.1,\n  contour: 0.4,\n  angle: 90,\n  shape: SHAPE_NONE,\n  scale: 1,\n  rotation: 0,\n  offsetX: 0,\n  offsetY: 0,\n  originX: 0.5,\n  originY: 0.5,\n  worldWidth: 0,\n  worldHeight: 0,\n  fit: FIT_CONTAIN,\n};\n\nconst CHROMATIC: Preset = {\n  name: 'chromatic',\n  modes: {\n    // Cool blue burn with the dispersion pushed well past Paper's default —\n    // the R/B channel split is the only knob that produces colour separation\n    // in this shader, so it carries what the 5-stop palette used to do.\n    dark: { ...BASE, colorTint: '#88ccff2e', shiftRed: 0.75, shiftBlue: 0.75, repetition: 2, softness: 0.09, shaderOpacity: 1 },\n    light: { ...BASE, colorTint: '#66b0ff99', shiftRed: 0.6, shiftBlue: 0.6, shaderOpacity: 1 },\n  },\n};\n\nconst SILVER: Preset = {\n  name: 'silver',\n  modes: {\n    // White tint at low amount = Paper's material essentially untouched.\n    dark: { ...BASE, colorTint: '#ffffff66', shaderOpacity: 0.88 },\n    light: { ...BASE, colorTint: '#ffffff40', shaderOpacity: 1 },\n  },\n};\n\nconst GOLD: Preset = {\n  name: 'gold',\n  modes: {\n    dark: { ...BASE, colorTint: '#ffcc55cc', speed: 0.85, shaderOpacity: 0.92 },\n    light: { ...BASE, colorTint: '#f7d488aa', shaderOpacity: 1 },\n  },\n};\n\nexport const PRESETS: Record<PresetName, Preset> = {\n  chromatic: CHROMATIC,\n  silver: SILVER,\n  gold: GOLD,\n};\n\nexport { hexToRgb, hexToRgba } from './color';\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/color.ts",
          "target": "@components/effects/metal-fx/upstream/engine/color.ts",
          "type": "registry:component",
          "content": "/** Converts `#rrggbb` (or `#rgb`) to a normalized `[r, g, b]` triple (0–1). */\nexport function hexToRgb(hex: string): [number, number, number] {\n  let h = hex.replace('#', '');\n  if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n  return [parseInt(h.slice(0, 2), 16) / 255, parseInt(h.slice(2, 4), 16) / 255, parseInt(h.slice(4, 6), 16) / 255];\n}\n\n/**\n * Converts `#rgb` / `#rgba` / `#rrggbb` / `#rrggbbaa` to a normalized\n * `[r, g, b, a]` quad (0–1). Alpha defaults to 1 when the hex omits it.\n *\n * Paper's shader takes colors as `vec4`, and for `u_colorTint` the alpha is a\n * blend *amount* (how much colour-burn to apply), not an opacity — so the\n * 8-digit form is the normal way to write a tint here, not an edge case.\n */\nexport function hexToRgba(hex: string): [number, number, number, number] {\n  let h = hex.replace('#', '');\n  if (h.length === 3 || h.length === 4) h = h.split('').map((c) => c + c).join('');\n  const a = h.length >= 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1;\n  return [\n    parseInt(h.slice(0, 2), 16) / 255,\n    parseInt(h.slice(2, 4), 16) / 255,\n    parseInt(h.slice(4, 6), 16) / 255,\n    a,\n  ];\n}\n\nexport function rgbToHsv(r: number, g: number, b: number): [number, number, number] {\n  r /= 255; g /= 255; b /= 255;\n  const max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min;\n  let h = 0;\n  const s = max === 0 ? 0 : d / max;\n  if (d !== 0) {\n    if (max === r) h = ((g - b) / d + 6) % 6;\n    else if (max === g) h = (b - r) / d + 2;\n    else h = (r - g) / d + 4;\n    h /= 6;\n  }\n  return [h, s, max];\n}\n\nexport function hsvToRgb(h: number, s: number, v: number): [number, number, number] {\n  const i = Math.floor(h * 6), f = h * 6 - i;\n  const p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s);\n  let r = 0, g = 0, b = 0;\n  switch (i % 6) {\n    case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break;\n    case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break;\n    case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break;\n  }\n  return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/shaders.ts",
          "target": "@components/effects/metal-fx/upstream/engine/shaders.ts",
          "type": "registry:component",
          "content": "/**\n * Vertex + fragment shader for the metal-fx effect.\n *\n * Source-of-truth: Paper Shaders' `liquidMetal`, consumed unmodified from\n * `@paper-design/shaders` so the material stays byte-identical to what the\n * Paper editor previews and updates come in via npm.\n *\n * Paper's shaders are GLSL ES 3.00 / WebGL2 (`#version 300 es`, `out vec4\n * fragColor`), which is why the shared renderer asks for a `webgl2` context.\n * The fragment stage reads varyings (`v_objectUV`, `v_responsiveUV`,\n * `v_responsiveBoxGivenSize`, `v_imageUV`) produced by Paper's own vertex\n * shader, so the pair has to travel together — a bare full-screen-quad vertex\n * stage will link but render nothing.\n *\n * The vertex source is vendored below rather than imported: `@paper-design/\n * shaders` exposes it only through `ShaderMount`, which owns its own canvas\n * and RAF loop and would bypass this library's shared-renderer architecture\n * (one GL context feeding every instance). Copied verbatim from\n * paper-design/shaders `packages/shaders/src/vertex-shader.ts` @ 0.0.80,\n * Apache-2.0 — see NOTICE.\n *\n * IMPORTANT: `#version` must be the first characters of the source string.\n * Neither template literal below may start with a newline.\n *\n * Fragment uniforms (Paper's liquidMetal):\n *   u_resolution      vec2  — destination pixel buffer (DPR-scaled)\n *   u_time            float — seconds since boot, JS-side multiplied by speed\n *   u_pixelRatio      float — device pixel ratio the buffer was sized at\n *   u_colorBack       vec4  — backdrop RGBA, composited under the material\n *   u_colorTint       vec4  — tint RGBA, applied as color-burn (a = amount)\n *   u_repetition      float — stripe density (1..10)\n *   u_softness        float — stripe transition blur (0..1)\n *   u_shiftRed        float — R-channel dispersion (-1..1)\n *   u_shiftBlue       float — B-channel dispersion (-1..1)\n *   u_distortion      float — simplex-noise warp over the stripes (0..1)\n *   u_contour         float — edge-following strength (0..1)\n *   u_angle           float — pattern drift direction, degrees (0..360)\n *   u_shape           float — 0 none / 1 circle / 2 daisy / 3 diamond / 4 metaballs\n *   u_isImage         bool  — image-mask mode; always false here\n *   u_image           sampler2D — unused at u_isImage=false, 1×1 dummy bound\n *\n * Sizing uniforms consumed by the vertex stage: u_originX, u_originY,\n * u_worldWidth, u_worldHeight, u_fit, u_scale, u_rotation, u_offsetX,\n * u_offsetY, u_imageAspectRatio.\n *\n * Note the material itself is fixed: Paper hardcodes the stripe endpoints to\n * near-white and near-black, so all color comes from u_colorTint (burn) and\n * u_colorBack. There is no multi-stop palette to drive.\n */\nimport { liquidMetalFragmentShader } from '@paper-design/shaders';\n\n/** Paper's sizing vertex stage. Vendored verbatim — see file header. */\nexport const VERT_SHADER_SRC = /* glsl */ `#version 300 es\nprecision mediump float;\n\nlayout(location = 0) in vec4 a_position;\n\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\nuniform float u_imageAspectRatio;\nuniform float u_originX;\nuniform float u_originY;\nuniform float u_worldWidth;\nuniform float u_worldHeight;\nuniform float u_fit;\nuniform float u_scale;\nuniform float u_rotation;\nuniform float u_offsetX;\nuniform float u_offsetY;\n\nout vec2 v_objectUV;\nout vec2 v_objectBoxSize;\nout vec2 v_responsiveUV;\nout vec2 v_responsiveBoxGivenSize;\nout vec2 v_patternUV;\nout vec2 v_patternBoxSize;\nout vec2 v_imageUV;\n\nvec3 getBoxSize(float boxRatio, vec2 givenBoxSize) {\n  vec2 box = vec2(0.);\n  // fit = none\n  box.x = boxRatio * min(givenBoxSize.x / boxRatio, givenBoxSize.y);\n  float noFitBoxWidth = box.x;\n  if (u_fit == 1.) { // fit = contain\n    box.x = boxRatio * min(u_resolution.x / boxRatio, u_resolution.y);\n  } else if (u_fit == 2.) { // fit = cover\n    box.x = boxRatio * max(u_resolution.x / boxRatio, u_resolution.y);\n  }\n  box.y = box.x / boxRatio;\n  return vec3(box, noFitBoxWidth);\n}\n\nvoid main() {\n  gl_Position = a_position;\n\n  vec2 uv = gl_Position.xy * .5;\n  vec2 boxOrigin = vec2(.5 - u_originX, u_originY - .5);\n  vec2 givenBoxSize = vec2(u_worldWidth, u_worldHeight);\n  givenBoxSize = max(givenBoxSize, vec2(1.)) * u_pixelRatio;\n  float r = u_rotation * 3.14159265358979323846 / 180.;\n  mat2 graphicRotation = mat2(cos(r), sin(r), -sin(r), cos(r));\n  vec2 graphicOffset = vec2(-u_offsetX, u_offsetY);\n\n\n  // ===================================================\n\n  float fixedRatio = 1.;\n  vec2 fixedRatioBoxGivenSize = vec2(\n  (u_worldWidth == 0.) ? u_resolution.x : givenBoxSize.x,\n  (u_worldHeight == 0.) ? u_resolution.y : givenBoxSize.y\n  );\n\n  v_objectBoxSize = getBoxSize(fixedRatio, fixedRatioBoxGivenSize).xy;\n  vec2 objectWorldScale = u_resolution.xy / v_objectBoxSize;\n\n  v_objectUV = uv;\n  v_objectUV *= objectWorldScale;\n  v_objectUV += boxOrigin * (objectWorldScale - 1.);\n  v_objectUV += graphicOffset;\n  v_objectUV /= u_scale;\n  v_objectUV = graphicRotation * v_objectUV;\n\n  // ===================================================\n\n  v_responsiveBoxGivenSize = vec2(\n  (u_worldWidth == 0.) ? u_resolution.x : givenBoxSize.x,\n  (u_worldHeight == 0.) ? u_resolution.y : givenBoxSize.y\n  );\n  float responsiveRatio = v_responsiveBoxGivenSize.x / v_responsiveBoxGivenSize.y;\n  vec2 responsiveBoxSize = getBoxSize(responsiveRatio, v_responsiveBoxGivenSize).xy;\n  vec2 responsiveBoxScale = u_resolution.xy / responsiveBoxSize;\n\n  v_responsiveUV = uv;\n  v_responsiveUV *= responsiveBoxScale;\n  v_responsiveUV += boxOrigin * (responsiveBoxScale - 1.);\n  v_responsiveUV += graphicOffset;\n  v_responsiveUV /= u_scale;\n  v_responsiveUV.x *= responsiveRatio;\n  v_responsiveUV = graphicRotation * v_responsiveUV;\n  v_responsiveUV.x /= responsiveRatio;\n\n  // ===================================================\n\n  float patternBoxRatio = givenBoxSize.x / givenBoxSize.y;\n  vec2 patternBoxGivenSize = vec2(\n  (u_worldWidth == 0.) ? u_resolution.x : givenBoxSize.x,\n  (u_worldHeight == 0.) ? u_resolution.y : givenBoxSize.y\n  );\n  patternBoxRatio = patternBoxGivenSize.x / patternBoxGivenSize.y;\n\n  vec3 boxSizeData = getBoxSize(patternBoxRatio, patternBoxGivenSize);\n  v_patternBoxSize = boxSizeData.xy;\n  float patternBoxNoFitBoxWidth = boxSizeData.z;\n  vec2 patternBoxScale = u_resolution.xy / v_patternBoxSize;\n\n  v_patternUV = uv;\n  v_patternUV += graphicOffset / patternBoxScale;\n  v_patternUV += boxOrigin;\n  v_patternUV -= boxOrigin / patternBoxScale;\n  v_patternUV *= u_resolution.xy;\n  v_patternUV /= u_pixelRatio;\n  if (u_fit > 0.) {\n    v_patternUV *= (patternBoxNoFitBoxWidth / v_patternBoxSize.x);\n  }\n  v_patternUV /= u_scale;\n  v_patternUV = graphicRotation * v_patternUV;\n  v_patternUV += boxOrigin / patternBoxScale;\n  v_patternUV -= boxOrigin;\n  // x100 is a default multiplier between vertex and fragmant shaders\n  // we use it to avoid UV presision issues\n  v_patternUV *= .01;\n\n  // ===================================================\n\n  vec2 imageBoxSize;\n  if (u_fit == 1.) { // contain\n    imageBoxSize.x = min(u_resolution.x / u_imageAspectRatio, u_resolution.y) * u_imageAspectRatio;\n  } else if (u_fit == 2.) { // cover\n    imageBoxSize.x = max(u_resolution.x / u_imageAspectRatio, u_resolution.y) * u_imageAspectRatio;\n  } else {\n    imageBoxSize.x = min(10.0, 10.0 / u_imageAspectRatio * u_imageAspectRatio);\n  }\n  imageBoxSize.y = imageBoxSize.x / u_imageAspectRatio;\n  vec2 imageBoxScale = u_resolution.xy / imageBoxSize;\n\n  v_imageUV = uv;\n  v_imageUV *= imageBoxScale;\n  v_imageUV += boxOrigin * (imageBoxScale - 1.);\n  v_imageUV += graphicOffset;\n  v_imageUV /= u_scale;\n  v_imageUV.x *= u_imageAspectRatio;\n  v_imageUV = graphicRotation * v_imageUV;\n  v_imageUV.x /= u_imageAspectRatio;\n\n  v_imageUV += .5;\n  v_imageUV.y = 1. - v_imageUV.y;\n}`;\n\n/** Paper's liquidMetal fragment stage, unmodified. */\nexport const FRAG_SHADER_SRC: string = liquidMetalFragmentShader;\n\n/** Compile a single shader stage. Throws with the GL info log on failure. */\nexport function compileShader(\n  gl: WebGL2RenderingContext,\n  type: number,\n  source: string\n): WebGLShader {\n  const shader = gl.createShader(type);\n  if (!shader) throw new Error('metal-fx: gl.createShader returned null');\n  gl.shaderSource(shader, source);\n  gl.compileShader(shader);\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    const info = gl.getShaderInfoLog(shader);\n    gl.deleteShader(shader);\n    throw new Error(`metal-fx: shader compile failed: ${info ?? '(no info log)'}`);\n  }\n  return shader;\n}\n\n/** Link a vertex + fragment shader pair into a complete program. */\nexport function linkProgram(\n  gl: WebGL2RenderingContext,\n  vert: WebGLShader,\n  frag: WebGLShader\n): WebGLProgram {\n  const program = gl.createProgram();\n  if (!program) throw new Error('metal-fx: gl.createProgram returned null');\n  gl.attachShader(program, vert);\n  gl.attachShader(program, frag);\n  gl.linkProgram(program);\n  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n    const info = gl.getProgramInfoLog(program);\n    gl.deleteProgram(program);\n    throw new Error(`metal-fx: program link failed: ${info ?? '(no info log)'}`);\n  }\n  return program;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/renderer/loop.ts",
          "target": "@components/effects/metal-fx/upstream/engine/renderer/loop.ts",
          "type": "registry:component",
          "content": "/** Animation loop, per-frame compositing, and instance lifecycle. */\nimport { hexToRgba } from '../color';\nimport { FRAME_INTERVAL_MS, GLOW_SKIP_FRAMES } from '../perfConfig';\nimport { PRESETS, type PresetMode, type PresetName, type PresetTheme } from '../presets';\nimport {\n  SHARED,\n  CANONICAL_PILL_W,\n  CANONICAL_PILL_H,\n  CIRCLE_SHADER_SCALE,\n  PILL_SHADER_SCALE,\n  ensureSharedRenderer,\n  setContextRestoredCallback,\n  teardownSharedRenderer,\n  type DeformFn,\n  type DeformLayers,\n  type MaskFn,\n  type MetalFxInstance,\n} from './core';\nimport { ensureGlowPixels } from './sampling';\nimport { createOutlineBuf, roundRectOutline, type OutlineBuf } from './outline';\n\n// Restart the animation loop when the browser restores the GL context.\nsetContextRestoredCallback(() => {\n  if (SHARED && SHARED.instances.size > 0 && SHARED.pausedAtMs === null) {\n    startSharedLoop();\n  }\n});\n\nif (typeof document !== 'undefined') {\n  document.addEventListener('visibilitychange', () => {\n    if (!SHARED || SHARED.pausedAtMs !== null || SHARED.contextLost) return;\n    if (document.hidden) {\n      stopSharedLoop();\n    } else if (SHARED.instances.size > 0) {\n      startSharedLoop();\n    }\n  });\n}\n\n// ─── Instance lifecycle ───────────────────────────────────────────────────\n\ninterface CreateInstanceOptions {\n  hostCanvas: HTMLCanvasElement;\n  cssWidth: number;\n  cssHeight: number;\n  cornerRadius: number;\n  kind: 'pill' | 'circle';\n  shaderScale?: number;\n  ringCssPx?: number;\n  opacityMul?: number;\n  glowGain?: number;\n  paused?: boolean;\n  scale?: number;\n  onAfterFrame?: () => void;\n  onComposite?: () => void;\n  onFirstCopy?: () => void;\n  mask?: MaskFn | null;\n}\n\nexport function createInstance(opts: CreateInstanceOptions): MetalFxInstance {\n  const renderer = ensureSharedRenderer();\n  const ctx = opts.hostCanvas.getContext('2d', { alpha: true });\n  if (!ctx) throw new Error('metal-fx: canvas 2D context unavailable');\n\n  const scale = opts.scale ?? 1;\n  const inst: MetalFxInstance = {\n    canvas: opts.hostCanvas, ctx,\n    cssWidth: opts.cssWidth, cssHeight: opts.cssHeight,\n    cornerRadius: opts.cornerRadius,\n    kind: opts.kind,\n    ringCssPx: opts.ringCssPx ?? (opts.kind === 'circle' ? 2 : 1) * scale,\n    shaderScale: opts.shaderScale ?? (opts.kind === 'circle' ? CIRCLE_SHADER_SCALE : PILL_SHADER_SCALE) * scale,\n    opacityMul: opts.opacityMul ?? 1,\n    glowGain: opts.glowGain ?? 1,\n    visible: true,\n    paused: opts.paused ?? false,\n    everCopied: false,\n    frozen: null,\n    dpr: typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1,\n    scale,\n    onAfterFrame: opts.onAfterFrame,\n    onComposite: opts.onComposite,\n    onFirstCopy: opts.onFirstCopy,\n    mask: opts.mask ?? null,\n    deform: null,\n    deformLayers: null,\n    overscan: 0,\n    cursorLight: null,\n    glowFast: false,\n    rawCanvas: null,\n    wantRaw: false,\n    ringCanvas: null,\n    wantRing: false,\n  };\n  resizeInstanceCanvas(inst);\n  renderer.instances.add(inst);\n  if (renderer.rafId === 0 && renderer.pausedAtMs === null) startSharedLoop();\n  return inst;\n}\n\nexport function destroyInstance(inst: MetalFxInstance): void {\n  if (!SHARED) return;\n  SHARED.instances.delete(inst);\n  const qi = SHARED.glowQueue.indexOf(inst);\n  if (qi !== -1) SHARED.glowQueue.splice(qi, 1);\n  if (SHARED.instances.size === 0) { stopSharedLoop(); teardownSharedRenderer(); }\n}\n\nexport function registerGlowInstance(inst: MetalFxInstance): void {\n  if (!SHARED) return;\n  if (!SHARED.glowQueue.includes(inst)) SHARED.glowQueue.push(inst);\n}\n\nexport function unregisterGlowInstance(inst: MetalFxInstance): void {\n  if (!SHARED) return;\n  const i = SHARED.glowQueue.indexOf(inst);\n  if (i !== -1) SHARED.glowQueue.splice(i, 1);\n}\n\nexport function updateInstance(\n  inst: MetalFxInstance,\n  patch: Partial<Pick<MetalFxInstance, 'cssWidth' | 'cssHeight' | 'cornerRadius' | 'kind' | 'shaderScale' | 'ringCssPx' | 'opacityMul' | 'glowGain' | 'paused' | 'scale' | 'mask'>>\n): void {\n  let dirty = false;\n  if (patch.mask !== undefined) inst.mask = patch.mask;\n  if (patch.cssWidth !== undefined && patch.cssWidth !== inst.cssWidth) { inst.cssWidth = patch.cssWidth; dirty = true; }\n  if (patch.cssHeight !== undefined && patch.cssHeight !== inst.cssHeight) { inst.cssHeight = patch.cssHeight; dirty = true; }\n  if (patch.cornerRadius !== undefined) inst.cornerRadius = patch.cornerRadius;\n  if (patch.scale !== undefined) inst.scale = patch.scale;\n  if (patch.kind !== undefined && patch.kind !== inst.kind) {\n    inst.kind = patch.kind;\n    if (patch.shaderScale === undefined) inst.shaderScale = (patch.kind === 'circle' ? CIRCLE_SHADER_SCALE : PILL_SHADER_SCALE) * inst.scale;\n    if (patch.ringCssPx === undefined) inst.ringCssPx = (patch.kind === 'circle' ? 2 : 1) * inst.scale;\n  }\n  if (patch.shaderScale !== undefined) inst.shaderScale = patch.shaderScale;\n  if (patch.ringCssPx !== undefined) inst.ringCssPx = patch.ringCssPx;\n  if (patch.opacityMul !== undefined) inst.opacityMul = patch.opacityMul;\n  if (patch.glowGain !== undefined) inst.glowGain = patch.glowGain;\n  if (patch.paused !== undefined && patch.paused !== inst.paused) {\n    inst.paused = patch.paused;\n    // Freeze on the frame the instance is showing right now; drop the copy\n    // on unpause so composites go back to the live frame.\n    if (patch.paused) freezeFrame(inst); else inst.frozen = null;\n    // Unpausing should kick the loop if it had idled because every visible\n    // instance was paused.\n    if (!patch.paused && SHARED && SHARED.rafId === 0 && SHARED.pausedAtMs === null && !SHARED.contextLost) {\n      startSharedLoop();\n    }\n  }\n  if (dirty) resizeInstanceCanvas(inst);\n}\n\nexport function setInstanceVisible(inst: MetalFxInstance, visible: boolean): void {\n  inst.visible = visible;\n  if (visible && SHARED && SHARED.rafId === 0 && SHARED.pausedAtMs === null && !SHARED.contextLost) {\n    startSharedLoop();\n  }\n}\n\n/**\n * Attach (or clear) a vector deformation to the instance that owns `canvas`.\n * `overscan` grows the canvas by that many CSS px on every side so outward\n * bulges aren't clipped. Redraws immediately so a paused instance updates.\n */\nexport function setInstanceDeform(\n  canvas: HTMLCanvasElement,\n  deform: DeformFn | null,\n  layers: DeformLayers | null = null,\n  overscan = 0\n): boolean {\n  const inst = findInstance(canvas);\n  if (!inst) return false;\n  inst.deform = deform;\n  inst.deformLayers = deform ? layers : null;\n  const o = deform ? Math.max(0, Math.round(overscan)) : 0;\n  if (o !== inst.overscan) { inst.overscan = o; resizeInstanceCanvas(inst); }\n  copyShaderToInstance(inst);\n  return true;\n}\n\n/** Re-rasterise an instance after the devicePixelRatio changed (browser\n *  zoom, a display switch). The CSS box is unchanged, so no ResizeObserver\n *  fires; without this the canvas stays at the old backing resolution. */\nexport function refreshInstanceDpr(inst: MetalFxInstance): boolean {\n  const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n  if (dpr === inst.dpr) return false;\n  resizeInstanceCanvas(inst);\n  copyShaderToInstance(inst);\n  return true;\n}\n\n/** Re-composite one instance now — for callers driving `deform` per frame at\n *  a higher rate than the shared 15 fps loop. */\nexport function redrawInstance(canvas: HTMLCanvasElement): void {\n  const inst = findInstance(canvas);\n  if (inst) copyShaderToInstance(inst);\n}\n\nfunction findInstance(canvas: HTMLCanvasElement): MetalFxInstance | null {\n  if (!SHARED) return null;\n  for (const inst of SHARED.instances) if (inst.canvas === canvas) return inst;\n  return null;\n}\n\n/** Set by `setSharedPresetMode`. While non-null it wins over the named\n *  presets, so a live tuning surface isn't fighting every `<MetalFx preset>`\n *  effect that re-runs on a theme toggle. */\nlet presetOverride: PresetMode | null = null;\n\nexport function setSharedPreset(name: PresetName, theme: PresetTheme): void {\n  const s = ensureSharedRenderer();\n  s.preset = presetOverride ?? PRESETS[name].modes[theme];\n  s.presetDirty = true;\n}\n\n/**\n * Push raw Paper liquidMetal parameters into the shared renderer, bypassing\n * the named presets. Pass `null` to hand control back to `preset` / `theme`.\n *\n * This exists for the playground: every instance shares one GL program, so\n * tuning is necessarily global rather than per-instance.\n */\nexport function setSharedPresetMode(mode: PresetMode | null): void {\n  const s = ensureSharedRenderer();\n  presetOverride = mode;\n  if (mode) {\n    s.preset = mode;\n    s.presetDirty = true;\n  }\n}\n\n/** The preset the shared renderer is currently drawing with, or null before\n *  any instance has mounted. Read-only snapshot — mutate via the setters. */\nexport function getSharedPreset(): PresetMode | null {\n  return SHARED ? { ...SHARED.preset } : null;\n}\n\nexport function pauseShared(): void {\n  if (!SHARED || SHARED.pausedAtMs !== null) return;\n  SHARED.pausedAtMs = performance.now();\n  stopSharedLoop();\n}\n\nexport function resumeShared(): void {\n  if (!SHARED || SHARED.pausedAtMs === null) return;\n  SHARED.pausedMs += performance.now() - SHARED.pausedAtMs;\n  SHARED.pausedAtMs = null;\n  if (SHARED.instances.size > 0) startSharedLoop();\n}\n\nexport function getSharedFrameCount(): number {\n  return SHARED?.frameCount ?? 0;\n}\n\n// ─── Glow callback ────────────────────────────────────────────────────────\n\n/** Returns true when the glow wants per-frame ticks (mid-fade). */\nexport type GlowCallback = (inst: MetalFxInstance, nowMs: number) => boolean | void;\nlet _glowCallback: GlowCallback | null = null;\n\nexport function setGlowCallback(cb: GlowCallback | null): void {\n  _glowCallback = cb;\n}\n\n/** Run one glow update for an instance now — for drivers (cursor light) that\n *  need the hotspot to move at pointer rate rather than the shared 15 fps. */\nexport function tickInstanceGlow(inst: MetalFxInstance, nowMs: number): void {\n  if (!_glowCallback || !SHARED || !inst.visible || inst.paused) return;\n  if (!SHARED.glowQueue.includes(inst)) return;\n  inst.glowFast = !!_glowCallback(inst, nowMs);\n}\n\n// ─── Internal rendering ───────────────────────────────────────────────────\n\nfunction resizeInstanceCanvas(inst: MetalFxInstance): void {\n  inst.dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n  const o = inst.overscan;\n  const w = Math.max(1, Math.round((inst.cssWidth + 2 * o) * inst.dpr));\n  const h = Math.max(1, Math.round((inst.cssHeight + 2 * o) * inst.dpr));\n  if (inst.canvas.width !== w) inst.canvas.width = w;\n  if (inst.canvas.height !== h) inst.canvas.height = h;\n  // Overscan: grow the element past its box and drop the CSS radius clip so\n  // displaced geometry outside the rounded box is visible.\n  const st = inst.canvas.style;\n  if (o > 0) {\n    st.left = `${-o}px`; st.top = `${-o}px`;\n    st.width = `calc(100% + ${2 * o}px)`; st.height = `calc(100% + ${2 * o}px)`;\n    st.borderRadius = '0';\n  } else if (st.left !== '') {\n    st.left = ''; st.top = ''; st.width = '100%'; st.height = '100%'; st.borderRadius = '';\n  }\n}\n\nfunction punchInnerHole(inst: MetalFxInstance): void {\n  const { ctx, dpr, canvas } = inst;\n  const stroke = inst.ringCssPx * dpr;\n  const w = canvas.width, h = canvas.height;\n  const innerR = Math.max(0, (inst.cornerRadius - inst.ringCssPx) * dpr);\n  ctx.save();\n  ctx.globalCompositeOperation = 'destination-out';\n  ctx.fillStyle = '#000';\n  ctx.beginPath();\n  ctx.roundRect(stroke, stroke, w - 2 * stroke, h - 2 * stroke, innerR);\n  ctx.fill();\n  ctx.restore();\n}\n\nconst _outline: OutlineBuf = createOutlineBuf();\n\n/** Trace a (possibly deformed) rounded rect into the ctx, in device px. */\nfunction traceDeformedRoundRect(\n  ctx: CanvasRenderingContext2D,\n  x: number, y: number, w: number, h: number, r: number,\n  deform: DeformFn, dpr: number\n): void {\n  const { xy, n } = roundRectOutline(x, y, w, h, r, deform, _outline);\n  ctx.beginPath();\n  for (let i = 0; i < n; i++) {\n    if (i === 0) ctx.moveTo(xy[0] * dpr, xy[1] * dpr);\n    else ctx.lineTo(xy[i * 2] * dpr, xy[i * 2 + 1] * dpr);\n  }\n  ctx.closePath();\n}\n\n/** Copy the current shared frame into the instance's own still. */\nfunction freezeFrame(inst: MetalFxInstance): HTMLCanvasElement | null {\n  if (!SHARED) return null;\n  const live: CanvasImageSource = SHARED.frameBitmap ?? SHARED.glCanvas;\n  const w = SHARED.glCanvas.width, h = SHARED.glCanvas.height;\n  if (w < 1 || h < 1) return null;\n  let fc = inst.frozen;\n  if (!fc) { fc = document.createElement('canvas'); inst.frozen = fc; }\n  if (fc.width !== w || fc.height !== h) { fc.width = w; fc.height = h; }\n  const g = fc.getContext('2d');\n  if (!g) { inst.frozen = null; return null; }\n  g.clearRect(0, 0, w, h);\n  g.drawImage(live, 0, 0);\n  return fc;\n}\n\nfunction copyShaderToInstance(inst: MetalFxInstance): void {\n  if (!SHARED) return;\n  // A paused instance composites from its frozen frame — a bend or a resize\n  // must not pull in the live shader, or the \"paused\" ring plays on hover.\n  const src: CanvasImageSource = (inst.paused ? (inst.frozen ?? freezeFrame(inst)) : null) ?? SHARED.frameBitmap ?? SHARED.glCanvas;\n  const dpr = inst.dpr;\n  const dw = inst.canvas.width, dh = inst.canvas.height;\n  if (dw < 1 || dh < 1) return;\n  // Box = the element's own CSS box in device px; the canvas may be larger\n  // by `overscan` on every side while deforming.\n  const bw = Math.max(1, Math.round(inst.cssWidth * dpr));\n  const bh = Math.max(1, Math.round(inst.cssHeight * dpr));\n  const od = inst.overscan * dpr;\n\n  const cw = (src as { width: number }).width, ch = (src as { height: number }).height;\n  const bdW = CANONICAL_PILL_W * dpr, bdH = CANONICAL_PILL_H * dpr;\n  let srcW = (bw * (cw / bdW)) / inst.shaderScale;\n  let srcH = (bh * (ch / bdH)) / inst.shaderScale;\n  if (srcW > cw) srcW = cw;\n  if (srcH > ch) srcH = ch;\n  const sx = Math.max(0, (cw - srcW) / 2);\n  const sy = Math.max(0, (ch - srcH) / 2);\n\n  // Paper's shader has no `u_shaderOpacity` equivalent, so the preset-level\n  // opacity rides along with the per-instance `strength` multiplier here\n  // instead of being applied on the GPU.\n  const alpha = inst.opacityMul * SHARED.preset.shaderOpacity;\n  const ctx = inst.ctx;\n\n  ctx.clearRect(0, 0, dw, dh);\n\n  const deform = inst.deform;\n  if (inst.mask) {\n    // ── Custom mask (metal text / glyph) ─────────────────────────────\n    if (alpha < 1) ctx.globalAlpha = alpha;\n    ctx.drawImage(src, sx, sy, srcW, srcH, 0, 0, dw, dh);\n    if (alpha < 1) ctx.globalAlpha = 1;\n    if (inst.wantRaw) {\n      // Keep the sheet before it is cut to the glyphs, for reflections.\n      let rc = inst.rawCanvas;\n      if (!rc) { rc = document.createElement('canvas'); inst.rawCanvas = rc; }\n      if (rc.width !== dw || rc.height !== dh) { rc.width = dw; rc.height = dh; }\n      const rg = rc.getContext('2d');\n      if (rg) { rg.clearRect(0, 0, dw, dh); rg.drawImage(inst.canvas, 0, 0); }\n    }\n    ctx.save();\n    ctx.globalCompositeOperation = 'destination-in';\n    ctx.fillStyle = '#000';\n    inst.mask(ctx, dw, dh, dpr);\n    ctx.restore();\n    ctx.globalCompositeOperation = 'source-over';\n  } else if (!deform) {\n    if (alpha < 1) ctx.globalAlpha = alpha;\n    ctx.drawImage(src, sx, sy, srcW, srcH, 0, 0, dw, dh);\n    if (alpha < 1) ctx.globalAlpha = 1;\n    punchInnerHole(inst);\n  } else {\n    // ── Vector-deformed ring ──────────────────────────────────────────\n    // The shader texture is laid down over the (overscanned) canvas, then\n    // masked to a displaced outer outline minus a displaced inner outline.\n    // Because the mask is geometry, stretched regions stay crisp.\n    const W = inst.cssWidth, H = inst.cssHeight;\n    const R = inst.cornerRadius, ring = inst.ringCssPx;\n    const layers = inst.deformLayers;\n    ctx.save();\n    ctx.translate(od, od);\n\n    // Texture: over the box plus the overscan margin, so an outward bulge\n    // still has shader pixels under it. The source crop grows by the same\n    // ratio so the mapping *inside the box* is identical to the rigid path —\n    // otherwise the pattern jumps scale the moment a bend starts or ends.\n    // If the enlarged crop would exceed the GL buffer, shrink the *destination*\n    // instead of the crop's scale — a scale change is a visible texture jump.\n    const scX = bw / srcW, scY = bh / srcH;          // dest px per source px\n    const esW = Math.min(cw, srcW * (bw + 2 * od) / bw);\n    const esH = Math.min(ch, srcH * (bh + 2 * od) / bh);\n    const esx = Math.max(0, (cw - esW) / 2);\n    const esy = Math.max(0, (ch - esH) / 2);\n    const dW = esW * scX, dH = esH * scY;\n    if (alpha < 1) ctx.globalAlpha = alpha;\n    ctx.drawImage(src, esx, esy, esW, esH, bw / 2 - dW / 2, bh / 2 - dH / 2, dW, dH);\n    if (alpha < 1) ctx.globalAlpha = 1;\n\n    ctx.globalCompositeOperation = 'destination-in';\n    traceDeformedRoundRect(ctx, 0, 0, W, H, R, deform, dpr);\n    ctx.fillStyle = '#000';\n    ctx.fill();\n\n    ctx.globalCompositeOperation = 'destination-out';\n    traceDeformedRoundRect(ctx, ring, ring, W - 2 * ring, H - 2 * ring, Math.max(0, R - ring), deform, dpr);\n    ctx.fill();\n\n    if (inst.wantRing) {\n      // For reflections: the same thing the rigid path produces — the full\n      // texture with the (deformed) inner hole punched, no outer mask. The\n      // rigid canvas is never outer-masked either (CSS border-radius clips\n      // it on screen), so mirroring a masked ring here would dim the\n      // reflection the moment a bend starts.\n      let rc = inst.ringCanvas;\n      if (!rc) { rc = document.createElement('canvas'); inst.ringCanvas = rc; }\n      if (rc.width !== dw || rc.height !== dh) { rc.width = dw; rc.height = dh; }\n      const rg = rc.getContext('2d');\n      if (rg) {\n        rg.setTransform(1, 0, 0, 1, 0, 0);\n        rg.globalCompositeOperation = 'source-over';\n        rg.clearRect(0, 0, dw, dh);\n        rg.translate(od, od);\n        if (alpha < 1) rg.globalAlpha = alpha;\n        rg.drawImage(src, esx, esy, esW, esH, bw / 2 - dW / 2, bh / 2 - dH / 2, dW, dH);\n        rg.globalAlpha = 1;\n        rg.globalCompositeOperation = 'destination-out';\n        traceDeformedRoundRect(rg, ring, ring, W - 2 * ring, H - 2 * ring, Math.max(0, R - ring), deform, dpr);\n        rg.fillStyle = '#000';\n        rg.fill();\n        rg.globalCompositeOperation = 'source-over';\n        rg.setTransform(1, 0, 0, 1, 0, 0);\n      }\n    }\n\n    if (layers?.hairline) {\n      const hl = layers.hairline;\n      ctx.globalCompositeOperation = 'destination-over';\n      traceDeformedRoundRect(ctx, hl.inset, hl.inset, W - 2 * hl.inset, H - 2 * hl.inset, Math.max(0, R - hl.inset), deform, dpr);\n      ctx.lineWidth = hl.width * dpr;\n      ctx.strokeStyle = hl.color;\n      ctx.stroke();\n    }\n    if (layers?.fill) {\n      ctx.globalCompositeOperation = 'destination-over';\n      traceDeformedRoundRect(ctx, 0, 0, W, H, R, deform, dpr);\n      ctx.fillStyle = layers.fill;\n      ctx.fill();\n    }\n    if (layers?.rim) {\n      const rim = layers.rim;\n      ctx.globalCompositeOperation = 'source-over';\n      // Inset band of `width` starting `inset` in from the outline: stroke\n      // its centre line, then clip to the outline so nothing spills out.\n      ctx.save();\n      traceDeformedRoundRect(ctx, 0, 0, W, H, R, deform, dpr);\n      ctx.clip();\n      const c = rim.inset + rim.width / 2;\n      traceDeformedRoundRect(ctx, c, c, W - 2 * c, H - 2 * c, Math.max(0, R - c), deform, dpr);\n      ctx.lineWidth = rim.width * dpr;\n      ctx.strokeStyle = rim.color;\n      ctx.stroke();\n      ctx.restore();\n    }\n    ctx.restore();\n    ctx.globalCompositeOperation = 'source-over';\n  }\n\n  inst.onComposite?.();\n  if (inst.onFirstCopy) { const cb = inst.onFirstCopy; inst.onFirstCopy = undefined; cb(); }\n  inst.onAfterFrame?.();\n}\n\nfunction uploadPresetUniforms(): void {\n  if (!SHARED) return;\n  const { gl, uniforms, preset, glCanvas, dpr } = SHARED;\n\n  // Shared by both stages.\n  if (uniforms.u_resolution) gl.uniform2f(uniforms.u_resolution, glCanvas.width, glCanvas.height);\n  // Paper's vertex stage divides the world box by this; leaving it at the\n  // default 0 collapses the box and the shader renders nothing.\n  if (uniforms.u_pixelRatio) gl.uniform1f(uniforms.u_pixelRatio, dpr);\n\n  // Fragment — material.\n  if (uniforms.u_colorBack) gl.uniform4fv(uniforms.u_colorBack, hexToRgba(preset.colorBack));\n  if (uniforms.u_colorTint) gl.uniform4fv(uniforms.u_colorTint, hexToRgba(preset.colorTint));\n  if (uniforms.u_repetition) gl.uniform1f(uniforms.u_repetition, preset.repetition);\n  if (uniforms.u_softness) gl.uniform1f(uniforms.u_softness, preset.softness);\n  if (uniforms.u_shiftRed) gl.uniform1f(uniforms.u_shiftRed, preset.shiftRed);\n  if (uniforms.u_shiftBlue) gl.uniform1f(uniforms.u_shiftBlue, preset.shiftBlue);\n  if (uniforms.u_distortion) gl.uniform1f(uniforms.u_distortion, preset.distortion);\n  if (uniforms.u_contour) gl.uniform1f(uniforms.u_contour, preset.contour);\n  if (uniforms.u_angle) gl.uniform1f(uniforms.u_angle, preset.angle);\n  if (uniforms.u_shape) gl.uniform1f(uniforms.u_shape, preset.shape);\n  // Procedural only — metal-fx never feeds a logo through the effect.\n  if (uniforms.u_isImage) gl.uniform1i(uniforms.u_isImage, 0);\n  if (uniforms.u_imageAspectRatio) gl.uniform1f(uniforms.u_imageAspectRatio, 1);\n\n  // Vertex — sizing.\n  if (uniforms.u_originX) gl.uniform1f(uniforms.u_originX, preset.originX);\n  if (uniforms.u_originY) gl.uniform1f(uniforms.u_originY, preset.originY);\n  if (uniforms.u_worldWidth) gl.uniform1f(uniforms.u_worldWidth, preset.worldWidth);\n  if (uniforms.u_worldHeight) gl.uniform1f(uniforms.u_worldHeight, preset.worldHeight);\n  if (uniforms.u_fit) gl.uniform1f(uniforms.u_fit, preset.fit);\n  if (uniforms.u_scale) gl.uniform1f(uniforms.u_scale, preset.scale);\n  if (uniforms.u_rotation) gl.uniform1f(uniforms.u_rotation, preset.rotation);\n  if (uniforms.u_offsetX) gl.uniform1f(uniforms.u_offsetX, preset.offsetX);\n  if (uniforms.u_offsetY) gl.uniform1f(uniforms.u_offsetY, preset.offsetY);\n\n  SHARED.presetDirty = false;\n}\n\nfunction renderSharedFrame(now: number): void {\n  if (!SHARED) return;\n  const { gl, uniforms, preset, glCanvas } = SHARED;\n  const t = ((now - SHARED.startMs - SHARED.pausedMs) / 1000) * preset.speed;\n\n  gl.viewport(0, 0, glCanvas.width, glCanvas.height);\n  gl.clearColor(0, 0, 0, 0);\n  gl.clear(gl.COLOR_BUFFER_BIT);\n\n  if (SHARED.presetDirty) uploadPresetUniforms();\n  if (uniforms.u_time) gl.uniform1f(uniforms.u_time, t);\n\n  gl.drawArrays(gl.TRIANGLES, 0, 6);\n  SHARED.frameCount++;\n}\n\nlet lastFrameMs = 0;\n\nfunction tick(now: number): void {\n  if (!SHARED) return;\n  if (SHARED.contextLost) { SHARED.rafId = 0; return; }\n\n  // Loop stays alive while at least one visible instance still has work to do\n  // — i.e. it's either unpaused (needs a fresh copy each frame) or paused but\n  // hasn't yet painted its first frame (initial-mount-paused case).\n  let anyWork = false;\n  for (const inst of SHARED.instances) {\n    if (inst.visible && (!inst.paused || !inst.everCopied)) { anyWork = true; break; }\n  }\n  if (!anyWork) { SHARED.rafId = 0; return; }\n\n  SHARED.rafId = requestAnimationFrame(tick);\n  if (now - lastFrameMs < FRAME_INTERVAL_MS) {\n    // Between shader frames, keep fading glows moving at display rate.\n    if (_glowCallback) {\n      for (const inst of SHARED.glowQueue) {\n        if (inst.glowFast && inst.visible && !inst.paused) inst.glowFast = !!_glowCallback(inst, now);\n      }\n    }\n    return;\n  }\n  lastFrameMs = now;\n\n  renderSharedFrame(now);\n\n  // The only readback: after the draw, before the frame is transferred away.\n  ensureGlowPixels();\n  if (SHARED.useOffscreen) {\n    SHARED.frameBitmap?.close();\n    SHARED.frameBitmap = (SHARED.glCanvas as OffscreenCanvas).transferToImageBitmap();\n  }\n\n  for (const inst of SHARED.instances) {\n    if (!inst.visible) continue;\n    if (inst.paused && inst.everCopied) continue;\n    copyShaderToInstance(inst);\n    inst.everCopied = true;\n  }\n\n  // Every visible glow instance, every Nth tick. Round-robin (one instance\n  // per tick) made each halo's update rate depend on how many rings were on\n  // the page — five rings meant ~330 ms between updates, so a 300 ms fade\n  // landed in a single step and read as a flash. updateGlow costs ~0.05 ms.\n  if (_glowCallback && SHARED.glowQueue.length > 0 && ++SHARED.glowSkip % GLOW_SKIP_FRAMES === 0) {\n    for (const inst of SHARED.glowQueue) {\n      // Skip paused instances so their halo also freezes (otherwise the\n      // catch-light would keep travelling on a frozen ring).\n      if (inst.visible && !inst.paused) inst.glowFast = !!_glowCallback(inst, now);\n    }\n  }\n}\n\nfunction startSharedLoop(): void {\n  if (!SHARED || SHARED.rafId !== 0) return;\n  SHARED.rafId = requestAnimationFrame(tick);\n}\n\nfunction stopSharedLoop(): void {\n  if (!SHARED) return;\n  if (SHARED.rafId !== 0) cancelAnimationFrame(SHARED.rafId);\n  SHARED.rafId = 0;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/renderer/sampling.ts",
          "target": "@components/effects/metal-fx/upstream/engine/renderer/sampling.ts",
          "type": "registry:component",
          "content": "/**\n * Pixel readback and luminance/colour sampling from the shared GL canvas.\n *\n * All glow luminance/color sampling reads from a shared pixel buffer\n * (SHARED.glowPixels). The buffer is refreshed via gl.readPixels at most\n * every GLOW_READBACK_INTERVAL_MS to avoid the expensive GPU→CPU pipeline\n * flush on every frame. The plasma shader evolves slowly so stale data is\n * visually indistinguishable.\n *\n * The readback happens in exactly one place: the render loop, right after\n * the shader frame is drawn and before the OffscreenCanvas frame is\n * transferred (`transferToImageBitmap` leaves the drawing buffer cleared).\n * The samplers below never read back on their own — they used to, and any\n * sample taken between shader frames (fast glow ticks while a fade runs,\n * the cursor-light loop at pointer rate) that landed on an elapsed interval\n * read the cleared buffer: black tint, zero luminance, a halo that vanished\n * with no fade and stayed gone for the next interval.\n */\nimport { GLOW_READBACK_INTERVAL_MS } from '../perfConfig';\nimport { SHARED, CANONICAL_PILL_W, CANONICAL_PILL_H, type MetalFxInstance, type ShaderRGB } from './core';\nlet _lastReadbackMs = 0;\n\nexport function ensureGlowPixels(): void {\n  if (!SHARED) return;\n  const now = performance.now();\n  if (now - _lastReadbackMs < GLOW_READBACK_INTERVAL_MS) return;\n  _lastReadbackMs = now;\n  const { gl, glCanvas } = SHARED;\n  const cw = glCanvas.width, ch = glCanvas.height;\n  if (SHARED.glowPixelsW !== cw || SHARED.glowPixelsH !== ch) {\n    SHARED.glowPixelsW = cw;\n    SHARED.glowPixelsH = ch;\n    SHARED.glowPixels = new Uint8Array(cw * ch * 4);\n  }\n  gl.readPixels(0, 0, cw, ch, gl.RGBA, gl.UNSIGNED_BYTE, SHARED.glowPixels);\n}\n\n/**\n * Map per-instance CSS-px glow coordinates to the shared GL pixel buffer.\n *\n * The GL canvas is shared across all instances. Each instance \"sees\" a\n * different crop of it (computed identically to copyShaderToInstance).\n * This function reverses that mapping: given a CSS-px coordinate on the\n * instance, it returns the (bx, by) index into SHARED.glowPixels.\n *\n * readPixels stores rows bottom-up (GL convention) so Y is flipped.\n */\nconst _map = { bx: 0, by: 0 };\n\nfunction mapToGlowBuf(inst: MetalFxInstance, cssPxX: number, cssPxY: number): typeof _map {\n  if (!SHARED) { _map.bx = 0; _map.by = 0; return _map; }\n  const { glCanvas } = SHARED;\n  const cw = glCanvas.width, ch = glCanvas.height;\n  const dpr = inst.dpr;\n  const dw = inst.cssWidth * dpr, dh = inst.cssHeight * dpr;\n  const bdW = CANONICAL_PILL_W * dpr, bdH = CANONICAL_PILL_H * dpr;\n  let srcW = (dw * (cw / bdW)) / inst.shaderScale;\n  let srcH = (dh * (ch / bdH)) / inst.shaderScale;\n  if (srcW > cw) srcW = cw;\n  if (srcH > ch) srcH = ch;\n  const sx = (cw - srcW) / 2;\n  const sy = (ch - srcH) / 2;\n  const glX = sx + (cssPxX / inst.cssWidth) * srcW;\n  const glY = sy + (cssPxY / inst.cssHeight) * srcH;\n  _map.bx = Math.round(glX);\n  _map.by = Math.round(ch - 1 - glY);\n  return _map;\n}\n\nconst _sr = { r: 0, g: 0, b: 0, lum: 0, count: 0 };\n\nfunction sampleRegion(\n  buf: Uint8Array, W: number, H: number,\n  bx: number, by: number, radius: number\n): typeof _sr {\n  const r = Math.max(1, radius | 0);\n  const x0 = Math.max(0, bx - r), x1 = Math.min(W, bx + r + 1);\n  const y0 = Math.max(0, by - r), y1 = Math.min(H, by + r + 1);\n  _sr.r = 0; _sr.g = 0; _sr.b = 0; _sr.lum = 0; _sr.count = 0;\n  for (let py = y0; py < y1; py++) {\n    const row = py * W;\n    for (let px = x0; px < x1; px++) {\n      const i = (row + px) * 4;\n      _sr.r += buf[i]; _sr.g += buf[i + 1]; _sr.b += buf[i + 2];\n      _sr.lum += (0.2126 * buf[i] + 0.7152 * buf[i + 1] + 0.0722 * buf[i + 2]) / 255;\n      _sr.count++;\n    }\n  }\n  return _sr;\n}\n\nconst _rgb: ShaderRGB = { r: 255, g: 255, b: 255 };\n\nexport function sampleShaderLumAt(inst: MetalFxInstance, cssPxX: number, cssPxY: number, radius: number): number {\n  if (!SHARED) return 0;\n  const m = mapToGlowBuf(inst, cssPxX, cssPxY);\n  const s = sampleRegion(SHARED.glowPixels, SHARED.glowPixelsW, SHARED.glowPixelsH, m.bx, m.by, radius);\n  return s.count > 0 ? s.lum / s.count : 0;\n}\n\nexport function sampleShaderRGBAt(inst: MetalFxInstance, cssPxX: number, cssPxY: number, radius: number): ShaderRGB {\n  if (!SHARED) { _rgb.r = 255; _rgb.g = 255; _rgb.b = 255; return _rgb; }\n  const m = mapToGlowBuf(inst, cssPxX, cssPxY);\n  const s = sampleRegion(SHARED.glowPixels, SHARED.glowPixelsW, SHARED.glowPixelsH, m.bx, m.by, radius);\n  if (s.count === 0) { _rgb.r = 255; _rgb.g = 255; _rgb.b = 255; return _rgb; }\n  _rgb.r = s.r / s.count; _rgb.g = s.g / s.count; _rgb.b = s.b / s.count;\n  return _rgb;\n}\n\nexport function sampleShaderRGBChromatic(inst: MetalFxInstance, cssPxX: number, cssPxY: number, radius: number): ShaderRGB {\n  if (!SHARED) { _rgb.r = 255; _rgb.g = 255; _rgb.b = 255; return _rgb; }\n  const m = mapToGlowBuf(inst, cssPxX, cssPxY);\n  const { glowPixels: buf, glowPixelsW: W, glowPixelsH: H } = SHARED;\n  const r = Math.max(1, radius | 0);\n  const x0 = Math.max(0, m.bx - r), x1 = Math.min(W, m.bx + r + 1);\n  const y0 = Math.max(0, m.by - r), y1 = Math.min(H, m.by + r + 1);\n  let bestScore = -1;\n  _rgb.r = 255; _rgb.g = 255; _rgb.b = 255;\n  for (let py = y0; py < y1; py++) {\n    const row = py * W;\n    for (let px = x0; px < x1; px++) {\n      const i = (row + px) * 4;\n      const rr = buf[i], gg = buf[i + 1], bb = buf[i + 2];\n      const maxC = Math.max(rr, gg, bb), minC = Math.min(rr, gg, bb);\n      const sat = maxC > 0 ? (maxC - minC) / maxC : 0;\n      const score = sat * (0.35 + 0.65 * (maxC / 255));\n      if (score > bestScore) { bestScore = score; _rgb.r = rr; _rgb.g = gg; _rgb.b = bb; }\n    }\n  }\n  return _rgb;\n}\n\nconst _pk = { r: 255, g: 255, b: 255, lum: 0 };\n\n/** Brightest pixel in the window (not the mean) — for \"is the ring shining\n *  here\" questions, where a dark stripe next to a bright one should still\n *  read as lit. */\nexport function sampleShaderPeakAt(inst: MetalFxInstance, cssPxX: number, cssPxY: number, radius: number): typeof _pk {\n  _pk.r = 255; _pk.g = 255; _pk.b = 255; _pk.lum = 0;\n  if (!SHARED) return _pk;\n  const m = mapToGlowBuf(inst, cssPxX, cssPxY);\n  const { glowPixels: buf, glowPixelsW: W, glowPixelsH: H } = SHARED;\n  const r = Math.max(1, radius | 0);\n  const x0 = Math.max(0, m.bx - r), x1 = Math.min(W, m.bx + r + 1);\n  const y0 = Math.max(0, m.by - r), y1 = Math.min(H, m.by + r + 1);\n  for (let py = y0; py < y1; py++) {\n    const row = py * W;\n    for (let px = x0; px < x1; px++) {\n      const i = (row + px) * 4;\n      const lum = (0.2126 * buf[i] + 0.7152 * buf[i + 1] + 0.0722 * buf[i + 2]) / 255;\n      if (lum > _pk.lum) { _pk.lum = lum; _pk.r = buf[i]; _pk.g = buf[i + 1]; _pk.b = buf[i + 2]; }\n    }\n  }\n  return _pk;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/renderer/outline.ts",
          "target": "@components/effects/metal-fx/upstream/engine/renderer/outline.ts",
          "type": "registry:component",
          "content": "/**\n * Rounded-rect outline sampling shared by the canvas ring mask and the glow's\n * SVG mask, so both see the *same* deformed shape.\n *\n * Points go into a reusable flat `Float32Array` (x0,y0,x1,y1,…) — a bend\n * traces 6–8 outlines per frame at display rate, and allocating ~150 point\n * objects per outline was measurable GC churn.\n */\nimport type { DeformFn } from './core';\n\nexport interface OutlineBuf { xy: Float32Array; n: number }\n\nconst ARC_N = 14;\nconst EDGE_STEP = 1.5;\nconst _o = { x: 0, y: 0 };\n\nexport function createOutlineBuf(capacity = 512): OutlineBuf {\n  return { xy: new Float32Array(capacity * 2), n: 0 };\n}\n\n/**\n * Sample a rounded rect clockwise from the end of the top-left corner. Edges\n * every ~1.5 CSS px, 14 points per corner arc — dense enough that a gaussian\n * dent a few px wide stays smooth. `deform` (optional) displaces each point.\n */\nexport function roundRectOutline(\n  x: number, y: number, w: number, h: number, r: number,\n  deform: DeformFn | null,\n  buf: OutlineBuf = createOutlineBuf()\n): OutlineBuf {\n  r = Math.max(0, Math.min(r, Math.min(w, h) / 2));\n  // Upper bound on point count: 4 arcs + 4 edges.\n  const need = 4 * (ARC_N + 1) + Math.ceil((2 * (w + h)) / EDGE_STEP) + 8;\n  if (buf.xy.length < need * 2) buf.xy = new Float32Array(need * 2);\n  const xy = buf.xy;\n  let n = 0;\n  const push = (px: number, py: number) => {\n    if (deform) { deform(px, py, _o); xy[n * 2] = _o.x; xy[n * 2 + 1] = _o.y; }\n    else { xy[n * 2] = px; xy[n * 2 + 1] = py; }\n    n++;\n  };\n  const edge = (x0: number, y0: number, x1: number, y1: number) => {\n    const len = Math.hypot(x1 - x0, y1 - y0);\n    const k = Math.max(1, Math.ceil(len / EDGE_STEP));\n    for (let i = 0; i < k; i++) { const t = i / k; push(x0 + (x1 - x0) * t, y0 + (y1 - y0) * t); }\n  };\n  const arc = (cx: number, cy: number, a0: number, a1: number) => {\n    for (let i = 0; i <= ARC_N; i++) {\n      const a = a0 + (a1 - a0) * (i / ARC_N);\n      push(cx + r * Math.cos(a), cy + r * Math.sin(a));\n    }\n  };\n  edge(x + r, y, x + w - r, y);\n  arc(x + w - r, y + r, -Math.PI / 2, 0);\n  edge(x + w, y + r, x + w, y + h - r);\n  arc(x + w - r, y + h - r, 0, Math.PI / 2);\n  edge(x + w - r, y + h, x + r, y + h);\n  arc(x + r, y + h - r, Math.PI / 2, Math.PI);\n  edge(x, y + h - r, x, y + r);\n  arc(x + r, y + r, Math.PI, 1.5 * Math.PI);\n  buf.n = n;\n  return buf;\n}\n\n/** SVG path data for an outline (closed). */\nexport function outlinePathD(buf: OutlineBuf): string {\n  const { xy, n } = buf;\n  if (n === 0) return '';\n  let d = `M${xy[0].toFixed(2)} ${xy[1].toFixed(2)}`;\n  for (let i = 1; i < n; i++) d += `L${xy[i * 2].toFixed(2)} ${xy[i * 2 + 1].toFixed(2)}`;\n  return d + 'Z';\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/glow/glow.ts",
          "target": "@components/effects/metal-fx/upstream/engine/glow/glow.ts",
          "type": "registry:component",
          "content": "/**\n * Glow overlay — a luminance-driven halo that tracks the brightest point on\n * the shader's perimeter, plus a tight catch-light.\n *\n * How it works:\n *   1. Samples luminance at N points around the component's perimeter.\n *   2. A state machine tracks which perimeter point is brightest, with dwell\n *      timers and fade-out / fade-in when relocating to a new hotspot.\n *   3. Pre-baked sprites (see `bake.ts`) are drawn onto a small per-instance\n *      canvas at the hotspot, tinted to the shader's colour there, and\n *      clipped to the ring band (or the glyph mask in point mode).\n *\n * The canvas replaces the earlier SVG: four `feGaussianBlur` strokes over a\n * 540×440 filter region re-rasterised on every move — the single biggest\n * idle cost of the effect. Now a move is a few `drawImage` calls inside\n * `clip()` paths, and nothing is drawn at all when the hotspot hasn't moved\n * more than a quarter pixel.\n *\n * Deliberately no `destination-in` / `source-in` compositing on the hot\n * path: WebKit intermittently applies those wrong on accelerated canvases\n * (one frame of the halo unclipped and untinted — a white flash). Tinting is\n * pixel data, clipping is paths; the glyph mask (point mode) multiplies\n * alpha in pixel data too.\n */\nimport type { MetalFxInstance, ShaderRGB } from '../renderer/core';\nimport { sampleShaderLumAt, sampleShaderRGBAt, sampleShaderRGBChromatic } from '../renderer/sampling';\nimport { type Tween, ease, tween, tweenStart, tweenTick } from '../tween';\nimport { hsvToRgb, rgbToHsv } from '../color';\nimport { GLOW } from './config';\nimport { CURSOR_LIGHT } from '../cursor/light';\nimport type { DeformFn } from '../renderer/core';\nimport { type OutlineBuf, createOutlineBuf, roundRectOutline } from '../renderer/outline';\nimport { type Sprite, type Tinted, bakeExtra, bakeHalo, gaussBlur, tintSprite } from './bake';\nimport {\n  type GlowOptions,\n  type PerimSample,\n  type Pt,\n  arcAtPoint,\n  buildPerimTable,\n  rrPerim,\n  sampleAtArc,\n  shapePerim,\n  smoothstep,\n  tangentAngleAtArc,\n} from './geometry';\n\n// ─── Constants ────────────────────────────────────────────────────────────\n\nconst RELOCATE_DELTA = 0.05;\n/** Wander retarget period. Was 120 ticks at the 15 fps shader rate. */\nconst WANDER_RETARGET_MS = 120 * (1000 / 15);\n/** Per-tick rates in GLOW are defined at the 15 fps shader rate; ticks now\n *  come at display rate mid-fade, so they're rescaled by elapsed time. */\nconst RATE_TICK_MS = 1000 / 15;\nconst TINT_HOLD_MS = 2000, TINT_FADE_MS = 400;\nconst LT_SAT_BOOST = 2.625, LT_VAL_MULT = 1.008, LT_MIN_VAL = 0.31;\nconst REF_W = 140, REF_H = 40, REF_R = 20;\n/** Longest a single tick may advance the fade envelope, ms (~2 frames). */\nconst ENV_MAX_STEP_MS = 34;\n/** Redraw thresholds — below these a frame is skipped entirely. */\nconst POS_EPS = 0.25, ANG_EPS = 0.01, OP_EPS = 0.004;\n/** Point mode: the glyph clip keeps a soft skirt around the letters, like the\n *  ring band's 50 % surround — otherwise on small type the halo's blur is\n *  thrown away and only a hairline glint survives inside the strokes. */\nconst GLYPH_SKIRT = 0.5, GLYPH_SKIRT_SIGMA = 3.5;\n\n// ─── Types ────────────────────────────────────────────────────────────────\n\nexport type { GlowOptions } from './geometry';\n\nexport interface GlowHandles {\n  /** Carries the `.metal-fx-glow-svg` class (theme opacity / blend / filter\n   *  from the stylesheet). Inside it `env` carries the appear/disappear\n   *  opacity, and the canvas sits in that, overscanned by `margin`. The\n   *  envelope lives on a plain div, not the canvas: Safari can show stale or\n   *  empty canvas content when the canvas itself is the element whose\n   *  opacity is animated in its own compositing layer. */\n  wrap: HTMLDivElement;\n  env: HTMLDivElement;\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  /** Ring mode clips: everything outside the ring (drawn at 50 %) and the\n   *  band itself (100 %), as evenodd paths in canvas CSS px. Rebuilt only\n   *  when the outline changes (deform). */\n  surroundPath: Path2D | null;\n  bandPath: Path2D | null;\n  /** Point mode: glyph alpha per device pixel of `canvas`, from the mask image. */\n  maskAlpha: Uint8ClampedArray | null;\n  maskReady: boolean;\n  /** CSS-px margin the canvas extends beyond the host box on every side. */\n  margin: number;\n  dpr: number;\n  halo: Sprite;\n  extra: Sprite;\n  haloTint: Tinted;\n  extraTint: Tinted;\n  /** Outline buffers for the band mask; `maskSum` is a cheap checksum of the\n   *  last rendered outline so unchanged composites don't repaint it. */\n  mO: OutlineBuf; mI: OutlineBuf; maskSum: number; maskDeformed: boolean;\n  /** Current deform, mirrored from the instance so the hotspot rides the dent. */\n  deform: DeformFn | null;\n  width: number; height: number; cornerRadius: number; kind: 'pill' | 'circle';\n  /** Master scale used at bake time so per-frame position math\n   *  (GLOW.inset / GLOW.extraOutward) stays consistent with the sprites. */\n  scale: number;\n  perim: PerimSample[];\n  /** True when perim is a point set (custom mask) rather than a ring arc. */\n  pointMode: boolean;\n  currentIdx: number; appearedAt: number; glowOpacity: number;\n  /** Appear/disappear envelope, 0..1. The tween runs on `envClock`, a clock\n   *  that advances by at most `ENV_MAX_STEP_MS` per tick: a dropped frame\n   *  stretches the fade instead of skipping most of it (which read as a pop). */\n  relocTween: Tween | null; relocNextIdx: number; relocMul: number; envClock: number;\n  // wanderFrames accumulates elapsed ms (name kept for the handle shape).\n  /** Cursor mode: the hotspot faces `inst.cursorLight` instead of hunting\n   *  luminance. `cursorArc` is the smoothed hotspot arc position. */\n  cursorMode: boolean; cursorArc: number; cursorTargetArc: number; lastTickMs: number;\n  wanderS: number; wanderTargetS: number; wanderFrames: number;\n  tintFrom: ShaderRGB; tintTarget: ShaderRGB; tintTween: Tween | null; tintHoldUntil: number;\n  /** Last drawn state, for the skip test. */\n  dX: number; dY: number; dAng: number; dEX: number; dEY: number; dHOp: number; dEOp: number;\n  dHaloTint: string; dExtraTint: string; dirty: boolean;\n  /** Last envelope written to `canvas.style.opacity`. The appear/disappear\n   *  fade is a compositor-only opacity change — no canvas redraw. */\n  dEnv: number;\n}\n\nconst _pt: Pt = { x: 0, y: 0 };\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\nexport function injectGlow(container: HTMLElement, opts: GlowOptions): GlowHandles {\n  const { width: W, height: H } = opts;\n  const s = opts.scale ?? 1;\n  const dpr = Math.min(3, typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1);\n\n  const ratio = shapePerim(W, H, opts.cornerRadius, opts.kind) / rrPerim(REF_W, REF_H, REF_R);\n  const haloHL = Math.max(1, GLOW.haloHalfLen * ratio);\n  const extraHL = Math.max(0.6, GLOW.extraHalfLen * ratio);\n  const halo = bakeHalo(haloHL, s, dpr);\n  const extra = bakeExtra(extraHL, s, dpr);\n\n  // Enough room for the halo's full blur skirt plus the outward catch-light.\n  const margin = Math.ceil(Math.max(halo.ay, extra.ay) + GLOW.extraOutward * ratio * s + 2);\n\n  const wrap = document.createElement('div');\n  wrap.className = 'metal-fx-glow-svg';\n  wrap.setAttribute('aria-hidden', 'true');\n  const env = document.createElement('div');\n  env.className = 'metal-fx-glow-env';\n  env.style.cssText = 'position:absolute;inset:0;pointer-events:none;opacity:0';\n  const canvas = document.createElement('canvas');\n  canvas.className = 'metal-fx-glow-canvas';\n  const cw = W + 2 * margin, ch = H + 2 * margin;\n  canvas.width = Math.ceil(cw * dpr); canvas.height = Math.ceil(ch * dpr);\n  canvas.style.cssText = `position:absolute;left:${-margin}px;top:${-margin}px;width:${cw}px;height:${ch}px;pointer-events:none`;\n  env.appendChild(canvas);\n  wrap.appendChild(env);\n  container.appendChild(wrap);\n  const ctx = canvas.getContext('2d', { willReadFrequently: !!opts.maskDataUrl });\n  if (!ctx) throw new Error('metal-fx: glow canvas 2D context unavailable');\n\n  const h: GlowHandles = {\n    wrap, env, canvas, ctx, surroundPath: null, bandPath: null, maskAlpha: null, maskReady: false, margin, dpr,\n    halo, extra,\n    haloTint: { canvas: null, img: null, tint: -1, src: null }, extraTint: { canvas: null, img: null, tint: -1, src: null },\n    mO: createOutlineBuf(), mI: createOutlineBuf(), maskSum: Number.NaN, maskDeformed: false, deform: null,\n    width: W, height: H, cornerRadius: opts.cornerRadius, kind: opts.kind,\n    scale: s,\n    perim: buildPerimTable(opts),\n    pointMode: !!(opts.samplePoints && opts.samplePoints.length > 0),\n    currentIdx: 0, appearedAt: 0, glowOpacity: 0,\n    relocTween: null, relocNextIdx: -1, relocMul: 0, envClock: 0,\n    cursorMode: false, cursorArc: 0, cursorTargetArc: 0, lastTickMs: 0,\n    wanderS: 0, wanderTargetS: 0, wanderFrames: 0,\n    tintFrom: { r: 255, g: 255, b: 255 }, tintTarget: { r: 255, g: 255, b: 255 }, tintTween: null, tintHoldUntil: 0,\n    dX: Number.NaN, dY: Number.NaN, dAng: Number.NaN, dEX: Number.NaN, dEY: Number.NaN, dHOp: Number.NaN, dEOp: Number.NaN,\n    dHaloTint: '', dExtraTint: '', dirty: true,\n    dEnv: -1,\n  };\n\n  if (opts.maskDataUrl) {\n    const img = new Image();\n    img.onload = () => {\n      // Rasterise the glyph mask once at canvas resolution and keep its alpha.\n      const c = document.createElement('canvas');\n      c.width = canvas.width; c.height = canvas.height;\n      const g = c.getContext('2d', { willReadFrequently: true });\n      if (!g) return;\n      g.scale(dpr, dpr);\n      g.drawImage(img, margin, margin, W, H);\n      const d = g.getImageData(0, 0, c.width, c.height).data;\n      const n = c.width * c.height;\n      const glyph = new Float32Array(n);\n      for (let i = 0, j = 3; i < n; i++, j += 4) glyph[i] = d[j] / 255;\n      const skirt = gaussBlur(Float32Array.from(glyph), c.width, c.height, GLYPH_SKIRT_SIGMA * dpr);\n      let peak = 0;\n      for (let i = 0; i < n; i++) if (skirt[i] > peak) peak = skirt[i];\n      const k = peak > 0 ? GLYPH_SKIRT / peak : 0;\n      const a = new Uint8ClampedArray(n);\n      for (let i = 0; i < n; i++) a[i] = Math.round(Math.max(glyph[i], skirt[i] * k) * 255);\n      h.maskAlpha = a; h.maskReady = true; h.dirty = true;\n    };\n    img.src = opts.maskDataUrl;\n  } else {\n    renderMask(h, null);\n  }\n  return h;\n}\n\n// ─── Mask ─────────────────────────────────────────────────────────────────\n\n/**\n * The band clip, as two evenodd paths. Matches the old SVG mask: 50 % outside\n * the ring, 100 % inside the band, 0 in the hole — the halo's blur skirt\n * still spills softly onto the page.\n */\nfunction renderMask(h: GlowHandles, deform: DeformFn | null): void {\n  if (h.pointMode) return;\n  const { margin: m, width: W, height: H, cornerRadius: R } = h;\n  const ringInset = h.kind === 'circle' ? 2 : 1;\n  roundRectOutline(0, 0, W, H, R, deform, h.mO);\n  roundRectOutline(ringInset, ringInset, W - 2 * ringInset, H - 2 * ringInset, Math.max(0, R - ringInset), deform, h.mI);\n  const outer = new Path2D();\n  tracePath(outer, h.mO, m);\n  const band = new Path2D();\n  tracePath(band, h.mO, m);\n  tracePath(band, h.mI, m);\n  const surround = new Path2D();\n  surround.rect(0, 0, W + 2 * m, H + 2 * m);\n  surround.addPath(outer);\n  h.surroundPath = surround;\n  h.bandPath = band;\n  h.maskReady = true;\n}\n\nfunction tracePath(p: Path2D, buf: OutlineBuf, off: number): void {\n  const xy = buf.xy;\n  for (let i = 0; i < buf.n; i++) {\n    const x = xy[i * 2] + off, y = xy[i * 2 + 1] + off;\n    if (i === 0) p.moveTo(x, y); else p.lineTo(x, y);\n  }\n  p.closePath();\n}\n\nfunction outlineSum(deform: DeformFn | null, h: GlowHandles): number {\n  if (!deform) return 0;\n  // Cheap checksum of the deformed outline: every 4th point.\n  roundRectOutline(0, 0, h.width, h.height, h.cornerRadius, deform, h.mO);\n  let sum = 0;\n  const xy = h.mO.xy;\n  for (let i = 0; i < h.mO.n; i += 4) sum += xy[i * 2] * 1.37 + xy[i * 2 + 1];\n  return sum;\n}\n\n/**\n * Keep the glow's band mask (and hotspot) on the deformed outline. Call after\n * every composite while `deform` is set; pass null once to restore the rigid\n * mask. Cheap: a checksum of ~40 points, and a small path fill when changed.\n */\nexport function updateGlowMask(h: GlowHandles, deform: DeformFn | null): void {\n  h.deform = deform;\n  if (h.pointMode) return;\n  if (deform) {\n    const sum = outlineSum(deform, h);\n    if (sum !== h.maskSum) { h.maskSum = sum; renderMask(h, deform); h.maskDeformed = true; h.dirty = true; }\n  } else if (h.maskDeformed) {\n    h.maskSum = Number.NaN;\n    renderMask(h, null);\n    h.maskDeformed = false;\n    h.dirty = true;\n  }\n}\n\n// ─── Per-frame update ─────────────────────────────────────────────────────\n\n/**\n * One glow tick. Returns true while an envelope is animating (relocation\n * fade, tint crossfade, cursor tracking) — the loop then calls again every\n * animation frame so the fade is smooth instead of stepping at 15 fps.\n */\nexport function updateGlow(h: GlowHandles, inst: MetalFxInstance, nowMs: number, strengthMul: number, theme: 'dark' | 'light' = 'dark'): boolean {\n  const { width: W, height: H, cornerRadius: R, perim } = h;\n  if (perim.length === 0) return false;\n\n  const halfWin = 2;\n\n  let maxLum = -1, maxIdx = h.currentIdx, curLum = 0;\n  for (let i = 0; i < perim.length; i++) {\n    const pt = perim[i];\n    const lum = sampleShaderLumAt(inst, pt.x, pt.y, halfWin);\n    if (lum > maxLum) { maxLum = lum; maxIdx = i; }\n    if (i === h.currentIdx) curLum = lum;\n  }\n\n  const dwellActive = h.appearedAt > 0 && nowMs - h.appearedAt < GLOW.minDwellMs;\n  const targetOp = GLOW.baseOp + (GLOW.peakOp - GLOW.baseOp) * smoothstep(GLOW.lumLo, GLOW.lumHi, curLum);\n  const rivalDominates = !dwellActive && maxLum - curLum > RELOCATE_DELTA;\n\n  // Cursor as light source: while the pointer is within reach the hotspot\n  // faces it (nearest outline point) and its brightness follows proximity.\n  // Ring mode only — glyph masks have no continuous outline to slide along.\n  const cl = inst.cursorLight;\n  const cursorOn = CURSOR_LIGHT.enabled && CURSOR_LIGHT.catchLight && !h.pointMode && !!cl && cl.w > 0.02;\n  const perimLen = shapePerim(W, H, R, h.kind);\n  if (cursorOn) h.cursorTargetArc = arcAtPoint(cl!.x, cl!.y, W, H, R, h.kind);\n  const cursorOp = cursorOn ? Math.min(1, GLOW.peakOp * CURSOR_LIGHT.catchGain * cl!.w) : 0;\n  const dtMs = h.lastTickMs > 0 ? Math.min(200, Math.max(0.5, nowMs - h.lastTickMs)) : RATE_TICK_MS;\n  h.lastTickMs = nowMs;\n  h.envClock += Math.min(dtMs, ENV_MAX_STEP_MS);\n  const rate = (perTick: number) => 1 - Math.pow(1 - perTick, dtMs / RATE_TICK_MS);\n\n  // Relocation rules: a hotspot holds for at least `minDwellMs`; moving is\n  // always disappear-in-place (relocFadeOutMs) then appear at the new point\n  // (relocFadeMs). The halo never slides along the ring — except in cursor\n  // mode, where the light source itself is moving.\n  const fadeMs = Math.max(1, GLOW.relocFadeMs);\n  const fadeOutMs = Math.max(1, GLOW.relocFadeOutMs);\n  const CURSOR_ENTER = -2, CURSOR_EXIT = -3;\n  const fadeIn = () => {\n    h.appearedAt = nowMs;\n    h.wanderS = 0; h.wanderTargetS = 0; h.wanderFrames = 0;\n    h.relocTween = tween(0, 1, fadeMs, ease.smoothstep);\n    tweenStart(h.relocTween, h.envClock);\n  };\n  const fadeOut = (next: number) => {\n    h.relocNextIdx = next;\n    h.relocTween = tween(1, 0, fadeOutMs, ease.smoothstep);\n    tweenStart(h.relocTween, h.envClock);\n  };\n  if (h.relocTween?.done && h.relocTween.to === 0) {\n    // Faded out at the old spot: switch, then fade in at the new one.\n    let next = h.relocNextIdx;\n    if (next === CURSOR_ENTER && !cursorOn) next = CURSOR_EXIT;\n    if (next === CURSOR_EXIT) {\n      // Back to the luminance hunt — re-appears below as a first appearance.\n      h.cursorMode = false; h.appearedAt = 0; h.relocTween = null;\n    } else if (next === CURSOR_ENTER) {\n      h.cursorMode = true; h.cursorArc = h.cursorTargetArc; h.glowOpacity = cursorOp;\n      fadeIn();\n    } else {\n      h.currentIdx = next;\n      const np = perim[h.currentIdx];\n      const nl = sampleShaderLumAt(inst, np.x, np.y, halfWin);\n      h.glowOpacity = GLOW.baseOp + (GLOW.peakOp - GLOW.baseOp) * smoothstep(GLOW.lumLo, GLOW.lumHi, nl);\n      fadeIn();\n    }\n  }\n  if (!h.relocTween || h.relocTween.done) {\n    if (h.appearedAt === 0) {\n      // First appearance: face the cursor if it's there, else the brightest point.\n      if (cursorOn) { h.cursorMode = true; h.cursorArc = h.cursorTargetArc; h.glowOpacity = cursorOp; }\n      else { h.cursorMode = false; h.currentIdx = maxIdx; h.glowOpacity = targetOp; }\n      fadeIn();\n    } else if (cursorOn !== h.cursorMode) {\n      fadeOut(cursorOn ? CURSOR_ENTER : CURSOR_EXIT);\n    } else if (!h.cursorMode && rivalDominates) {\n      fadeOut(maxIdx);\n    }\n  }\n  if (h.cursorMode) {\n    // Proximity-weighted, no lag; holds the last value while fading out.\n    if (cursorOn) h.glowOpacity = cursorOp;\n    const follow = Math.max(0.01, Math.min(1, CURSOR_LIGHT.catchFollow));\n    const fa = 1 - Math.pow(1 - follow, dtMs / (1000 / 60));\n    let diff = h.cursorTargetArc - h.cursorArc;\n    diff = ((((diff % perimLen) + perimLen * 1.5) % perimLen) - perimLen / 2);\n    h.cursorArc += diff * fa;\n  } else {\n    // Luminance tracking runs continuously; the envelope handles appear/disappear.\n    h.glowOpacity += (targetOp - h.glowOpacity) * rate(GLOW.fadeRate);\n  }\n  h.glowOpacity = Math.max(0, Math.min(1, h.glowOpacity));\n  h.relocMul = h.relocTween ? tweenTick(h.relocTween, h.envClock) : 1;\n\n  const ratio = shapePerim(W, H, R, h.kind) / rrPerim(REF_W, REF_H, REF_R);\n  const wanderRange = GLOW.wanderRange * ratio;\n  h.wanderFrames += dtMs;\n  if (h.wanderFrames >= WANDER_RETARGET_MS) { h.wanderTargetS = (Math.random() * 2 - 1) * wanderRange; h.wanderFrames = 0; }\n  h.wanderS += (h.wanderTargetS - h.wanderS) * rate(GLOW.wanderLerp);\n\n  let blobX: number, blobY: number, tangent: number, exX: number, exY: number;\n  if (h.pointMode) {\n    // Custom-mask instance: hotspot sits on a sampled glyph point, halo runs\n    // horizontally (reads as a glint across the letterforms), wander slides\n    // it along x only.\n    const p = perim[h.currentIdx];\n    blobX = p.x + h.wanderS; blobY = p.y; tangent = 0;\n    exX = blobX; exY = blobY;\n  } else {\n    const blobArc = h.cursorMode ? h.cursorArc : perim[h.currentIdx].arc + h.wanderS;\n    // GLOW.inset / GLOW.extraOutward are absolute units; multiply by the\n    // master scale so the catch-light sits at the right perpendicular\n    // distance when the host element is rendered at non-1× layout.\n    const insetS = GLOW.inset * h.scale;\n    sampleAtArc(blobArc, W, H, R, insetS, 0, h.kind, _pt);\n    blobX = _pt.x; blobY = _pt.y;\n    tangent = tangentAngleAtArc(blobArc, W, H, R, insetS, h.kind);\n    const extraOut = GLOW.extraOutward * ratio * h.scale;\n    sampleAtArc(blobArc, W, H, R, insetS, extraOut, h.kind, _pt);\n    exX = _pt.x; exY = _pt.y;\n  }\n  if (h.deform) {\n    h.deform(blobX, blobY, _pt); blobX = _pt.x; blobY = _pt.y;\n    h.deform(exX, exY, _pt); exX = _pt.x; exY = _pt.y;\n  }\n\n  const light = theme === 'light';\n  const samp = light\n    ? sampleShaderRGBChromatic(inst, blobX, blobY, halfWin)\n    : sampleShaderRGBAt(inst, blobX, blobY, halfWin);\n\n  if (!h.tintTween) {\n    h.tintFrom = { ...samp }; h.tintTarget = { ...samp };\n    h.tintTween = tween(0, 1, TINT_FADE_MS);\n    tweenStart(h.tintTween, nowMs);\n    h.tintHoldUntil = light ? 0 : nowMs + TINT_HOLD_MS;\n  } else if (h.tintTween.done) {\n    if (light) {\n      h.tintFrom = {\n        r: h.tintFrom.r + (h.tintTarget.r - h.tintFrom.r) * h.tintTween.val,\n        g: h.tintFrom.g + (h.tintTarget.g - h.tintFrom.g) * h.tintTween.val,\n        b: h.tintFrom.b + (h.tintTarget.b - h.tintFrom.b) * h.tintTween.val,\n      };\n      h.tintTarget = { ...samp };\n      h.tintTween = tween(0, 1, TINT_FADE_MS);\n      tweenStart(h.tintTween, nowMs);\n    } else if (nowMs >= h.tintHoldUntil) {\n      h.tintFrom = { ...h.tintTarget };\n      h.tintTarget = { ...samp };\n      h.tintTween = tween(0, 1, TINT_FADE_MS);\n      tweenStart(h.tintTween, nowMs);\n      h.tintHoldUntil = nowMs + TINT_HOLD_MS;\n    }\n  }\n  tweenTick(h.tintTween!, nowMs);\n  const ft = h.tintTween!.val;\n\n  let tR: number, tG: number, tB: number;\n  if (light) {\n    tR = Math.round(h.tintFrom.r + (h.tintTarget.r - h.tintFrom.r) * ft);\n    tG = Math.round(h.tintFrom.g + (h.tintTarget.g - h.tintFrom.g) * ft);\n    tB = Math.round(h.tintFrom.b + (h.tintTarget.b - h.tintFrom.b) * ft);\n  } else {\n    const hR = h.tintFrom.r + (h.tintTarget.r - h.tintFrom.r) * ft;\n    const hG = h.tintFrom.g + (h.tintTarget.g - h.tintFrom.g) * ft;\n    const hB = h.tintFrom.b + (h.tintTarget.b - h.tintFrom.b) * ft;\n    const peak = Math.max(hR, hG, hB) || 1;\n    tR = Math.round(255 * (hR / peak)); tG = Math.round(255 * (hG / peak)); tB = Math.round(255 * (hB / peak));\n  }\n  const haloTint = `rgb(${tR},${tG},${tB})`;\n  let extraTint = '#ffffff';\n  if (light) {\n    const hsv = rgbToHsv(tR, tG, tB);\n    const [er, eg, eb] = hsvToRgb(hsv[0], Math.min(1, hsv[1] * LT_SAT_BOOST), Math.max(LT_MIN_VAL, hsv[2] * LT_VAL_MULT));\n    extraTint = `rgb(${er},${eg},${eb})`;\n  }\n\n  const m = Math.max(0, Math.min(1, strengthMul)) * (h.pointMode ? GLOW.pointGain : 1);\n  const haloOp = Math.min(1, h.glowOpacity * GLOW.haloOpMul * m);\n  const extraOp = Math.min(1, h.glowOpacity * GLOW.extraIntensity * m);\n\n  // The appear/disappear envelope is element opacity: a compositor-only\n  // change, so it can run every animation frame for free. Only movement,\n  // tint and luminance changes redraw the canvas.\n  if (Math.abs(h.relocMul - h.dEnv) > 0.002) {\n    const arrived = h.relocMul >= 0.998 && h.dEnv < 0.998;\n    h.dEnv = h.relocMul;\n    h.env.style.opacity = h.relocMul.toFixed(3);\n    // Fresh content once fully visible — a nudge for engines that only\n    // re-upload a canvas when something in it changes.\n    if (arrived) h.dirty = true;\n  }\n\n  const animating = !!(h.relocTween && !h.relocTween.done) || h.cursorMode;\n\n  // Skip the draw when nothing visible changed.\n  const moved = !(Math.abs(blobX - h.dX) < POS_EPS && Math.abs(blobY - h.dY) < POS_EPS &&\n                  Math.abs(tangent - h.dAng) < ANG_EPS &&\n                  Math.abs(exX - h.dEX) < POS_EPS && Math.abs(exY - h.dEY) < POS_EPS);\n  const faded = !(Math.abs(haloOp - h.dHOp) < OP_EPS && Math.abs(extraOp - h.dEOp) < OP_EPS);\n  const tinted = haloTint !== h.dHaloTint || extraTint !== h.dExtraTint;\n  if (!(h.dirty || moved || faded || tinted)) return animating;\n  h.dX = blobX; h.dY = blobY; h.dAng = tangent; h.dEX = exX; h.dEY = exY;\n  h.dHOp = haloOp; h.dEOp = extraOp; h.dHaloTint = haloTint; h.dExtraTint = extraTint;\n  h.dirty = false;\n  draw(h, blobX, blobY, tangent, exX, exY, haloOp, extraOp, haloTint, extraTint);\n  return animating;\n}\n\n// ─── Drawing ──────────────────────────────────────────────────────────────\n\nfunction draw(\n  h: GlowHandles,\n  bx: number, by: number, ang: number, ex: number, ey: number,\n  haloOp: number, extraOp: number, haloTint: string, extraTint: string\n): void {\n  const { ctx: g, canvas: c, dpr, margin: m } = h;\n  g.setTransform(1, 0, 0, 1, 0, 0);\n  g.globalCompositeOperation = 'source-over';\n  g.globalAlpha = 1;\n  g.clearRect(0, 0, c.width, c.height);\n  if ((haloOp <= 0.002 && extraOp <= 0.002) || !h.maskReady) return;\n\n  const haloImg = haloOp > 0.002 ? tintSprite(h.halo, ...parseRgb(haloTint), h.haloTint) : null;\n  const extraImg = extraOp > 0.002\n    ? (extraTint === '#ffffff' ? h.extra.canvas : tintSprite(h.extra, ...parseRgb(extraTint), h.extraTint))\n    : null;\n\n  const sprites = (mul: number) => {\n    if (haloImg) {\n      g.save();\n      g.translate(bx + m, by + m);\n      g.rotate(ang);\n      g.globalAlpha = haloOp * mul;\n      g.drawImage(haloImg, -h.halo.ax, -h.halo.ay, h.halo.w, h.halo.h);\n      g.restore();\n    }\n    if (extraImg) {\n      g.save();\n      g.translate(ex + m, ey + m);\n      g.rotate(ang);\n      g.globalAlpha = extraOp * mul;\n      g.drawImage(extraImg, -h.extra.ax, -h.extra.ay, h.extra.w, h.extra.h);\n      g.restore();\n    }\n  };\n\n  if (!h.pointMode && h.surroundPath && h.bandPath) {\n    // Two disjoint clip regions: outside the ring at half strength, the band\n    // at full. Plain source-over inside each, so nothing for WebKit to get\n    // wrong.\n    g.save(); g.scale(dpr, dpr); g.clip(h.surroundPath, 'evenodd'); sprites(0.5); g.restore();\n    g.save(); g.scale(dpr, dpr); g.clip(h.bandPath, 'evenodd'); sprites(1); g.restore();\n    return;\n  }\n\n  // Point mode: draw, then multiply alpha by the glyph mask in pixel data.\n  g.save(); g.scale(dpr, dpr); sprites(1); g.restore();\n  const a = h.maskAlpha;\n  if (!a) return;\n  const img = g.getImageData(0, 0, c.width, c.height);\n  const d = img.data;\n  for (let i = 0, j = 3; i < a.length; i++, j += 4) {\n    const ma = a[i];\n    if (ma === 255) continue;\n    if (ma === 0) { d[j] = 0; continue; }\n    d[j] = (d[j] * ma + 127) / 255;\n  }\n  g.putImageData(img, 0, 0);\n}\n\nconst _rgb: [number, number, number] = [255, 255, 255];\nfunction parseRgb(css: string): [number, number, number] {\n  if (css[0] === '#') {\n    _rgb[0] = parseInt(css.slice(1, 3), 16); _rgb[1] = parseInt(css.slice(3, 5), 16); _rgb[2] = parseInt(css.slice(5, 7), 16);\n    return _rgb;\n  }\n  // \"rgb(r,g,b)\"\n  let i = 4, n = 0, k = 0;\n  while (i < css.length && k < 3) {\n    const ch = css.charCodeAt(i++);\n    if (ch >= 48 && ch <= 57) n = n * 10 + (ch - 48);\n    else if (ch === 44 || ch === 41) { _rgb[k++] = n; n = 0; }\n  }\n  return _rgb;\n}\n\n/**\n * Carry the visible state of a glow across a rebuild (a real resize), so the\n * halo keeps its hotspot, brightness and fade instead of restarting from\n * invisible. Only state — never geometry, sprites or masks.\n */\nexport function carryGlowState(prev: GlowHandles, next: GlowHandles): void {\n  if (prev.pointMode !== next.pointMode) return;\n  next.currentIdx = Math.min(prev.currentIdx, Math.max(0, next.perim.length - 1));\n  next.appearedAt = prev.appearedAt;\n  next.glowOpacity = prev.glowOpacity;\n  next.relocTween = prev.relocTween;\n  next.relocNextIdx = prev.relocNextIdx;\n  next.relocMul = prev.relocMul;\n  next.envClock = prev.envClock;\n  next.cursorMode = prev.cursorMode;\n  next.cursorArc = prev.cursorArc;\n  next.cursorTargetArc = prev.cursorTargetArc;\n  next.lastTickMs = prev.lastTickMs;\n  next.wanderS = prev.wanderS; next.wanderTargetS = prev.wanderTargetS; next.wanderFrames = prev.wanderFrames;\n  next.tintFrom = prev.tintFrom; next.tintTarget = prev.tintTarget;\n  next.tintTween = prev.tintTween; next.tintHoldUntil = prev.tintHoldUntil;\n  next.dEnv = prev.relocMul;\n  next.env.style.opacity = prev.relocMul.toFixed(3);\n}\n\nexport function resizeGlow(handles: GlowHandles, container: HTMLElement, opts: GlowOptions): GlowHandles {\n  for (const el of Array.from(container.querySelectorAll('.metal-fx-glow-svg'))) {\n    if (el.parentNode === container) container.removeChild(el);\n  }\n  void handles;\n  return injectGlow(container, opts);\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/tween.ts",
          "target": "@components/effects/metal-fx/upstream/engine/tween.ts",
          "type": "registry:component",
          "content": "export type EaseFn = (t: number) => number;\n\nexport const ease = {\n  linear: (t: number) => t,\n  smoothstep: (t: number) => t * t * (3 - 2 * t),\n} as const;\n\nexport interface Tween {\n  from: number;\n  to: number;\n  dur: number;\n  ease: EaseFn;\n  startMs: number;\n  val: number;\n  done: boolean;\n}\n\nexport function tween(from: number, to: number, dur: number, e: EaseFn = ease.linear): Tween {\n  return { from, to, dur, ease: e, startMs: -1, val: from, done: false };\n}\n\nexport function tweenStart(tw: Tween, nowMs: number): void {\n  tw.startMs = nowMs;\n  tw.val = tw.from;\n  tw.done = false;\n}\n\nexport function tweenTick(tw: Tween, nowMs: number): number {\n  if (tw.done || tw.startMs < 0) return tw.val;\n  const t = Math.min(1, (nowMs - tw.startMs) / tw.dur);\n  tw.val = tw.from + (tw.to - tw.from) * tw.ease(t);\n  if (t >= 1) tw.done = true;\n  return tw.val;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/glow/config.ts",
          "target": "@components/effects/metal-fx/upstream/engine/glow/config.ts",
          "type": "registry:component",
          "content": "/**\n * Live-tunable glow parameters.\n *\n * Every number the halo + catch-light overlay used to hard-code lives here as\n * a mutable singleton so a tuning surface can drive it at runtime. Two classes:\n *\n *   • runtime — read every frame inside `updateGlow`. Changing one takes\n *     effect on the next frame with no DOM work.\n *   • markup — baked into the SVG (`buildSvgMarkup`) at inject time: stroke\n *     widths, blur radii, per-layer opacities, blob lengths. Changing one\n *     requires the SVG to be rebuilt, which `setGlowConfig` signals through\n *     `subscribeGlowConfig` so MetalFx can re-inject.\n *\n * `GLOW_DEFAULTS` are the values that shipped before this file existed, so\n * `resetGlowConfig()` is an exact restore.\n */\n\nexport interface GlowConfig {\n  // ── runtime ───────────────────────────────────────────────────────────\n  /** Overall halo group opacity multiplier. */\n  haloOpMul: number;\n  /** Catch-light group intensity multiplier (clamped to 1 after multiply). */\n  extraIntensity: number;\n  /** Glow opacity at a fully-lit perimeter point. */\n  peakOp: number;\n  /** Glow opacity at a dark perimeter point. */\n  baseOp: number;\n  /** Perpendicular inset of the halo from the ring, SVG units at 1×. */\n  inset: number;\n  /** Extra outward offset for the catch-light, SVG units at 1×. */\n  extraOutward: number;\n  /** Random wander amplitude along the perimeter, at the 140×40 reference. */\n  wanderRange: number;\n  /** Per-frame lerp toward the wander target. */\n  wanderLerp: number;\n  /** Per-frame lerp of opacity toward its luminance-driven target. */\n  fadeRate: number;\n  /** Luminance below which the glow sits at `baseOp`. */\n  lumLo: number;\n  /** Luminance above which the glow reaches `peakOp`. */\n  lumHi: number;\n  /** Minimum time at a hotspot before a brighter rival can steal it. */\n  minDwellMs: number;\n  /** Appear duration, ms. A relocation is a full fade-out at the old spot\n   *  then a full fade-in at the new one — the glow never slides. */\n  relocFadeMs: number;\n  /** Disappear duration, ms. Slower than the appear so a hotspot lingers. */\n  relocFadeOutMs: number;\n  /** Point-mode (masked text/glyph) intensity multiplier. The mask discards\n   *  most of the halo's blur, so what survives inside the strokes needs a\n   *  boost to read at all. */\n  pointGain: number;\n\n  // ── markup (re-inject on change) ──────────────────────────────────────\n  /** Half-length of the halo stroke path, at the reference pill. */\n  haloHalfLen: number;\n  /** Half-length of the catch-light stroke path, at the reference pill. */\n  extraHalfLen: number;\n  haloStrokeXl: number;\n  haloStrokeLg: number;\n  haloStrokeMd: number;\n  haloStrokeSm: number;\n  haloBlurXl: number;\n  haloBlurLg: number;\n  haloBlurMd: number;\n  haloBlurSm: number;\n  haloOpXl: number;\n  haloOpLg: number;\n  haloOpMd: number;\n  haloOpSm: number;\n  extraStrokeOuter: number;\n  extraStrokeCore: number;\n  extraBlurOuter: number;\n  extraBlurCore: number;\n  /** Radius of the radial mask that fades the catch-light's ends. */\n  extraFadeR: number;\n  extraOpOuter: number;\n}\n\nexport const GLOW_MARKUP_KEYS: ReadonlySet<keyof GlowConfig> = new Set<keyof GlowConfig>([\n  'haloHalfLen', 'extraHalfLen',\n  'haloStrokeXl', 'haloStrokeLg', 'haloStrokeMd', 'haloStrokeSm',\n  'haloBlurXl', 'haloBlurLg', 'haloBlurMd', 'haloBlurSm',\n  'haloOpXl', 'haloOpLg', 'haloOpMd', 'haloOpSm',\n  'extraStrokeOuter', 'extraStrokeCore', 'extraBlurOuter', 'extraBlurCore',\n  'extraFadeR', 'extraOpOuter',\n]);\n\n// The `/ 3` values were `EXTRA_SCALE = 1 / 3` applied to the original\n// constants (4.0, 2.0, 2.0, 1.35, 13.0, 9.13952). Stored pre-multiplied so a\n// slider moves the number the SVG actually receives.\nexport const GLOW_DEFAULTS: Readonly<GlowConfig> = Object.freeze({\n  haloOpMul: 2.0,\n  extraIntensity: 3.51,\n  peakOp: 0.85,\n  baseOp: 0.34,\n  inset: 1.5,\n  extraOutward: 1.0,\n  wanderRange: 15,\n  wanderLerp: 0.0075,\n  fadeRate: 0.00875,\n  lumLo: 0.08,\n  lumHi: 0.32,\n  minDwellMs: 1500,\n  relocFadeMs: 300,\n  relocFadeOutMs: 450,\n  pointGain: 2.5,\n\n  haloHalfLen: 7.8,\n  extraHalfLen: 9.13952 / 3,\n  haloStrokeXl: 26.4,\n  haloStrokeLg: 15.6,\n  haloStrokeMd: 7.2,\n  haloStrokeSm: 3.0,\n  haloBlurXl: 8.4,\n  haloBlurLg: 4.8,\n  haloBlurMd: 2.1,\n  haloBlurSm: 0.9,\n  haloOpXl: 0.385,\n  haloOpLg: 0.595,\n  haloOpMd: 0.70,\n  haloOpSm: 0.70,\n  extraStrokeOuter: 4.0 / 3,\n  extraStrokeCore: 2.0 / 3,\n  extraBlurOuter: 2.0 / 3,\n  extraBlurCore: 1.35 / 3,\n  extraFadeR: 13.0 / 3,\n  extraOpOuter: 0.85,\n});\n\n/** Live values. Read directly by the glow engine; write via `setGlowConfig`. */\nexport const GLOW: GlowConfig = { ...GLOW_DEFAULTS };\n\ntype Listener = (markupChanged: boolean) => void;\nconst listeners = new Set<Listener>();\n\n/**\n * Merge a partial config. Notifies subscribers, flagging whether any markup\n * key changed so they can decide between \"next frame picks it up\" and\n * \"rebuild the SVG\".\n */\nexport function setGlowConfig(patch: Partial<GlowConfig>): void {\n  let markupChanged = false;\n  for (const k of Object.keys(patch) as Array<keyof GlowConfig>) {\n    const v = patch[k];\n    if (v === undefined || GLOW[k] === v) continue;\n    GLOW[k] = v;\n    if (GLOW_MARKUP_KEYS.has(k)) markupChanged = true;\n  }\n  for (const fn of listeners) fn(markupChanged);\n}\n\nexport function resetGlowConfig(): void {\n  setGlowConfig({ ...GLOW_DEFAULTS });\n}\n\nexport function subscribeGlowConfig(fn: Listener): () => void {\n  listeners.add(fn);\n  return () => { listeners.delete(fn); };\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/cursor/light.ts",
          "target": "@components/effects/metal-fx/upstream/engine/cursor/light.ts",
          "type": "registry:component",
          "content": "/**\n * Cursor light — the pointer and the ring lighting each other.\n *\n * Three effects, all keyed off the pointer's distance to the nearest ring\n * (either side of the edge, within `reach`):\n *\n *   • cursor — the ring lights the cursor. A page cannot paint on the OS\n *     cursor, so while the pointer is near a ring and the element under it\n *     shows the plain arrow, that element gets `cursor: none` and a sprite\n *     of the pointer is drawn at the same spot (same trick as cursorjoy).\n *     The sprite must be the platform's real pointer or the swap shows —\n *     consumers supply it via `setCursorSprite`; without one this effect is\n *     off. Over buttons/text (hand, I-beam) the OS cursor stays.\n *\n *     Lighting treats the ring as the light source and the pointer as a\n *     small glossy object: a diffuse rim on the face that looks at the ring,\n *     coloured by the ring there and falling off with the inverse square of\n *     the distance, plus a specular term — the ring's own canvas mirrored\n *     across that face and compressed in depth, like on a convex surface.\n *   • spill — a soft glint on the page under the pointer, tinted with the\n *     ring's colour at the outline point nearest the cursor.\n *   • catch — the ring's catch-light faces the pointer (see `updateGlow`'s\n *     cursor mode), so the pointer acts as a light source.\n *\n * Runs only on `(pointer: fine)` devices. Tracking starts when the first\n * instance attaches and stops with the last; the per-frame loop runs only\n * while the pointer is within reach of some ring (plus the fade-out).\n *\n * Fail-safes for the cursor swap (the only part that can hurt someone):\n *   • off under `prefers-reduced-motion`, `forced-colors`, coarse/no-hover\n *     pointers, and pen/touch input;\n *   • browser zoom is compensated: the sprite is scaled by the display's\n *     backing scale over the current DPR, so it keeps the OS cursor's\n *     device-pixel size while the page zooms around it; off only while\n *     pinch-zoomed (the visual viewport, which the fixed sprite can't track);\n *   • the OS cursor is hidden by an inline style on one element only, never\n *     a stylesheet, restored on every leave/blur/hide/keydown, when that\n *     element is detached, and on any exception (which also disables the\n *     effect for the session);\n *   • a frame-time watchdog disables it if it ever becomes expensive;\n *   • it never runs where the pointer is anything but the plain arrow, so\n *     hand, I-beam, resize and custom cursors are untouched.\n * Not detectable: Accessibility › Pointer size/colour on macOS. A user with\n * an enlarged pointer sees it swap to the stock one — ship the sprite only\n * where that trade-off is acceptable, and give them a way to turn it off.\n */\nimport { SHARED, type MetalFxInstance } from '../renderer/core';\nimport { sampleShaderLumAt, sampleShaderPeakAt, sampleShaderRGBAt } from '../renderer/sampling';\nimport { tickInstanceGlow } from '../renderer/loop';\nimport { hsvToRgb, rgbToHsv } from '../color';\n\nexport interface CursorLightConfig {\n  enabled: boolean;\n  /** Distance from the ring's edge, either side, where the pointer is felt (CSS px). */\n  reach: number;\n  /** Envelope for the whole effect on enter/leave, ms (~95% settled). */\n  fadeMs: number;\n\n  /** Pointer sprite lit by the ring (needs `setCursorSprite`). */\n  cursor: boolean;\n  /** How far from the ring edge the pointer still gets lit, px. Beyond it\n   *  nothing is drawn on the pointer; the last third ramps out. Independent\n   *  of `reach`, which gates spill / catch-light. */\n  cursorDistance: number;\n  /** Specular: intensity of the mirrored ring (0..4, >1 stacks passes). */\n  cursorStrength: number;\n  /** Diffuse: intensity of the lit rim on the face toward the ring (0..2). */\n  cursorDiffuse: number;\n  /** Distance from the ring edge at which light has fallen to half, px.\n   *  Inverse-square: I = 1 / (1 + (d / falloff)²). */\n  cursorFalloff: number;\n  /** Depth compression of the mirrored ring (0.1..1). Lower = the ring stays\n   *  on the pointer's edge as it gets farther, like a convex surface. */\n  cursorDepth: number;\n  /** Mirror plane offset from the pointer's silhouette edge, px (+ = outside). */\n  cursorEdge: number;\n  /** How far the light spreads across the body from the facing edge, px.\n   *  ~6 lights one side of the ~8 px wide arrow; 20+ covers all of it. */\n  cursorReach: number;\n  /** Blur on the mirrored ring, px. */\n  cursorBlur: number;\n  /** Magnification of the mirrored ring (1..5). The ring is ~2 px thick;\n   *  without this it compresses into a hairline nobody can see. */\n  cursorZoom: number;\n\n  /** Glint on the page under the pointer. */\n  spill: boolean;\n  /** Glint radius, CSS px. */\n  spillRadius: number;\n  /** Peak opacity with the pointer on the ring (0..1). */\n  spillStrength: number;\n  /** 0 = centred on the pointer, 1 = centred on the nearest ring point. */\n  spillOffset: number;\n  /** How much the ring's brightness at that point modulates the glint (0..1). */\n  spillLumGain: number;\n  /** Saturation multiplier on the sampled tint. */\n  spillSaturation: number;\n  /** Strength multiplier while the pointer is inside the ring (over content). */\n  spillInside: number;\n  /** Extra blur on the glint element, CSS px. 0 = gradient only. */\n  spillBlur: number;\n\n  /** Ring catch-light follows the pointer. */\n  catchLight: boolean;\n  /** Hotspot tracking, per-60 Hz-frame lerp (0..1). Lower = lags more. */\n  catchFollow: number;\n  /** Opacity multiplier on the cursor-driven catch-light. */\n  catchGain: number;\n}\n\nexport const CURSOR_LIGHT_DEFAULTS: Readonly<CursorLightConfig> = Object.freeze({\n  enabled: true,\n  reach: 56,\n  fadeMs: 200,\n  cursor: true,\n  cursorDistance: 186,\n  cursorStrength: 3.35,\n  cursorDiffuse: 1.4,\n  cursorFalloff: 37,\n  cursorDepth: 0.4,\n  cursorEdge: 0,\n  cursorReach: 11.5,\n  cursorBlur: 0.5,\n  cursorZoom: 3,\n  spill: false,\n  spillRadius: 48,\n  spillStrength: 0.55,\n  spillOffset: 0.35,\n  spillLumGain: 0.7,\n  spillSaturation: 1.3,\n  spillInside: 0.5,\n  spillBlur: 0,\n  catchLight: false,\n  catchFollow: 0.25,\n  catchGain: 1,\n});\n\n/** Live values. Read every frame; write via `setCursorLightConfig`. */\nexport const CURSOR_LIGHT: CursorLightConfig = { ...CURSOR_LIGHT_DEFAULTS };\n\nexport function setCursorLightConfig(patch: Partial<CursorLightConfig>): void {\n  Object.assign(CURSOR_LIGHT, patch);\n  if (!CURSOR_LIGHT.spill && spillEl) hideSpill();\n  if (!CURSOR_LIGHT.cursor) hideCursor();\n  kick();\n}\n\nexport function resetCursorLightConfig(): void {\n  setCursorLightConfig({ ...CURSOR_LIGHT_DEFAULTS });\n}\n\n/** A raster of the platform's real pointer. `width`/`height` in CSS px,\n *  `hotX`/`hotY` the click point. `centerX`/`centerY` optionally override\n *  the body centre (default: alpha centroid). */\nexport interface CursorSprite {\n  src: string;\n  width: number;\n  height: number;\n  hotX: number;\n  hotY: number;\n  centerX?: number;\n  centerY?: number;\n}\n\nlet sprite: CursorSprite | null = null;\nlet spriteImg: HTMLImageElement | null = null;\n/** The display's backing scale (1 or 2 on a Mac). The OS cursor is drawn at\n *  this scale regardless of page zoom; `devicePixelRatio` is backing scale\n *  × browser zoom, so the sprite is drawn at `spriteDpr / devicePixelRatio`\n *  of its CSS size to stay the cursor's true size. A page loaded already\n *  zoomed can't tell the two apart; ≥ 1.5 reads as a Retina display. */\nlet spriteDpr = 0;\n\n/** CSS scale that keeps the sprite at the OS cursor's device-pixel size. */\nfunction zoomScale(): number {\n  const dpr = window.devicePixelRatio || 1;\n  return spriteDpr > 0 ? spriteDpr / dpr : 1;\n}\n\n/** Put the sprite's hotspot on the pointer, at the zoom-compensated size. */\nfunction placeCursor(x: number, y: number): void {\n  if (!curEl || !sprite) return;\n  const k = zoomScale();\n  const tx = (x - sprite.hotX * k).toFixed(2), ty = (y - sprite.hotY * k).toFixed(2);\n  curEl.style.transform = k === 1 ? `translate3d(${tx}px,${ty}px,0)` : `translate3d(${tx}px,${ty}px,0) scale(${k.toFixed(4)})`;\n}\n/** Off-switch flipped by the fail-safes. An exception disables for the\n *  session; the frame-time watchdog only pauses for a while (`disabledUntil`). */\nlet cursorDisabled = false;\nlet disabledUntil = 0;\nlet slowFrames = 0;\n/** Opaque body pixels (sprite-local CSS px, centred on `bodyC`), the alpha\n *  centroid, and a hard mask of the body — built once per sprite. The\n *  silhouette extent in any direction comes from `bodyPts` per frame. */\nlet bodyPts: Float32Array | null = null;\nconst bodyC = { x: 0, y: 0 };\n/** Hard body alpha at the sprite canvas's device resolution, cached by dpr. */\nlet bodyAlpha: Uint8ClampedArray | null = null;\nlet bodyAlphaDpr = 0;\n\nfunction bodyAlphaFor(img: HTMLImageElement, sp: CursorSprite, dpr: number, w: number, h: number): Uint8ClampedArray | null {\n  if (bodyAlpha && bodyAlphaDpr === dpr && bodyAlpha.length === w * h) return bodyAlpha;\n  const c = document.createElement('canvas');\n  c.width = w; c.height = h;\n  const g = c.getContext('2d', { willReadFrequently: true });\n  if (!g) return null;\n  g.scale(dpr, dpr);\n  g.drawImage(img, 0, 0, sp.width, sp.height);\n  const d = g.getImageData(0, 0, w, h).data;\n  const a = new Uint8ClampedArray(w * h);\n  for (let i = 0, j = 3; i < a.length; i++, j += 4) a[i] = d[j] >= 128 ? 255 : 0;\n  bodyAlpha = a; bodyAlphaDpr = dpr;\n  return a;\n}\n\n/**\n * Multiply the canvas alpha by a per-pixel factor, in pixel data. Used in\n * place of `destination-in`, which WebKit intermittently misapplies on\n * accelerated canvases (a frame of the unclipped image — a white flash).\n */\nfunction alphaPass(g: CanvasRenderingContext2D, w: number, h: number, factor: (x: number, y: number, i: number) => number): void {\n  const img = g.getImageData(0, 0, w, h);\n  const px = img.data;\n  for (let y = 0, i = 0, j = 3; y < h; y++) {\n    for (let x = 0; x < w; x++, i++, j += 4) {\n      const a = px[j];\n      if (a === 0) continue;\n      const f = factor(x, y, i);\n      px[j] = f >= 1 ? a : f <= 0 ? 0 : a * f;\n    }\n  }\n  g.putImageData(img, 0, 0);\n}\n\nfunction analyseSprite(img: HTMLImageElement, sp: CursorSprite): void {\n  const S = 2;\n  const c = document.createElement('canvas');\n  c.width = Math.ceil(sp.width * S); c.height = Math.ceil(sp.height * S);\n  const g = c.getContext('2d', { willReadFrequently: true });\n  if (!g) return;\n  g.drawImage(img, 0, 0, c.width, c.height);\n  const d = g.getImageData(0, 0, c.width, c.height).data;\n  const pts: number[] = [];\n  let sx = 0, sy = 0, n = 0;\n  for (let y = 0; y < c.height; y++) {\n    for (let x = 0; x < c.width; x++) {\n      const a = d[(y * c.width + x) * 4 + 3];\n      if (a < 128) continue;\n      const px = (x + 0.5) / S, py = (y + 0.5) / S;\n      pts.push(px, py); sx += px; sy += py; n++;\n    }\n  }\n  if (n === 0) return;\n  bodyC.x = sp.centerX ?? sx / n;\n  bodyC.y = sp.centerY ?? sy / n;\n  const arr = new Float32Array(pts.length);\n  for (let i = 0; i < pts.length; i += 2) { arr[i] = pts[i] - bodyC.x; arr[i + 1] = pts[i + 1] - bodyC.y; }\n  bodyPts = arr;\n}\n\n/** Farthest the body extends from its centre along direction (ux, uy). */\nfunction bodyExtent(ux: number, uy: number): number {\n  if (!bodyPts) return 0;\n  let best = -Infinity;\n  for (let i = 0; i < bodyPts.length; i += 2) {\n    const dot = bodyPts[i] * ux + bodyPts[i + 1] * uy;\n    if (dot > best) best = dot;\n  }\n  return best === -Infinity ? 0 : best;\n}\n\n/** Supply the pointer raster (or null to turn the cursor effect off). Must\n *  match the OS pointer pixel-for-pixel, or the swap is visible. */\nexport function setCursorSprite(next: CursorSprite | null): void {\n  sprite = next;\n  spriteImg = null; bodyPts = null; bodyAlpha = null;\n  cursorDisabled = false; disabledUntil = 0; slowFrames = 0;\n  const dprNow = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n  spriteDpr = dprNow >= 1.5 ? 2 : 1;\n  hideCursor();\n  if (!next || typeof Image === 'undefined') return;\n  const img = new Image();\n  img.decoding = 'async';\n  img.onload = () => { if (sprite === next) { analyseSprite(img, next); spriteImg = img; kick(); } };\n  img.src = next.src;\n}\n\n// ─── Tracking ─────────────────────────────────────────────────────────────\n\nlet attached = 0;\nlet tracking = false;\nlet raf = 0;\nlet last = 0;\nlet px = Number.NaN, py = Number.NaN; // live pointer, NaN when gone\nlet lpx = 0, lpy = 0;                 // last known, for the fade-out\nlet uS = 0;                           // smoothed proximity weight (reach)\nlet uCS = 0;                          // smoothed proximity weight (cursorReach)\nlet near: MetalFxInstance | null = null;\nconst _near = { d: 0, nx: 0, ny: 0, k: 1, left: 0, top: 0 };\nconst _pt = { x: 0, y: 0 };\nconst _sc = { r: 255, g: 255, b: 255 }; // smoothed spill tint\n\nlet spillEl: HTMLDivElement | null = null;\nlet spillBg = '';\nlet spillSize = -1;\nlet spillBlur = -1;\nlet spillShown = false;\n\n/** Reference-counted: MetalFx calls attach on mount, detach on unmount. */\nexport function attachCursorLight(): void {\n  attached++;\n  ensureTracking();\n}\n\nexport function detachCursorLight(): void {\n  attached = Math.max(0, attached - 1);\n  if (attached === 0) stopTracking();\n}\n\nconst mq = (q: string): boolean => typeof window.matchMedia === 'function' && window.matchMedia(q).matches;\n\n/** Whether replacing the OS cursor is acceptable right now. Re-checked\n *  every frame; all of these can change while the page is open. */\nfunction cursorSwapAllowed(): boolean {\n  if (cursorDisabled || performance.now() < disabledUntil || !sprite || !spriteImg) return false;\n  if (mq('(prefers-reduced-motion: reduce)') || mq('(forced-colors: active)')) return false;\n  if (!mq('(pointer: fine)') || !mq('(hover: hover)')) return false;\n  const vv = window.visualViewport;\n  if (vv && Math.abs(vv.scale - 1) > 0.001) return false;\n  return true;\n}\n\nfunction ensureTracking(): void {\n  if (tracking || attached === 0 || typeof document === 'undefined') return;\n  if (!mq('(pointer: fine)')) return;\n  tracking = true;\n  document.addEventListener('pointermove', onMove, { passive: true });\n  document.addEventListener('pointerleave', onLeave);\n  document.addEventListener('pointercancel', onLeave);\n  document.addEventListener('keydown', onKey, { passive: true });\n  document.addEventListener('visibilitychange', onLeave);\n  window.addEventListener('blur', onLeave);\n}\n\nfunction stopTracking(): void {\n  if (!tracking) return;\n  tracking = false;\n  document.removeEventListener('pointermove', onMove);\n  document.removeEventListener('pointerleave', onLeave);\n  document.removeEventListener('pointercancel', onLeave);\n  document.removeEventListener('keydown', onKey);\n  document.removeEventListener('visibilitychange', onLeave);\n  window.removeEventListener('blur', onLeave);\n  if (raf !== 0) { cancelAnimationFrame(raf); raf = 0; }\n  if (near) { near.cursorLight = null; near = null; }\n  uS = 0; uCS = 0;\n  if (spillEl) { spillEl.remove(); spillEl = null; spillBg = ''; spillSize = -1; spillBlur = -1; spillShown = false; }\n  hideCursor();\n  if (curEl) { curEl.remove(); curEl = null; }\n}\n\nlet pointerIsMouse = true;\n/** Set on keydown, cleared by the next pointer move — keeps the sprite off\n *  while someone types even though the loop keeps running nearby. */\nlet typing = false;\n\nfunction onMove(e: PointerEvent): void {\n  pointerIsMouse = e.pointerType === 'mouse' || e.pointerType === '';\n  typing = false;\n  px = lpx = e.clientX;\n  py = lpy = e.clientY;\n  // While the sprite is up, hide the OS cursor and move the sprite *inside*\n  // the event, not in the next frame. WebKit re-evaluates the cursor only on\n  // mouse moves: a hide applied one frame late, after the pointer crossed\n  // into a new element and stopped, leaves the real arrow showing until the\n  // next move. Moving the sprite here also trims a frame of lag.\n  if (curShown && curEl) {\n    if (pointerIsMouse && claimCursor(px, py)) {\n      placeCursor(px, py);\n    } else {\n      hideCursor();\n    }\n  }\n  kick();\n}\n\n/** macOS hides the pointer while typing; match it, and never leave a fake\n *  arrow sitting over a field someone is keyboard-navigating. */\nfunction onKey(): void {\n  typing = true;\n  hideCursor();\n}\n\nfunction onLeave(): void {\n  px = py = Number.NaN;\n  kick();\n}\n\nfunction kick(): void {\n  if (!tracking || raf !== 0) return;\n  last = performance.now();\n  raf = requestAnimationFrame(step);\n}\n\n// ─── Geometry ─────────────────────────────────────────────────────────────\n\n/**\n * Signed distance from a box-local point to the ring's outer outline\n * (positive outside), writing the nearest outline point to `out`.\n */\nfunction nearestOutlinePoint(\n  lx: number, ly: number, W: number, H: number, R: number, kind: 'pill' | 'circle', out: { x: number; y: number }\n): number {\n  const rr = kind === 'circle' ? Math.min(W, H) / 2 : Math.max(0, Math.min(R, Math.min(W, H) / 2));\n  const cx = W / 2, cy = H / 2;\n  const hx = Math.max(0, W / 2 - rr), hy = Math.max(0, H / 2 - rr);\n  const qx = Math.max(-hx, Math.min(hx, lx - cx));\n  const qy = Math.max(-hy, Math.min(hy, ly - cy));\n  const dx = lx - cx - qx, dy = ly - cy - qy;\n  const len = Math.hypot(dx, dy);\n  if (len > 1e-6) {\n    out.x = cx + qx + (dx / len) * rr;\n    out.y = cy + qy + (dy / len) * rr;\n    return len - rr;\n  }\n  // Inside the straight-edged core: nearest side.\n  const dl = lx, dr = W - lx, dt = ly, db = H - ly;\n  const m = Math.min(dl, dr, dt, db);\n  if (m === dl) { out.x = 0; out.y = ly; }\n  else if (m === dr) { out.x = W; out.y = ly; }\n  else if (m === dt) { out.x = lx; out.y = 0; }\n  else { out.x = lx; out.y = H; }\n  return -m;\n}\n\n// ─── Pointer sprite ───────────────────────────────────────────────────────\n\nlet curEl: HTMLDivElement | null = null;\nlet curCanvas: HTMLCanvasElement | null = null;\nlet curCtx: CanvasRenderingContext2D | null = null;\nlet refCanvas: HTMLCanvasElement | null = null;\nlet refCtx: CanvasRenderingContext2D | null = null;\nlet refCtxReadable = false;\nlet curDpr = 0, curW = 0, curH = 0;\nlet curShown = false;\n/** Root-level hide (stable while the sprite is up — no churn as the pointer\n *  crosses elements, which is what WebKit shows as flicker), plus one\n *  element-level hide for elements that set their own `cursor: default`. */\nlet rootHidden = false;\nlet rootPrev = '';\nlet hiddenEl: HTMLElement | null = null;\nlet hiddenPrev = '';\n\nconst TEXTY = /^(INPUT|TEXTAREA|SELECT)$/;\n/** Per-element verdicts (true = plain arrow, claimable) so a pointermove\n *  doesn't force style resolution on every event. Cleared on release. */\nlet verdicts = new WeakMap<HTMLElement, boolean>();\nlet lastClaimMs = 0;\nlet lastTarget: HTMLElement | null = null;\n/** Elements where `cursor: auto` means something other than the arrow. */\nfunction isTextTarget(el: HTMLElement): boolean {\n  let n: HTMLElement | null = el;\n  while (n && n !== document.body) {\n    if (TEXTY.test(n.tagName) || n.isContentEditable) return true;\n    n = n.parentElement;\n  }\n  return false;\n}\n\nfunction ensureCursor(): boolean {\n  if (curEl) return true;\n  const el = document.createElement('div');\n  el.className = 'metal-fx-cursor';\n  el.setAttribute('aria-hidden', 'true');\n  el.style.cssText = 'position:fixed;left:0;top:0;pointer-events:none;z-index:2147483001;will-change:transform;transform-origin:0 0;display:none';\n  const c = document.createElement('canvas');\n  c.style.display = 'block';\n  el.appendChild(c);\n  document.body.appendChild(el);\n  const ctx = c.getContext('2d');\n  const rc = document.createElement('canvas');\n  const rctx = rc.getContext('2d');\n  if (!ctx || !rctx) { el.remove(); return false; }\n  curEl = el; curCanvas = c; curCtx = ctx; refCanvas = rc; refCtx = rctx;\n  return true;\n}\n\n/** Hide the OS cursor on the element under the pointer, if it shows the\n *  plain arrow there. Returns whether the sprite may show. */\nfunction claimCursor(x: number, y: number, force = false): boolean {\n  // Hit-testing forces layout; while the bend is animating that layout is\n  // dirty on every frame, so cap this at ~one per frame unless forced.\n  const now = performance.now();\n  if (!force && rootHidden && now - lastClaimMs < 12) return true;\n  lastClaimMs = now;\n  const target = document.elementFromPoint(x, y) as HTMLElement | null;\n  if (!target) { releaseCursor(); return false; }\n  if (target === lastTarget && rootHidden) return true;\n  lastTarget = target;\n  let ok = verdicts.get(target);\n  if (ok === undefined) {\n    ok = !isTextTarget(target);\n    if (ok) { const cur = getComputedStyle(target).cursor; ok = cur === 'auto' || cur === 'default' || cur === 'none'; }\n    verdicts.set(target, ok);\n  }\n  if (!ok) { releaseCursor(); return false; }\n  if (!rootHidden) {\n    const root = document.documentElement;\n    rootPrev = root.style.cursor;\n    root.style.cursor = 'none';\n    rootHidden = true;\n  }\n  // Elements that set `cursor: default` / `auto` themselves don't inherit the\n  // root's `none`; hide on them directly (rare — chips, drag handles).\n  if (target !== hiddenEl) {\n    if (hiddenEl) { hiddenEl.style.cursor = hiddenPrev; hiddenEl = null; hiddenPrev = ''; }\n    if (getComputedStyle(target).cursor !== 'none') {\n      hiddenEl = target; hiddenPrev = target.style.cursor;\n      target.style.cursor = 'none';\n    }\n  }\n  return true;\n}\n\nfunction releaseCursor(): void {\n  if (hiddenEl) {\n    if (hiddenEl.isConnected) hiddenEl.style.cursor = hiddenPrev;\n    hiddenEl = null; hiddenPrev = '';\n  }\n  if (rootHidden) {\n    document.documentElement.style.cursor = rootPrev;\n    rootHidden = false; rootPrev = '';\n  }\n  lastTarget = null;\n  verdicts = new WeakMap();\n}\n\nfunction hideCursor(): void {\n  releaseCursor();\n  if (curEl && curShown) { curEl.style.display = 'none'; curShown = false; }\n}\n\nfunction drawCursor(inst: MetalFxInstance, cfg: CursorLightConfig, env: number): void {\n  if (!curCtx || !refCtx || !curCanvas || !refCanvas || !curEl || !sprite || !spriteImg) return;\n  const sp = sprite;\n  const dpr = Math.min(3, window.devicePixelRatio || 1);\n  if (dpr !== curDpr || sp.width !== curW || sp.height !== curH) {\n    curDpr = dpr; curW = sp.width; curH = sp.height;\n    curCanvas.width = refCanvas.width = Math.ceil(sp.width * dpr);\n    curCanvas.height = refCanvas.height = Math.ceil(sp.height * dpr);\n    curCanvas.style.width = `${sp.width}px`;\n    curCanvas.style.height = `${sp.height}px`;\n  }\n  if (!refCtxReadable) { refCtx = refCanvas.getContext('2d', { willReadFrequently: true }); refCtxReadable = true; if (!refCtx) return; }\n  const ctx = curCtx, rctx = refCtx;\n  const W = sp.width, H = sp.height;\n\n  // The pointer itself.\n  ctx.setTransform(1, 0, 0, 1, 0, 0);\n  ctx.clearRect(0, 0, curCanvas.width, curCanvas.height);\n  ctx.scale(dpr, dpr);\n  ctx.drawImage(spriteImg, 0, 0, W, H);\n\n  // Light from the ring. Direction from the body centre to the outline\n  // point nearest it; the mirror plane sits on the body's silhouette in that\n  // direction, so only the face that looks at the ring catches light —\n  // cursor left of the button lights the pointer's right side, and so on.\n  const rx = _near.left + _near.nx * _near.k, ry = _near.top + _near.ny * _near.k;\n  const ccx = lpx - sp.hotX + bodyC.x, ccy = lpy - sp.hotY + bodyC.y;\n  const dx = rx - ccx, dy = ry - ccy;\n  const dist = Math.hypot(dx, dy);\n  const ux0 = dist > 0.01 ? dx / dist : 1, uy0 = dist > 0.01 ? dy / dist : 0;\n  const e = bodyExtent(ux0, uy0) + cfg.cursorEdge;\n  const dEdge = Math.max(0, dist - e);\n  const f0 = Math.max(1, cfg.cursorFalloff);\n  const falloff = 1 / (1 + (dEdge / f0) * (dEdge / f0));\n  // Sample the ring's colour a little inside its outer edge — the edge pixel\n  // itself is anti-aliased toward transparent and reads dark.\n  const bcx = inst.cssWidth / 2, bcy = inst.cssHeight / 2;\n  const inx = bcx - _near.nx, iny = bcy - _near.ny, inl = Math.hypot(inx, iny) || 1;\n  const ins = inst.mask ? 0 : inst.ringCssPx * 0.5 + 1;\n  const sxp = _near.nx + (inx / inl) * ins, syp = _near.ny + (iny / inl) * ins;\n  const pk = sampleShaderPeakAt(inst, sxp, syp, 4);\n  const lum = pk.lum;\n  const pr = pk.r, pg = pk.g, pb = pk.b;\n  const spec = cfg.cursorStrength * falloff * env;\n  const diff = cfg.cursorDiffuse * falloff * (0.5 + 0.5 * Math.min(1, lum / 0.5)) * env;\n  if (dist > 0.01 && spec + diff > 0.005) {\n    const ux = dx / dist, uy = dy / dist, a = Math.atan2(uy, ux);\n    const sdepth = Math.max(0.1, Math.min(1, cfg.cursorDepth));\n    // Mirror plane: on the face of the pointer that looks at the ring.\n    const mx = bodyC.x + e * ux, my = bodyC.y + e * uy;\n    const fl = Math.max(1, cfg.cursorReach);\n\n    rctx.setTransform(1, 0, 0, 1, 0, 0);\n    rctx.clearRect(0, 0, refCanvas.width, refCanvas.height);\n    rctx.scale(dpr, dpr);\n\n    // Specular: the ring seen in the pointer's surface.\n    if (spec > 0.005) {\n      rctx.save();\n      rctx.filter = cfg.cursorBlur > 0 ? `blur(${cfg.cursorBlur}px)` : 'none';\n      const zoom = Math.max(1, cfg.cursorZoom);\n      rctx.translate(mx, my);\n      rctx.rotate(a);\n      rctx.scale(-1, 1);                                // mirror across the plane\n      rctx.translate((dist - e) * sdepth, 0);           // ring point, depth-compressed, behind the plane\n      rctx.rotate(-a);\n      rctx.scale(zoom, zoom);                           // magnify around the ring point\n      const o = inst.overscan, k = _near.k;\n      const passes = Math.max(1, Math.ceil(spec));\n      rctx.globalAlpha = Math.min(1, spec / passes);\n      rctx.globalCompositeOperation = 'lighter';\n      const srcCanvas = inst.mask && inst.rawCanvas ? inst.rawCanvas : inst.canvas;\n      for (let i = 0; i < passes; i++) {\n        rctx.drawImage(srcCanvas, -(_near.nx + o) * k, -(_near.ny + o) * k, (inst.cssWidth + 2 * o) * k, (inst.cssHeight + 2 * o) * k);\n      }\n      rctx.restore();\n      // Fade into the body away from the mirror plane.\n      const inv = 1 / dpr, fl1 = 1 / fl;\n      alphaPass(rctx, refCanvas.width, refCanvas.height, (x, y) => {\n        const behind = -(((x + 0.5) * inv - mx) * ux + ((y + 0.5) * inv - my) * uy);\n        return behind <= 0 ? 1 : 1 - behind * fl1;\n      });\n    }\n\n    // Diffuse: the lit rim, in the ring's colour at that point.\n    if (diff > 0.005) {\n      const peak = Math.max(pr, pg, pb) || 1;\n      const cr = Math.round((pr * 255) / peak), cg = Math.round((pg * 255) / peak), cb = Math.round((pb * 255) / peak);\n      const dl = fl * 1.2;\n      const g = rctx.createLinearGradient(mx + 0.5 * ux, my + 0.5 * uy, mx - dl * ux, my - dl * uy);\n      const a0 = Math.min(1, diff);\n      g.addColorStop(0, `rgba(${cr},${cg},${cb},${a0.toFixed(3)})`);\n      g.addColorStop(0.45, `rgba(${cr},${cg},${cb},${(a0 * 0.4).toFixed(3)})`);\n      g.addColorStop(1, `rgba(${cr},${cg},${cb},0)`);\n      rctx.globalCompositeOperation = 'lighter';\n      rctx.fillStyle = g;\n      rctx.fillRect(0, 0, W, H);\n      rctx.globalCompositeOperation = 'source-over';\n    }\n\n    // Keep the light on the pointer's body only (not its soft shadow).\n    const body = bodyAlphaFor(spriteImg, sp, dpr, refCanvas.width, refCanvas.height);\n    if (body) alphaPass(rctx, refCanvas.width, refCanvas.height, (_x, _y, i) => body[i] === 0 ? 0 : 1);\n\n    ctx.globalCompositeOperation = 'lighter';\n    ctx.drawImage(refCanvas, 0, 0, W, H);\n    ctx.globalCompositeOperation = 'source-over';\n  }\n\n  placeCursor(lpx, lpy);\n  if (!curShown) { curEl.style.display = ''; curShown = true; }\n}\n\n// ─── Frame ────────────────────────────────────────────────────────────────\n\nfunction ensureSpill(): HTMLDivElement {\n  if (spillEl) return spillEl;\n  const el = document.createElement('div');\n  el.className = 'metal-fx-cursor-spill';\n  el.setAttribute('aria-hidden', 'true');\n  el.style.cssText =\n    'position:fixed;left:0;top:0;pointer-events:none;z-index:2147483000;border-radius:50%;' +\n    'mix-blend-mode:plus-lighter;will-change:transform,opacity;opacity:0;display:none';\n  document.body.appendChild(el);\n  spillEl = el;\n  return el;\n}\n\nfunction hideSpill(): void {\n  if (!spillEl || !spillShown) return;\n  spillEl.style.display = 'none';\n  spillEl.style.opacity = '0';\n  spillShown = false;\n}\n\nfunction step(now: number): void {\n  raf = 0;\n  if (!tracking) return;\n  // Own work only — `now` is the frame timestamp and includes whatever else\n  // ran in this frame (React renders, other rAF callbacks), which is not\n  // ours to be blamed for.\n  const t0 = performance.now();\n  try {\n    stepInner(now);\n  } catch (err) {\n    // Whatever broke, the user must get their cursor back.\n    cursorDisabled = true;\n    hideCursor();\n    hideSpill();\n    if (near) { near.cursorLight = null; near = null; }\n    if (typeof console !== 'undefined') console.warn('metal-fx: cursor light disabled after error', err);\n    return;\n  }\n  // Watchdog: this should cost well under a millisecond. If it keeps not\n  // doing so — huge pages, a pathological elementFromPoint — pause the\n  // cursor swap for a few seconds and try again.\n  const took = performance.now() - t0;\n  if (took > 6) {\n    if (++slowFrames >= 20) { slowFrames = 0; disabledUntil = performance.now() + 5000; hideCursor(); }\n  } else if (slowFrames > 0) slowFrames--;\n}\n\nfunction stepInner(now: number): void {\n  const cfg = CURSOR_LIGHT;\n  const dt = Math.min(0.05, Math.max(0.001, (now - last) / 1000));\n  last = now;\n\n  // Nearest ring within reach.\n  let best: MetalFxInstance | null = null;\n  let u = 0, uC = 0;\n  if (cfg.enabled && SHARED && !Number.isNaN(px)) {\n    let bestAbs = Number.POSITIVE_INFINITY;\n    const reachA = Math.max(1, cfg.reach);\n    const reachC = cfg.cursor && cursorSwapAllowed() ? Math.max(1, cfg.cursorDistance) : 0;\n    const reach = Math.max(reachA, reachC);\n    for (const inst of SHARED.instances) {\n      // Paused instances still hold a painted ring — they can light the\n      // pointer; only their glow tick is skipped further down.\n      if (!inst.visible || !inst.canvas.isConnected) continue;\n      const r = inst.canvas.getBoundingClientRect();\n      if (r.width <= 0) continue;\n      const o = inst.overscan;\n      const k = r.width / (inst.cssWidth + 2 * o);\n      const left = r.left + o * k, top = r.top + o * k;\n      const rk = reach * k;\n      if (px < left - rk || px > left + inst.cssWidth * k + rk || py < top - rk || py > top + inst.cssHeight * k + rk) continue;\n      const lx = (px - left) / k, ly = (py - top) / k;\n      const d = nearestOutlinePoint(lx, ly, inst.cssWidth, inst.cssHeight, inst.cornerRadius, inst.kind, _pt);\n      const ad = Math.abs(d);\n      if (ad <= reach && ad < bestAbs) {\n        bestAbs = ad; best = inst;\n        _near.d = d; _near.nx = _pt.x; _near.ny = _pt.y; _near.k = k; _near.left = left; _near.top = top;\n      }\n    }\n    if (best) {\n      if (bestAbs <= reachA) { const t = 1 - bestAbs / reachA; u = t * t * (3 - 2 * t); }\n      if (bestAbs <= reachC) uC = Math.min(1, (1 - bestAbs / reachC) * 3);\n      if (best.mask) {\n        // Metal text: the light is the word itself, not its box edge. Point\n        // the light at the box centre and keep the unmasked sheet around for\n        // the mirror image — three thin glyphs mirror as almost nothing.\n        _near.nx = best.cssWidth / 2; _near.ny = best.cssHeight / 2;\n        best.wantRaw = true;\n      }\n    }\n  }\n\n  // Envelope on the proximity weight — no pops on enter/leave/jump.\n  const a = 1 - Math.exp(-(dt * 1000) / (Math.max(1, cfg.fadeMs) / 3));\n  uS += (u - uS) * a;\n  uCS += (uC - uCS) * a;\n\n  if (best && best !== near) {\n    if (near) { near.cursorLight = null; tickInstanceGlow(near, now); }\n    near = best;\n  }\n  if (!best && uS < 0.002 && uCS < 0.002) {\n    uS = 0; uCS = 0;\n    if (near) { near.cursorLight = null; tickInstanceGlow(near, now); near = null; }\n    hideSpill();\n    hideCursor();\n    return;\n  }\n  if (!near) return;\n\n  // C — hand the glow a light source and tick it at pointer rate.\n  if (cfg.catchLight) {\n    const cl = near.cursorLight ?? (near.cursorLight = { x: 0, y: 0, w: 0 });\n    cl.x = _near.nx; cl.y = _near.ny; cl.w = uS;\n  } else if (near.cursorLight) {\n    near.cursorLight = null;\n  }\n  tickInstanceGlow(near, now);\n\n  // A — the ring on the cursor.\n  if (cfg.cursor && uCS > 0.002 && pointerIsMouse && !typing && !Number.isNaN(px) && cursorSwapAllowed() && ensureCursor() && claimCursor(px, py)) {\n    drawCursor(near, cfg, uCS);\n  } else {\n    hideCursor();\n  }\n\n  // B — the glint under the pointer.\n  if (cfg.spill) {\n    const el = ensureSpill();\n    const rgb = sampleShaderRGBAt(near, _near.nx, _near.ny, 2);\n    const lum = sampleShaderLumAt(near, _near.nx, _near.ny, 3);\n    const peak = Math.max(rgb.r, rgb.g, rgb.b) || 1;\n    const hsv = rgbToHsv((rgb.r * 255) / peak, (rgb.g * 255) / peak, (rgb.b * 255) / peak);\n    const [cr, cg, cb] = hsvToRgb(hsv[0], Math.min(1, hsv[1] * cfg.spillSaturation), 1);\n    _sc.r += (cr - _sc.r) * 0.15; _sc.g += (cg - _sc.g) * 0.15; _sc.b += (cb - _sc.b) * 0.15;\n    // Quantise so the gradient string (and its repaint) only changes on a\n    // visible step.\n    const qr = Math.round(_sc.r / 6) * 6, qg = Math.round(_sc.g / 6) * 6, qb = Math.round(_sc.b / 6) * 6;\n    const bg = `radial-gradient(closest-side, rgba(${qr},${qg},${qb},1) 0%, rgba(${qr},${qg},${qb},0.35) 45%, rgba(${qr},${qg},${qb},0) 100%)`;\n    if (bg !== spillBg) { spillBg = bg; el.style.background = bg; }\n\n    const R = Math.max(1, cfg.spillRadius * _near.k);\n    if (R !== spillSize) { spillSize = R; el.style.width = `${(2 * R).toFixed(1)}px`; el.style.height = `${(2 * R).toFixed(1)}px`; }\n    if (cfg.spillBlur !== spillBlur) { spillBlur = cfg.spillBlur; el.style.filter = cfg.spillBlur > 0 ? `blur(${cfg.spillBlur}px)` : ''; }\n\n    const rx = _near.left + _near.nx * _near.k, ry = _near.top + _near.ny * _near.k;\n    const sx = lpx + (rx - lpx) * cfg.spillOffset, sy = lpy + (ry - lpy) * cfg.spillOffset;\n    el.style.transform = `translate3d(${(sx - R).toFixed(2)}px,${(sy - R).toFixed(2)}px,0)`;\n\n    const lf = Math.min(1, Math.max(0, lum / 0.3));\n    const lumMix = 1 - cfg.spillLumGain + cfg.spillLumGain * lf;\n    const insideMul = _near.d < 0 ? cfg.spillInside : 1;\n    const op = Math.max(0, Math.min(1, cfg.spillStrength * uS * lumMix * insideMul));\n    if (!spillShown) { el.style.display = ''; spillShown = true; }\n    el.style.opacity = op.toFixed(3);\n  } else {\n    hideSpill();\n  }\n\n  raf = requestAnimationFrame(step);\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/glow/bake.ts",
          "target": "@components/effects/metal-fx/upstream/engine/glow/bake.ts",
          "type": "registry:component",
          "content": "/**\n * Pre-rendered glow sprites.\n *\n * The halo used to be four blurred SVG strokes re-rasterised through\n * `feGaussianBlur` on every move. Here the same strokes are rendered once,\n * in white, into small alpha bitmaps; the per-frame work is then a couple of\n * `drawImage` calls. Blur is a 3-pass box blur on the alpha channel (a close\n * gaussian approximation) so it doesn't depend on `ctx.filter` support.\n *\n * Sprites are cached by everything that shapes them — half-length, scale,\n * device pixel ratio and the GLOW markup values — and shared by every\n * instance with the same key.\n */\nimport { GLOW } from './config';\n\nexport interface Sprite {\n  canvas: HTMLCanvasElement;\n  /** Alpha per device pixel, row-major — the source for tinting. */\n  alpha: Uint8ClampedArray;\n  /** CSS-px size to draw it at. */\n  w: number;\n  h: number;\n  /** CSS-px offset from the sprite's top-left to its anchor (stroke centre). */\n  ax: number;\n  ay: number;\n}\n\nconst cache = new Map<string, Sprite>();\n\n// ─── Blur ─────────────────────────────────────────────────────────────────\n\n/** Box sizes for `n` passes approximating a gaussian of `sigma` (Kutskir). */\nfunction boxesForGauss(sigma: number, n: number): number[] {\n  const wIdeal = Math.sqrt((12 * sigma * sigma) / n + 1);\n  let wl = Math.floor(wIdeal);\n  if (wl % 2 === 0) wl--;\n  const wu = wl + 2;\n  const mIdeal = (12 * sigma * sigma - n * wl * wl - 4 * n * wl - 3 * n) / (-4 * wl - 4);\n  const m = Math.round(mIdeal);\n  const sizes: number[] = [];\n  for (let i = 0; i < n; i++) sizes.push(i < m ? wl : wu);\n  return sizes;\n}\n\nfunction boxBlurH(src: Float32Array, dst: Float32Array, w: number, h: number, r: number): void {\n  const iarr = 1 / (r + r + 1);\n  for (let y = 0; y < h; y++) {\n    const row = y * w;\n    let acc = 0;\n    for (let x = -r; x <= r; x++) acc += src[row + Math.min(w - 1, Math.max(0, x))];\n    for (let x = 0; x < w; x++) {\n      dst[row + x] = acc * iarr;\n      const out = row + Math.max(0, x - r), inn = row + Math.min(w - 1, x + r + 1);\n      acc += src[inn] - src[out];\n    }\n  }\n}\n\nfunction boxBlurV(src: Float32Array, dst: Float32Array, w: number, h: number, r: number): void {\n  const iarr = 1 / (r + r + 1);\n  for (let x = 0; x < w; x++) {\n    let acc = 0;\n    for (let y = -r; y <= r; y++) acc += src[Math.min(h - 1, Math.max(0, y)) * w + x];\n    for (let y = 0; y < h; y++) {\n      dst[y * w + x] = acc * iarr;\n      const out = Math.max(0, y - r) * w + x, inn = Math.min(h - 1, y + r + 1) * w + x;\n      acc += src[inn] - src[out];\n    }\n  }\n}\n\nexport function gaussBlur(a: Float32Array, w: number, h: number, sigma: number): Float32Array {\n  if (sigma <= 0.05) return a;\n  const tmp = new Float32Array(a.length);\n  const cur = a;\n  for (const box of boxesForGauss(sigma, 3)) {\n    const r = (box - 1) / 2;\n    boxBlurH(cur, tmp, w, h, r);\n    boxBlurV(tmp, cur, w, h, r);\n  }\n  return cur;\n}\n\n// ─── Rasterising ──────────────────────────────────────────────────────────\n\ninterface Layer { stroke: number; blur: number; opacity: number }\n\n/** Alpha of a horizontal round-capped line of `halfLen` at the given width,\n *  rendered through the 2D canvas so the AA matches what SVG produced. */\nfunction strokeAlpha(halfLen: number, strokeW: number, w: number, h: number, dpr: number, ax: number, ay: number): Float32Array {\n  const c = document.createElement('canvas');\n  c.width = w; c.height = h;\n  const g = c.getContext('2d', { willReadFrequently: true });\n  const out = new Float32Array(w * h);\n  if (!g) return out;\n  g.scale(dpr, dpr);\n  g.strokeStyle = '#fff';\n  g.lineCap = 'round';\n  g.lineJoin = 'round';\n  g.lineWidth = strokeW;\n  g.beginPath();\n  g.moveTo(ax - halfLen, ay);\n  g.lineTo(ax + halfLen, ay);\n  g.stroke();\n  const d = g.getImageData(0, 0, w, h).data;\n  for (let i = 0, j = 3; i < out.length; i++, j += 4) out[i] = d[j] / 255;\n  return out;\n}\n\nfunction compose(layers: Layer[], halfLen: number, s: number, dpr: number, fade: number): Sprite {\n  let padMax = 0;\n  for (const l of layers) padMax = Math.max(padMax, (l.stroke / 2 + 3 * l.blur) * s);\n  const pad = Math.ceil(padMax) + 1;\n  const cw = 2 * halfLen + 2 * pad, ch = 2 * pad;\n  const w = Math.ceil(cw * dpr), h = Math.ceil(ch * dpr);\n  const acc = new Float32Array(w * h);\n  for (const l of layers) {\n    let a = strokeAlpha(halfLen, l.stroke * s, w, h, dpr, pad, pad);\n    a = gaussBlur(a, w, h, l.blur * s * dpr);\n    const op = l.opacity;\n    // White over white: only alpha composes.\n    for (let i = 0; i < acc.length; i++) { const la = a[i] * op; acc[i] = acc[i] + la * (1 - acc[i]); }\n  }\n  if (fade > 0) {\n    // SVG luminance mask: white to 0.30, #404040 (0.25) at 0.65, black at 1.\n    const cx = pad * dpr, cy = pad * dpr, R = fade * s * dpr;\n    for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {\n      const t = Math.hypot(x + 0.5 - cx, y + 0.5 - cy) / R;\n      let m: number;\n      if (t <= 0.3) m = 1;\n      else if (t <= 0.65) m = 1 - ((t - 0.3) / 0.35) * 0.75;\n      else if (t < 1) m = 0.25 * (1 - (t - 0.65) / 0.35);\n      else m = 0;\n      acc[y * w + x] *= m;\n    }\n  }\n  const c = document.createElement('canvas');\n  c.width = w; c.height = h;\n  const g = c.getContext('2d');\n  const alpha = new Uint8ClampedArray(w * h);\n  for (let i = 0; i < acc.length; i++) alpha[i] = Math.round(Math.min(1, acc[i]) * 255);\n  if (g) {\n    const img = g.createImageData(w, h);\n    const d = img.data;\n    for (let i = 0, j = 0; i < acc.length; i++, j += 4) {\n      d[j] = 255; d[j + 1] = 255; d[j + 2] = 255; d[j + 3] = alpha[i];\n    }\n    g.putImageData(img, 0, 0);\n  }\n  return { canvas: c, alpha, w: cw, h: ch, ax: pad, ay: pad };\n}\n\nfunction markupKey(): string {\n  return [\n    GLOW.haloStrokeXl, GLOW.haloStrokeLg, GLOW.haloStrokeMd, GLOW.haloStrokeSm,\n    GLOW.haloBlurXl, GLOW.haloBlurLg, GLOW.haloBlurMd, GLOW.haloBlurSm,\n    GLOW.haloOpXl, GLOW.haloOpLg, GLOW.haloOpMd, GLOW.haloOpSm,\n    GLOW.extraStrokeOuter, GLOW.extraStrokeCore, GLOW.extraBlurOuter, GLOW.extraBlurCore,\n    GLOW.extraFadeR, GLOW.extraOpOuter,\n  ].join(',');\n}\n\n/** The wide halo: four blurred strokes stacked, at `halfLen` half-length. */\nexport function bakeHalo(halfLen: number, s: number, dpr: number): Sprite {\n  const key = `h|${halfLen.toFixed(2)}|${s}|${dpr}|${markupKey()}`;\n  let sp = cache.get(key);\n  if (!sp) {\n    sp = compose([\n      { stroke: GLOW.haloStrokeXl, blur: GLOW.haloBlurXl, opacity: GLOW.haloOpXl },\n      { stroke: GLOW.haloStrokeLg, blur: GLOW.haloBlurLg, opacity: GLOW.haloOpLg },\n      { stroke: GLOW.haloStrokeMd, blur: GLOW.haloBlurMd, opacity: GLOW.haloOpMd },\n      { stroke: GLOW.haloStrokeSm, blur: GLOW.haloBlurSm, opacity: GLOW.haloOpSm },\n    ], halfLen, s, dpr, 0);\n    cache.set(key, sp);\n  }\n  return sp;\n}\n\n/** The catch-light: two tight strokes with a radial fade at the ends. */\nexport function bakeExtra(halfLen: number, s: number, dpr: number): Sprite {\n  const key = `e|${halfLen.toFixed(2)}|${s}|${dpr}|${markupKey()}`;\n  let sp = cache.get(key);\n  if (!sp) {\n    sp = compose([\n      { stroke: GLOW.extraStrokeOuter, blur: GLOW.extraBlurOuter, opacity: GLOW.extraOpOuter },\n      { stroke: GLOW.extraStrokeCore, blur: GLOW.extraBlurCore, opacity: 1 },\n    ], halfLen, s, dpr, GLOW.extraFadeR);\n    cache.set(key, sp);\n  }\n  return sp;\n}\n\n/** A tinted copy of a white sprite. `holder` caches by tint so the re-tint\n *  only happens when the colour actually changes. Pixel-data based on\n *  purpose: no `source-in` compositing, which WebKit intermittently gets\n *  wrong on accelerated canvases (a solid rectangle instead of the shape). */\nexport interface Tinted { canvas: HTMLCanvasElement | null; img: ImageData | null; tint: number; src: Sprite | null }\n\nexport function tintSprite(src: Sprite, r: number, g: number, b: number, holder: Tinted): HTMLCanvasElement {\n  const key = (r << 16) | (g << 8) | b;\n  if (holder.canvas && holder.tint === key && holder.src === src) return holder.canvas;\n  let c = holder.canvas;\n  let img = holder.img;\n  if (!c || !img || holder.src !== src) {\n    c = document.createElement('canvas');\n    c.width = src.canvas.width; c.height = src.canvas.height;\n    img = c.getContext('2d')?.createImageData(c.width, c.height) ?? null;\n  }\n  const ctx = c.getContext('2d');\n  if (ctx && img) {\n    const d = img.data, a = src.alpha;\n    for (let i = 0, j = 0; i < a.length; i++, j += 4) { d[j] = r; d[j + 1] = g; d[j + 2] = b; d[j + 3] = a[i]; }\n    ctx.putImageData(img, 0, 0);\n  }\n  holder.canvas = c; holder.img = img; holder.tint = key; holder.src = src;\n  return c;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/glow/geometry.ts",
          "target": "@components/effects/metal-fx/upstream/engine/glow/geometry.ts",
          "type": "registry:component",
          "content": "/**\n * Pure geometry + SVG markup for the glow overlay.\n *\n * Perimeter math (rounded-rect / circle arc-length sampling), blob path\n * generation, SVG filter/mask construction, and HSV colour helpers.\n * No state — every function is a pure transform.\n */\nimport { PERIM_SAMPLES } from '../perfConfig';\n\nimport { GLOW } from './config';\nimport { outlinePathD, roundRectOutline } from '../renderer/outline';\n\nexport { PERIM_SAMPLES };\n\nexport interface GlowOptions {\n  width: number;\n  height: number;\n  cornerRadius: number;\n  kind: 'pill' | 'circle';\n  /** Master multiplier for absolute SVG units (stroke widths, blur,\n   *  fade-circle radius). 1 is the canonical 1× rendering. Set to 2 when\n   *  the host element is rendered at a 2× layout (e.g. CSS zoom: 2) so\n   *  the glow grows proportionally. */\n  scale?: number;\n  /**\n   * Point mode (custom-mask instances). `samplePoints` are box-local CSS-px\n   * positions inside the mask where luminance is sampled and the hotspot can\n   * sit; `maskDataUrl` is the mask rendered white-on-transparent, used to clip\n   * the glow to the glyphs instead of the ring band.\n   */\n  samplePoints?: Pt[];\n  maskDataUrl?: string;\n}\nexport interface Pt { x: number; y: number }\nexport interface PerimSample extends Pt { arc: number }\n\nexport function rrPerim(w: number, h: number, r: number): number {\n  const rr = Math.max(0, Math.min(r, Math.min(w, h) / 2));\n  return 2 * Math.max(0, w - 2 * rr) + 2 * Math.max(0, h - 2 * rr) + 2 * Math.PI * rr;\n}\n\nexport function shapePerim(w: number, h: number, r: number, kind: 'pill' | 'circle'): number {\n  if (kind === 'circle') return 2 * Math.PI * Math.max(0, Math.min(r, Math.min(w, h) / 2));\n  return rrPerim(w, h, r);\n}\n\nexport function sampleAtArc(s: number, w: number, h: number, r: number, inset: number, outward: number, kind: 'pill' | 'circle', out?: Pt): Pt {\n  const o = out || { x: 0, y: 0 };\n  const rr = Math.max(0, Math.min(r, Math.min(w, h) / 2));\n  if (kind === 'circle') {\n    const perim = 2 * Math.PI * rr;\n    if (perim <= 0.0001) { o.x = w * 0.5; o.y = h * 0.5; return o; }\n    s = ((s % perim) + perim) % perim;\n    const theta = -Math.PI / 2 + (s / perim) * Math.PI * 2;\n    const rad = Math.max(0, rr - inset + outward);\n    o.x = w * 0.5 + rad * Math.cos(theta);\n    o.y = h * 0.5 + rad * Math.sin(theta);\n    return o;\n  }\n  const topLen = Math.max(0, w - 2 * rr), sideLen = Math.max(0, h - 2 * rr);\n  const arcLen = (Math.PI * rr) / 2;\n  const perim = 2 * (topLen + sideLen) + 4 * arcLen;\n  s = ((s % perim) + perim) % perim;\n  const rad = Math.max(0, rr - inset + outward);\n  let d = s;\n  if (d < topLen) { o.x = rr + d; o.y = inset - outward; return o; }\n  d -= topLen;\n  if (d < arcLen) {\n    const theta = -Math.PI / 2 + (arcLen > 0 ? d / arcLen : 0) * (Math.PI / 2);\n    o.x = (w - rr) + rad * Math.cos(theta); o.y = rr + rad * Math.sin(theta); return o;\n  }\n  d -= arcLen;\n  if (d < sideLen) { o.x = w - inset + outward; o.y = rr + d; return o; }\n  d -= sideLen;\n  if (d < arcLen) {\n    const theta = (arcLen > 0 ? d / arcLen : 0) * (Math.PI / 2);\n    o.x = (w - rr) + rad * Math.cos(theta); o.y = (h - rr) + rad * Math.sin(theta); return o;\n  }\n  d -= arcLen;\n  if (d < topLen) { o.x = w - rr - d; o.y = h - inset + outward; return o; }\n  d -= topLen;\n  if (d < arcLen) {\n    const theta = Math.PI / 2 + (arcLen > 0 ? d / arcLen : 0) * (Math.PI / 2);\n    o.x = rr + rad * Math.cos(theta); o.y = (h - rr) + rad * Math.sin(theta); return o;\n  }\n  d -= arcLen;\n  if (d < sideLen) { o.x = inset - outward; o.y = h - rr - d; return o; }\n  d -= sideLen;\n  const theta = Math.PI + (arcLen > 0 ? d / arcLen : 0) * (Math.PI / 2);\n  o.x = rr + rad * Math.cos(theta); o.y = rr + rad * Math.sin(theta);\n  return o;\n}\n\n/**\n * Inverse of `sampleAtArc` at inset 0: the arc-length position on the outline\n * nearest a box-local point. Points off the outline project onto it.\n */\nexport function arcAtPoint(x: number, y: number, w: number, h: number, r: number, kind: 'pill' | 'circle'): number {\n  const rr = Math.max(0, Math.min(r, Math.min(w, h) / 2));\n  if (kind === 'circle') {\n    const perim = 2 * Math.PI * rr;\n    if (perim <= 0.0001) return 0;\n    const theta = Math.atan2(y - h / 2, x - w / 2);\n    const s = ((theta + Math.PI / 2) / (2 * Math.PI)) * perim;\n    return ((s % perim) + perim) % perim;\n  }\n  const topLen = Math.max(0, w - 2 * rr), sideLen = Math.max(0, h - 2 * rr);\n  const arcLen = (Math.PI * rr) / 2, Q = Math.PI / 2;\n  const s1 = topLen, s2 = s1 + arcLen, s3 = s2 + sideLen, s4 = s3 + arcLen, s5 = s4 + topLen, s6 = s5 + arcLen, s7 = s6 + sideLen;\n  const inX = x >= rr && x <= w - rr, inY = y >= rr && y <= h - rr;\n  if (inX && inY) {\n    const dl = x, dr = w - x, dt = y, db = h - y, m = Math.min(dl, dr, dt, db);\n    if (m === dt) return x - rr;\n    if (m === dr) return s2 + (y - rr);\n    if (m === db) return s4 + (w - rr - x);\n    return s6 + (h - rr - y);\n  }\n  if (inX) return y < h / 2 ? x - rr : s4 + (w - rr - x);\n  if (inY) return x > w / 2 ? s2 + (y - rr) : s6 + (h - rr - y);\n  if (x > w / 2 && y < h / 2) { const t = Math.atan2(y - rr, x - (w - rr)); return s1 + ((t + Q) / Q) * arcLen; }\n  if (x > w / 2) { const t = Math.atan2(y - (h - rr), x - (w - rr)); return s3 + (t / Q) * arcLen; }\n  if (y > h / 2) { const t = Math.atan2(y - (h - rr), x - rr); return s5 + ((t - Q) / Q) * arcLen; }\n  const t = Math.atan2(y - rr, x - rr);\n  return s7 + ((t + Math.PI) / Q) * arcLen;\n}\n\nexport function buildStaticBlobPath(halfLen: number, segments: number): string {\n  const step = (halfLen * 2) / segments;\n  let d = '';\n  for (let i = 0; i <= segments; i++) {\n    const x = -halfLen + i * step;\n    d += (i === 0 ? 'M ' : 'L ') + x.toFixed(3) + ' 0 ';\n  }\n  return d;\n}\n\nconst _ta: Pt = { x: 0, y: 0 };\nconst _tb: Pt = { x: 0, y: 0 };\n\nexport function tangentAngleAtArc(s: number, w: number, h: number, r: number, inset: number, kind: 'pill' | 'circle'): number {\n  const eps = 0.1;\n  sampleAtArc(s - eps, w, h, r, inset, 0, kind, _ta);\n  sampleAtArc(s + eps, w, h, r, inset, 0, kind, _tb);\n  return Math.atan2(_tb.y - _ta.y, _tb.x - _ta.x);\n}\n\nexport function smoothstep(a: number, b: number, x: number): number {\n  if (a === b) return x < a ? 0 : 1;\n  const t = Math.max(0, Math.min(1, (x - a) / (b - a)));\n  return t * t * (3 - 2 * t);\n}\n\nexport function buildPerimTable(opts: GlowOptions): PerimSample[] {\n  if (opts.samplePoints && opts.samplePoints.length > 0) {\n    // Point mode: `arc` is just the index — relocation logic works on\n    // indices, and positioning bypasses arc math entirely.\n    return opts.samplePoints.map((p, i) => ({ x: p.x, y: p.y, arc: i }));\n  }\n  const perim = shapePerim(opts.width, opts.height, opts.cornerRadius, opts.kind);\n  const insetS = GLOW.inset * (opts.scale ?? 1);\n  const table: PerimSample[] = [];\n  for (let i = 0; i < PERIM_SAMPLES; i++) {\n    const arc = (i / PERIM_SAMPLES) * perim;\n    const pt = sampleAtArc(arc, opts.width, opts.height, opts.cornerRadius, insetS, 0, opts.kind);\n    table.push({ x: pt.x, y: pt.y, arc });\n  }\n  return table;\n}\n\nexport function buildSvgMarkup(opts: GlowOptions, p: string): string {\n  const { width: W, height: H, cornerRadius: R } = opts;\n  const s = opts.scale ?? 1;\n  const ringInset = opts.kind === 'circle' ? 2 : 1;\n  const innerR = Math.max(0, R - ringInset);\n  // Filter region grows with scale so blurred strokes don't get clipped at\n  // bigger sizes. The 200/540/440 baseline matches the canonical 1× pill.\n  const fX = (-200 * s).toFixed(0), fY = fX;\n  const fW = (540 * s).toFixed(0), fH = (440 * s).toFixed(0);\n  const fRect = `x=\"${fX}\" y=\"${fY}\" width=\"${fW}\" height=\"${fH}\"`;\n  const fr = `${fRect} filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"`;\n  // Stroke widths and blur stdDeviations are absolute SVG units; multiply\n  // by `s` so they remain proportional when viewBox grows with the host.\n  const sw = (n: number) => (n * s).toFixed(3);\n  const sd = (n: number) => (n * s).toFixed(3);\n  return [\n    '<defs>',\n    `<filter id=\"${p}_bXl\" ${fr}><feGaussianBlur stdDeviation=\"${sd(GLOW.haloBlurXl)}\"/></filter>`,\n    `<filter id=\"${p}_bLg\" ${fr}><feGaussianBlur stdDeviation=\"${sd(GLOW.haloBlurLg)}\"/></filter>`,\n    `<filter id=\"${p}_bMd\" ${fr}><feGaussianBlur stdDeviation=\"${sd(GLOW.haloBlurMd)}\"/></filter>`,\n    `<filter id=\"${p}_bSm\" ${fr}><feGaussianBlur stdDeviation=\"${sd(GLOW.haloBlurSm)}\"/></filter>`,\n    `<filter id=\"${p}_ebO\" ${fr}><feGaussianBlur stdDeviation=\"${sd(GLOW.extraBlurOuter)}\"/></filter>`,\n    `<filter id=\"${p}_ebC\" ${fr}><feGaussianBlur stdDeviation=\"${sd(GLOW.extraBlurCore)}\"/></filter>`,\n    `<radialGradient id=\"${p}_fg\" cx=\"0.5\" cy=\"0.5\" r=\"0.5\"><stop offset=\"0\" stop-color=\"white\"/><stop offset=\"0.30\" stop-color=\"white\"/><stop offset=\"0.65\" stop-color=\"#404040\"/><stop offset=\"1\" stop-color=\"black\"/></radialGradient>`,\n    `<mask id=\"${p}_fm\" maskUnits=\"userSpaceOnUse\" ${fRect}><rect ${fRect} fill=\"black\"/><circle id=\"${p}_fc\" cx=\"0\" cy=\"0\" r=\"${(GLOW.extraFadeR * s).toFixed(3)}\" fill=\"url(#${p}_fg)\"/></mask>`,\n    opts.maskDataUrl\n      // Point mode clips hard to the glyphs (black surround); the halo's\n      // blurred energy outside the strokes is discarded, so `pointGain`\n      // compensates inside them.\n      ? `<mask id=\"${p}_rm\" maskUnits=\"userSpaceOnUse\" ${fRect}><rect ${fRect} fill=\"black\"/><image href=\"${opts.maskDataUrl}\" x=\"0\" y=\"0\" width=\"${W}\" height=\"${H}\" preserveAspectRatio=\"none\"/></mask>`\n      : `<mask id=\"${p}_rm\" maskUnits=\"userSpaceOnUse\" ${fRect}><rect ${fRect} fill=\"#808080\"/><path id=\"${p}_rmO\" d=\"${outlinePathD(roundRectOutline(0, 0, W, H, R, null))}\" fill=\"white\"/><path id=\"${p}_rmI\" d=\"${outlinePathD(roundRectOutline(ringInset, ringInset, W - ringInset * 2, H - ringInset * 2, innerR, null))}\" fill=\"black\"/></mask>`,\n    '</defs>',\n    // Safari clips mask to the masked element's bbox; our horizontal strokes\n    // have zero height, so the mask becomes a sliver. These spacer rects\n    // inflate the bbox to the full filter region.\n    `<g id=\"${p}_h\" mask=\"url(#${p}_rm)\" opacity=\"0\">`,\n    `<rect ${fRect} fill=\"none\" pointer-events=\"none\"/>`,\n    `<g id=\"${p}_hI\" stroke=\"white\">`,\n    `<path id=\"${p}_pXl\" stroke-width=\"${sw(GLOW.haloStrokeXl)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"${GLOW.haloOpXl}\" filter=\"url(#${p}_bXl)\"/>`,\n    `<path id=\"${p}_pLg\" stroke-width=\"${sw(GLOW.haloStrokeLg)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"${GLOW.haloOpLg}\" filter=\"url(#${p}_bLg)\"/>`,\n    `<path id=\"${p}_pMd\" stroke-width=\"${sw(GLOW.haloStrokeMd)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"${GLOW.haloOpMd}\" filter=\"url(#${p}_bMd)\"/>`,\n    `<path id=\"${p}_pSm\" stroke-width=\"${sw(GLOW.haloStrokeSm)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"${GLOW.haloOpSm}\" filter=\"url(#${p}_bSm)\"/>`,\n    '</g></g>',\n    `<g id=\"${p}_e\" mask=\"url(#${p}_rm)\" opacity=\"0\">`,\n    `<rect ${fRect} fill=\"none\" pointer-events=\"none\"/>`,\n    `<g mask=\"url(#${p}_fm)\">`,\n    `<g id=\"${p}_eI\" stroke=\"white\">`,\n    `<path id=\"${p}_eO\" stroke-width=\"${sw(GLOW.extraStrokeOuter)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"${GLOW.extraOpOuter}\" filter=\"url(#${p}_ebO)\"/>`,\n    `<path id=\"${p}_eC\" stroke-width=\"${sw(GLOW.extraStrokeCore)}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\" opacity=\"1.0\" filter=\"url(#${p}_ebC)\"/>`,\n    '</g></g></g>',\n  ].join('');\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/rim.ts",
          "target": "@components/effects/metal-fx/upstream/engine/rim.ts",
          "type": "registry:component",
          "content": "/**\n * Inner-shadow rim on the metal ring — the same treatment the \"Pro\" text\n * carries (Figma: white 90 %, offset 0/1, blur 0.5): a hairline of light\n * along the top inside edge of the band.\n *\n * Computed, not CSS: band alpha minus the same alpha shifted down by the\n * offset leaves exactly the top rim (outer edge on the ring's upper half,\n * inner edge on its lower half — what a light from above does to a torus).\n * Blurred, tinted, drawn to a small overlay canvas above the metal. Redrawn\n * only when the outline changes (deform), so it's free at rest.\n */\nimport type { DeformFn } from './renderer/core';\nimport { gaussBlur } from './glow/bake';\nimport { type OutlineBuf, createOutlineBuf, roundRectOutline } from './renderer/outline';\n\nexport interface RimOptions {\n  /** Shadow offset, CSS px (positive = light from above). */\n  offsetY: number;\n  /** Blur, CSS px. */\n  blur: number;\n  /** Peak opacity of the rim (0..1). */\n  alpha: number;\n  /** Rim colour, `#rrggbb`. */\n  color: string;\n}\n\nexport const RIM_DEFAULTS: Readonly<RimOptions> = Object.freeze({ offsetY: 1, blur: 0.5, alpha: 0.9, color: '#ffffff' });\n\nexport interface RimHandles {\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  scratch: HTMLCanvasElement;\n  sctx: CanvasRenderingContext2D;\n  width: number; height: number; cornerRadius: number; kind: 'pill' | 'circle'; ring: number;\n  margin: number; dpr: number;\n  opts: RimOptions;\n  mO: OutlineBuf; mI: OutlineBuf;\n  /** Checksum of the outline last drawn; unchanged composites are skipped. */\n  sum: number;\n}\n\nexport function injectRim(\n  container: HTMLElement,\n  dims: { width: number; height: number; cornerRadius: number; kind: 'pill' | 'circle'; ring: number },\n  opts: RimOptions\n): RimHandles | null {\n  const dpr = Math.min(3, typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1);\n  const margin = Math.ceil(3 * opts.blur + Math.abs(opts.offsetY) + 1);\n  const cw = dims.width + 2 * margin, ch = dims.height + 2 * margin;\n  const canvas = document.createElement('canvas');\n  canvas.className = 'metal-fx-rim-canvas';\n  canvas.setAttribute('aria-hidden', 'true');\n  canvas.width = Math.ceil(cw * dpr); canvas.height = Math.ceil(ch * dpr);\n  canvas.style.cssText = `position:absolute;left:${-margin}px;top:${-margin}px;width:${cw}px;height:${ch}px;pointer-events:none`;\n  const ctx = canvas.getContext('2d');\n  const scratch = document.createElement('canvas');\n  scratch.width = canvas.width; scratch.height = canvas.height;\n  const sctx = scratch.getContext('2d', { willReadFrequently: true });\n  if (!ctx || !sctx) return null;\n  container.appendChild(canvas);\n  const h: RimHandles = {\n    canvas, ctx, scratch, sctx,\n    width: dims.width, height: dims.height, cornerRadius: dims.cornerRadius, kind: dims.kind, ring: dims.ring,\n    margin, dpr, opts, mO: createOutlineBuf(), mI: createOutlineBuf(), sum: Number.NaN,\n  };\n  updateRim(h, null, true);\n  return h;\n}\n\nfunction trace(g: CanvasRenderingContext2D, buf: OutlineBuf, off: number): void {\n  const xy = buf.xy;\n  for (let i = 0; i < buf.n; i++) {\n    const x = xy[i * 2] + off, y = xy[i * 2 + 1] + off;\n    if (i === 0) g.moveTo(x, y); else g.lineTo(x, y);\n  }\n  g.closePath();\n}\n\n/** Redraw if the (deformed) outline changed. Cheap when it hasn't. */\nexport function updateRim(h: RimHandles, deform: DeformFn | null, force = false): void {\n  const { width: W, height: H, cornerRadius: R, ring, margin: m, dpr } = h;\n  roundRectOutline(0, 0, W, H, R, deform, h.mO);\n  roundRectOutline(ring, ring, W - 2 * ring, H - 2 * ring, Math.max(0, R - ring), deform, h.mI);\n  let sum = 0;\n  const xy = h.mO.xy;\n  for (let i = 0; i < h.mO.n; i += 4) sum += xy[i * 2] * 1.37 + xy[i * 2 + 1];\n  if (!force && sum === h.sum) return;\n  h.sum = sum;\n\n  const { sctx: g, scratch: sc, ctx, canvas: cv, opts } = h;\n  const w = sc.width, hh = sc.height;\n  g.setTransform(1, 0, 0, 1, 0, 0);\n  g.clearRect(0, 0, w, hh);\n  g.scale(dpr, dpr);\n  g.fillStyle = '#fff';\n  g.beginPath();\n  trace(g, h.mO, m);\n  trace(g, h.mI, m);\n  g.fill('evenodd');\n\n  const d = g.getImageData(0, 0, w, hh).data;\n  const n = w * hh;\n  const a = new Float32Array(n);\n  for (let i = 0, j = 3; i < n; i++, j += 4) a[i] = d[j] / 255;\n  const shift = Math.round(opts.offsetY * dpr) * w;\n  // Coverage the shifted band doesn't cover. A difference, not a product:\n  // on anti-aliased edges both values are partial and a product lit every\n  // edge instead of only the top one.\n  const rim = new Float32Array(n);\n  if (shift >= 0) {\n    for (let i = 0; i < n; i++) rim[i] = Math.max(0, a[i] - (i >= shift ? a[i - shift] : 0));\n  } else {\n    for (let i = 0; i < n; i++) rim[i] = Math.max(0, a[i] - (i - shift < n ? a[i - shift] : 0));\n  }\n  const blurred = gaussBlur(rim, w, hh, opts.blur * dpr);\n\n  const cr = parseInt(opts.color.slice(1, 3), 16), cg = parseInt(opts.color.slice(3, 5), 16), cb = parseInt(opts.color.slice(5, 7), 16);\n  const img = ctx.createImageData(w, hh);\n  const o = img.data;\n  for (let i = 0, j = 0; i < n; i++, j += 4) {\n    o[j] = cr; o[j + 1] = cg; o[j + 2] = cb;\n    // Inner shadow: clipped to the band so the blur never leaks outside it.\n    o[j + 3] = Math.round(Math.min(1, blurred[i] * a[i] * opts.alpha) * 255);\n  }\n  ctx.setTransform(1, 0, 0, 1, 0, 0);\n  ctx.putImageData(img, 0, 0);\n  void cv;\n}\n\nexport function removeRim(h: RimHandles | null): void {\n  if (h) h.canvas.remove();\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/reflection/paint.ts",
          "target": "@components/effects/metal-fx/upstream/engine/reflection/paint.ts",
          "type": "registry:component",
          "content": "/** Proximity reflection — public API and per-frame paint loop. */\nimport type { MetalFxInstance } from '../renderer/core';\nimport {\n  ATTACH_RANGE_PX,\n  BASE_ALPHA,\n  BOOST_ALPHA,\n  BORDER_HILITE_ALPHA,\n  BORDER_HILITE_PX,\n  FILL_CIRCLE_ATTENUATION,\n  FILL_EXTRA_ALPHA,\n  FILL_OPACITY_MUL,\n  GLOBAL_ATTENUATION,\n  GRAD_FAR,\n  GRAD_MID,\n  GRAD_NEAR,\n  OVERLAP_MIN_PX,\n  INTENSITY_MULT,\n  MAX_ALPHA_STACK,\n  RANGE_PX,\n  REF_DRAW_CSS_W,\n  REFLECTION_BLOCKED_TAGS,\n  STROKE_CSS_PX,\n  STROKE_EXTRA_ALPHA,\n  type ReflectionTarget,\n} from './constants';\nimport {\n  type BoxRect,\n  type DrawDst,\n  drawBorderHighlight,\n  isHorizontalNeighbour,\n  isVerticalNeighbour,\n  maskedFillPasses,\n  maskedStrokePasses,\n  shortestRectDistance,\n} from './geometry';\nimport { attachObservers, detachObservers, readCornerRadius, readHairlineSpec } from './observers';\n\nexport type { ReflectionTarget } from './constants';\n\nconst targets: Set<ReflectionTarget> = new Set();\n\n// ─── Cursor occluder ──────────────────────────────────────────────────────\n// The reflection is light leaving the anchor and landing on the target. A\n// pointer sitting in the gap between them blocks some of that light, so we\n// cut a soft shadow band out of the painted reflection at the pointer's\n// position across the layout axis. The band widens with distance from the\n// target (penumbra from an extended source) and is only applied while the\n// pointer is actually inside the gap.\n\nexport interface ReflectionOccluderConfig {\n  enabled: boolean;\n  /** Occluder radius, CSS px — how \"big\" the cursor is as a light blocker. */\n  radius: number;\n  /** Peak shadow depth (0..1) with the pointer right at the target's edge. */\n  strength: number;\n  /** Penumbra growth: band half-height multiplier at the anchor's edge. */\n  penumbra: number;\n  /** How much depth is lost as the pointer moves from target edge (0) to\n   *  anchor edge (1). 0 = same shadow everywhere in the gap. */\n  falloff: number;\n  /** Fade-in distance at the gap's ends, as a multiple of `radius`. */\n  edgeFade: number;\n  /** Band profile. 1 = smooth triangle, 0 = hard-edged plateau. */\n  softness: number;\n  /** Repaint throttle while the pointer moves, ms. */\n  repaintMs: number;\n}\n\nexport const REFLECTION_OCCLUDER_DEFAULTS: Readonly<ReflectionOccluderConfig> = Object.freeze({\n  enabled: true,\n  radius: 11.5,\n  strength: 0.57,\n  penumbra: 0.55,\n  falloff: 0.21,\n  edgeFade: 0.7,\n  softness: 0.24,\n  repaintMs: 36,\n});\n\nexport const REFLECTION_OCCLUDER: ReflectionOccluderConfig = { ...REFLECTION_OCCLUDER_DEFAULTS };\n\nexport function setReflectionOccluderConfig(patch: Partial<ReflectionOccluderConfig>): void {\n  Object.assign(REFLECTION_OCCLUDER, patch);\n  scheduleOccluderRepaint();\n}\n\nexport function resetReflectionOccluderConfig(): void {\n  setReflectionOccluderConfig({ ...REFLECTION_OCCLUDER_DEFAULTS });\n}\n\nlet occluder: { x: number; y: number } | null = null;\nlet occluderRaf = 0;\nlet occluderLastMs = 0;\nlet pointerTracked = false;\n\nfunction scheduleOccluderRepaint(): void {\n  if (occluderRaf !== 0 || typeof requestAnimationFrame === 'undefined') return;\n  occluderRaf = requestAnimationFrame((now) => {\n    occluderRaf = 0;\n    // 30 fps is plenty for a shadow that follows a hand.\n    if (now - occluderLastMs < REFLECTION_OCCLUDER.repaintMs) { scheduleOccluderRepaint(); return; }\n    occluderLastMs = now;\n    paintReflections();\n  });\n}\n\n// Repaint only while the pointer can actually cast a shadow — inside the\n// region spanning some anchor and its target (expanded by the occluder\n// radius) — plus one more repaint on the way out to clear it. Without this\n// every mouse move anywhere on the page re-rasterised every reflection.\nlet occluderWasNear = false;\nfunction pointerNearAnyGap(x: number, y: number): boolean {\n  const r = REFLECTION_OCCLUDER.radius;\n  for (const t of targets) {\n    const a = t.anchorEl.getBoundingClientRect();\n    const b = t.el.getBoundingClientRect();\n    const l = Math.min(a.left, b.left) - r, rt = Math.max(a.right, b.right) + r;\n    const tp = Math.min(a.top, b.top) - r, bt = Math.max(a.bottom, b.bottom) + r;\n    if (x >= l && x <= rt && y >= tp && y <= bt) return true;\n  }\n  return false;\n}\nfunction onOccluderMove(e: PointerEvent): void {\n  occluder = { x: e.clientX, y: e.clientY };\n  if (!REFLECTION_OCCLUDER.enabled) return;\n  const near = pointerNearAnyGap(e.clientX, e.clientY);\n  if (near || occluderWasNear) scheduleOccluderRepaint();\n  occluderWasNear = near;\n}\nfunction onOccluderLeave(): void {\n  occluder = null;\n  if (occluderWasNear) scheduleOccluderRepaint();\n  occluderWasNear = false;\n}\n\nfunction ensurePointerTracking(on: boolean): void {\n  if (typeof document === 'undefined' || on === pointerTracked) return;\n  pointerTracked = on;\n  if (on) {\n    document.addEventListener('pointermove', onOccluderMove, { passive: true });\n    document.addEventListener('pointerleave', onOccluderLeave);\n    window.addEventListener('blur', onOccluderLeave);\n  } else {\n    document.removeEventListener('pointermove', onOccluderMove);\n    document.removeEventListener('pointerleave', onOccluderLeave);\n    window.removeEventListener('blur', onOccluderLeave);\n    occluder = null;\n  }\n}\n\n/**\n * Cut the pointer's shadow out of a freshly painted reflection.\n * `horiz` — layout axis; light travels along x when true.\n */\nfunction applyOccluderShadow(\n  ctx: CanvasRenderingContext2D,\n  strokeCtx: CanvasRenderingContext2D,\n  aRect: DOMRect,\n  tRect: DOMRect,\n  horiz: boolean,\n  tw: number,\n  th: number,\n  overscanCssPx: number,\n  dpr: number\n): void {\n  if (!occluder) return;\n  const cfg = REFLECTION_OCCLUDER;\n  if (!cfg.enabled || cfg.strength <= 0) return;\n  const r = cfg.radius;\n\n  // Gap along the layout axis between the two facing edges, and the overlap\n  // band across it. Pointer must be inside (expanded by r) for any effect.\n  let gapStart: number, gapEnd: number, along: number, across: number, bandLo: number, bandHi: number;\n  if (horiz) {\n    const anchorRight = aRect.left >= tRect.right;\n    gapStart = anchorRight ? tRect.right : aRect.right;   // target-side edge\n    gapEnd = anchorRight ? aRect.left : tRect.left;       // anchor-side edge\n    along = occluder.x; across = occluder.y;\n    bandLo = Math.max(aRect.top, tRect.top); bandHi = Math.min(aRect.bottom, tRect.bottom);\n  } else {\n    const anchorBelow = aRect.top >= tRect.bottom;\n    gapStart = anchorBelow ? tRect.bottom : aRect.bottom;\n    gapEnd = anchorBelow ? aRect.top : tRect.top;\n    along = occluder.y; across = occluder.x;\n    bandLo = Math.max(aRect.left, tRect.left); bandHi = Math.min(aRect.right, tRect.right);\n  }\n  const lo = Math.min(gapStart, gapEnd), hi = Math.max(gapStart, gapEnd);\n  const gapW = Math.max(1, hi - lo);\n  if (along < lo - r || along > hi + r) return;\n  if (across < bandLo - r || across > bandHi + r) return;\n\n  // 0 at the target's edge, 1 at the anchor's edge.\n  const t = Math.max(0, Math.min(1, Math.abs(along - gapStart) / gapW));\n  // Fade at the region's edges on both axes so entering/leaving from any\n  // side eases in instead of popping — coming at the gap from above or\n  // below used to land the full band in one frame.\n  const fadePx = Math.max(0.5, r * cfg.edgeFade);\n  const endFade = Math.min(1, Math.min(along - (lo - r), (hi + r) - along) / fadePx);\n  const sideFade = Math.min(1, Math.min(across - (bandLo - r), (bandHi + r) - across) / fadePx);\n  const depth = cfg.strength * (1 - cfg.falloff * t) * endFade * sideFade;\n  if (depth <= 0.001) return;\n\n  const halfBand = r * dpr * (1 + cfg.penumbra * t);\n  // Position across the target, in the target canvas' device space.\n  const c = horiz\n    ? (across - tRect.top + overscanCssPx) * dpr\n    : (across - tRect.left + overscanCssPx) * dpr;\n  // softness 1 → triangle; 0 → flat plateau across the whole band.\n  const core = Math.max(0, Math.min(0.5, (1 - cfg.softness) * 0.5));\n  const ramp = Math.max(1e-3, 0.5 - core);\n\n  // Cut the band out in pixel data. Not `destination-out`: WebKit\n  // intermittently misapplies composite ops on accelerated canvases and\n  // paints the band's rectangle instead — a flash at the band's edges.\n  const span = horiz ? th : tw;\n  const p0 = Math.max(0, Math.floor(c - halfBand)), p1 = Math.min(span, Math.ceil(c + halfBand));\n  if (p1 <= p0) return;\n  const factor = new Float32Array(p1 - p0);\n  for (let i = p0; i < p1; i++) {\n    const p = (i + 0.5 - (c - halfBand)) / (2 * halfBand);\n    const a = p < ramp ? p / ramp : p > 1 - ramp ? (1 - p) / ramp : 1;\n    factor[i - p0] = 1 - depth * Math.max(0, Math.min(1, a));\n  }\n  for (const c2d of [ctx, strokeCtx]) {\n    const x = horiz ? 0 : p0, y = horiz ? p0 : 0;\n    const w = horiz ? tw : p1 - p0, h = horiz ? p1 - p0 : th;\n    const img = c2d.getImageData(x, y, w, h);\n    const d = img.data;\n    if (horiz) {\n      for (let row = 0; row < h; row++) {\n        const f = factor[row];\n        if (f >= 0.999) continue;\n        for (let j = row * w * 4 + 3, e = (row + 1) * w * 4; j < e; j += 4) d[j] = d[j] * f;\n      }\n    } else {\n      for (let row = 0; row < h; row++) {\n        for (let col = 0; col < w; col++) {\n          const f = factor[col];\n          if (f >= 0.999) continue;\n          const j = (row * w + col) * 4 + 3;\n          d[j] = d[j] * f;\n        }\n      }\n    }\n    c2d.putImageData(img, x, y);\n  }\n}\n\n// Scratch pair for multi-edge (contained) targets. Each masked pass ends with\n// a `destination-in` gradient over the whole ring clip, which would erase the\n// previous edge's ink — so every edge after the first paints here and is\n// composited back with `lighter`.\nlet scratchFill: HTMLCanvasElement | null = null;\nlet scratchStroke: HTMLCanvasElement | null = null;\nlet scratchFillCtx: CanvasRenderingContext2D | null = null;\nlet scratchStrokeCtx: CanvasRenderingContext2D | null = null;\nfunction ensureScratch(w: number, h: number): boolean {\n  if (!scratchFill) {\n    scratchFill = document.createElement('canvas');\n    scratchStroke = document.createElement('canvas');\n    scratchFillCtx = scratchFill.getContext('2d', { alpha: true });\n    scratchStrokeCtx = scratchStroke.getContext('2d', { alpha: true });\n  }\n  if (!scratchFillCtx || !scratchStrokeCtx || !scratchFill || !scratchStroke) return false;\n  if (scratchFill.width !== w) { scratchFill.width = w; scratchStroke.width = w; }\n  if (scratchFill.height !== h) { scratchFill.height = h; scratchStroke.height = h; }\n  scratchFillCtx.setTransform(1, 0, 0, 1, 0, 0);\n  scratchStrokeCtx.setTransform(1, 0, 0, 1, 0, 0);\n  scratchFillCtx.globalCompositeOperation = 'source-over';\n  scratchStrokeCtx.globalCompositeOperation = 'source-over';\n  scratchFillCtx.clearRect(0, 0, w, h);\n  scratchStrokeCtx.clearRect(0, 0, w, h);\n  return true;\n}\n\nexport function addReflectionTarget(\n  el: HTMLElement,\n  anchor: MetalFxInstance,\n  anchorEl: HTMLElement,\n  strength = 1\n): ReflectionTarget | null {\n  if (typeof document === 'undefined') return null;\n  if (REFLECTION_BLOCKED_TAGS.has(el.tagName)) return null;\n  for (const existing of targets) {\n    if (existing.el === el) { existing.strength = strength; return existing; }\n  }\n\n  const wrap = document.createElement('div');\n  wrap.setAttribute('data-metal-fx-reflection', '');\n  wrap.setAttribute('aria-hidden', 'true');\n\n  const canvas = document.createElement('canvas');\n  canvas.className = 'metal-fx-reflection-canvas';\n  const ctx = canvas.getContext('2d', { alpha: true, willReadFrequently: true });\n  if (!ctx) return null;\n\n  const strokeCanvas = document.createElement('canvas');\n  strokeCanvas.className = 'metal-fx-reflection-stroke-canvas';\n  const strokeCtx = strokeCanvas.getContext('2d', { alpha: true, willReadFrequently: true });\n  if (!strokeCtx) return null;\n\n  wrap.appendChild(canvas);\n  wrap.appendChild(strokeCanvas);\n\n  const cs = getComputedStyle(el);\n  let appliedPositionRelative = false;\n  if (cs.position === 'static') {\n    el.style.position = 'relative';\n    appliedPositionRelative = true;\n  }\n  let appliedIsolation = false;\n  if (cs.isolation !== 'isolate') {\n    el.style.isolation = 'isolate';\n    appliedIsolation = true;\n  }\n  el.setAttribute('data-metal-fx-reflect-host', '');\n  el.insertBefore(wrap, el.firstChild);\n\n  const initialSpec = readHairlineSpec(el);\n  const target: ReflectionTarget = {\n    el,\n    anchor,\n    anchorEl,\n    strength,\n    wrap,\n    canvas,\n    ctx,\n    strokeCanvas,\n    strokeCtx,\n    cornerRadius: readCornerRadius(el),\n    hairlineWidth: initialSpec.width,\n    hairlineOuterCssPx: initialSpec.outerCssPx,\n    appliedPositionRelative,\n    appliedIsolation,\n    resizeObserver: null,\n    mutationObserver: null,\n  };\n  attachObservers(target);\n  targets.add(target);\n  ensurePointerTracking(true);\n  return target;\n}\n\nexport function removeReflectionTarget(el: HTMLElement): void {\n  for (const target of targets) {\n    if (target.el === el) {\n      detachObservers(target);\n      target.canvas.width = 0;\n      target.canvas.height = 0;\n      target.strokeCanvas.width = 0;\n      target.strokeCanvas.height = 0;\n      if (target.wrap.parentNode === target.el) {\n        target.el.removeChild(target.wrap);\n      }\n      target.el.removeAttribute('data-metal-fx-reflect-host');\n      if (target.appliedPositionRelative) target.el.style.position = '';\n      if (target.appliedIsolation) target.el.style.isolation = '';\n      targets.delete(target);\n      if (targets.size === 0) ensurePointerTracking(false);\n      return;\n    }\n  }\n}\n\n/** Bounding box of pixels with alpha > 8 inside a sub-rect, device px. */\nfunction alphaBBox(\n  canvas: HTMLCanvasElement, x0: number, y0: number, w: number, h: number\n): { x: number; y: number; w: number; h: number } | null {\n  if (w < 1 || h < 1) return null;\n  const g = canvas.getContext('2d');\n  if (!g) return null;\n  const d = g.getImageData(x0, y0, w, h).data;\n  let minX = w, minY = h, maxX = -1, maxY = -1;\n  for (let y = 0; y < h; y++) {\n    const row = y * w;\n    for (let x = 0; x < w; x++) {\n      if (d[(row + x) * 4 + 3] > 8) {\n        if (x < minX) minX = x; if (x > maxX) maxX = x;\n        if (y < minY) minY = y; if (y > maxY) maxY = y;\n      }\n    }\n  }\n  if (maxX < 0) return null;\n  return { x: x0 + minX, y: y0 + minY, w: maxX - minX + 1, h: maxY - minY + 1 };\n}\n\nexport function paintReflections(): void {\n  if (targets.size === 0) return;\n  const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n\n  const anchorRects = new Map<HTMLElement, DOMRect>();\n\n  for (const t of targets) {\n    const tRect = t.el.getBoundingClientRect();\n    let aRect = anchorRects.get(t.anchorEl);\n    if (!aRect) {\n      aRect = t.anchorEl.getBoundingClientRect();\n      anchorRects.set(t.anchorEl, aRect);\n    }\n    if (tRect.width < 1 || tRect.height < 1) continue;\n    if (aRect.width < 1 || aRect.height < 1) continue;\n    // Glyph targets (text masked to its letterforms, see `data-metal-fx-text`)\n    // are lit differently from a chip: no rim stroke or border highlight —\n    // those are a white hairline along a box edge, which on text reads as a\n    // flat light on the last letter — just the mirrored metal itself, at its\n    // natural size so its banding stays legible, fading over a longer run so\n    // more than one letter catches it.\n    const glyph = t.el.hasAttribute('data-metal-fx-text');\n    if (glyph && !t.glyphStyled) {\n      // The chip blur (4 px) exists to melt the ring into a soft rim glow. On\n      // letters it erases exactly the detail the mirror should show — the\n      // stripes and dispersion fringes — so keep it to anti-aliasing width.\n      t.canvas.style.filter = 'blur(0.4px) saturate(1.35) brightness(1.2)';\n      t.glyphStyled = true;\n    }\n\n    if (\n      !isHorizontalNeighbour(aRect, tRect, OVERLAP_MIN_PX, ATTACH_RANGE_PX) &&\n      !isVerticalNeighbour(aRect, tRect, OVERLAP_MIN_PX, ATTACH_RANGE_PX)\n    ) {\n      if (t.canvas.width !== 1) { t.canvas.width = 1; t.canvas.height = 1; }\n      if (t.strokeCanvas.width !== 1) { t.strokeCanvas.width = 1; t.strokeCanvas.height = 1; }\n      continue;\n    }\n\n    // Glyph target on a masked anchor: mirror the metal *sheet*, not the\n    // three thin letters cut from it. A mirror facing the \"Pro\" glyphs shows\n    // the material's stripes across its whole face; the masked canvas would\n    // give mostly transparency with a few slivers.\n    const useRaw = glyph && !!t.anchor.mask;\n    if (useRaw && !t.anchor.wantRaw) t.anchor.wantRaw = true;\n    if (!t.anchor.wantRing) t.anchor.wantRing = true;\n    // While bending, mirror the ring-only snapshot, not the canvas that also\n    // carries the host's bent fill and rims.\n    const bending = !!t.anchor.deform && !!t.anchor.ringCanvas;\n    const anchorCanvas = (useRaw && t.anchor.rawCanvas) ? t.anchor.rawCanvas : bending ? t.anchor.ringCanvas! : t.anchor.canvas;\n    // Sample only the anchor's CSS box. While a vector bend is active the\n    // canvas carries an `overscan` margin on every side; reading it whole\n    // would shrink the ring to the middle of the slice and miss the band.\n    const ovs = Math.round(t.anchor.overscan * dpr);\n    let ssx = ovs, ssy = ovs;\n    let sw = (anchorCanvas.width | 0) - 2 * ovs;\n    let sh = (anchorCanvas.height | 0) - 2 * ovs;\n    // Custom-mask anchors (metal text): the metal is wherever the mask\n    // painted, not at the box edge. Crop the source to its alpha bounding\n    // box so the glyphs' edge — not the padding — lands on the target.\n    if (t.anchor.mask && !useRaw) {\n      const bb = alphaBBox(anchorCanvas, ssx, ssy, sw, sh);\n      if (bb) { ssx = bb.x; ssy = bb.y; sw = bb.w; sh = bb.h; }\n    }\n    if (sw < 4 || sh < 4) continue;\n\n    const acx = (aRect.left + aRect.right) * 0.5;\n    const acy = (aRect.top + aRect.bottom) * 0.5;\n    const tcx = (tRect.left + tRect.right) * 0.5;\n    const tcy = (tRect.top + tRect.bottom) * 0.5;\n    const dx = acx - tcx;\n    const dy = acy - tcy;\n\n    const edgeGapH = Math.max(aRect.left - tRect.right, tRect.left - aRect.right, 0);\n    const edgeGapV = Math.max(aRect.top - tRect.bottom, tRect.top - aRect.bottom, 0);\n    const isHorizontalLayout = edgeGapH >= edgeGapV;\n\n    const dist = shortestRectDistance(aRect, tRect);\n    let proximity = 1 - Math.min(1, dist / RANGE_PX);\n    proximity = proximity * proximity * (3 - 2 * proximity);\n    const intensity = BASE_ALPHA + (BOOST_ALPHA - BASE_ALPHA) * proximity;\n\n    const reflectionAlpha = Math.min(\n      MAX_ALPHA_STACK,\n      intensity * INTENSITY_MULT * GLOBAL_ATTENUATION\n    ) * t.strength;\n\n    // A target that contains the anchor (the card the button lives in) has no\n    // single \"facing\" edge — the button sits near a corner, so the echo lands\n    // on both the closest vertical and closest horizontal inner edge.\n    const contained =\n      aRect.left >= tRect.left && aRect.right <= tRect.right &&\n      aRect.top >= tRect.top && aRect.bottom <= tRect.bottom;\n    const layouts: boolean[] = contained ? [true, false] : [isHorizontalLayout];\n\n    // Effective scale of the host element. Anything drawn on the reflection\n    // canvas (strokes, border-highlight) is in DEVICE pixels, so it doesn't\n    // automatically grow when the host is rendered at non-1× layout (CSS\n    // zoom: 2, etc.). Multiply absolute-pixel constants by the anchor's\n    // scale so the reflection scales together with the metal effect itself.\n    const sScale = t.anchor.scale ?? 1;\n    const hairlineCssPx = Math.max(STROKE_CSS_PX * sScale, t.hairlineWidth);\n    const strokeBandPx = Math.max(1, Math.round(hairlineCssPx * dpr));\n    const borderHighlightPx = Math.max(\n      1,\n      Math.round(Math.max(BORDER_HILITE_PX * sScale, t.hairlineWidth) * dpr)\n    );\n\n    const overscanCssPx = t.hairlineOuterCssPx;\n    t.wrap.style.inset = `${-overscanCssPx}px`;\n    t.wrap.style.borderRadius = `${Math.max(0, t.cornerRadius)}px`;\n\n    const tw = Math.max(1, Math.round((tRect.width + overscanCssPx * 2) * dpr));\n    const th = Math.max(1, Math.round((tRect.height + overscanCssPx * 2) * dpr));\n    if (t.canvas.width !== tw) t.canvas.width = tw;\n    if (t.canvas.height !== th) t.canvas.height = th;\n    if (t.strokeCanvas.width !== tw) t.strokeCanvas.width = tw;\n    if (t.strokeCanvas.height !== th) t.strokeCanvas.height = th;\n\n    const ctx = t.ctx;\n    ctx.setTransform(1, 0, 0, 1, 0, 0);\n    ctx.clearRect(0, 0, tw, th);\n    const strokeCtx = t.strokeCtx;\n    strokeCtx.setTransform(1, 0, 0, 1, 0, 0);\n    strokeCtx.clearRect(0, 0, tw, th);\n\n    for (const [li, horiz] of layouts.entries()) {\n      // First edge paints straight into the target; later edges go via scratch.\n      const viaScratch = li > 0 && ensureScratch(tw, th);\n      const fCtx = viaScratch ? (scratchFillCtx as CanvasRenderingContext2D) : ctx;\n      const sCtx = viaScratch ? (scratchStrokeCtx as CanvasRenderingContext2D) : strokeCtx;\n      const bandDevPx = Math.min((glyph ? RANGE_PX * 1.5 : RANGE_PX) * dpr, Math.max(tw, th));\n      let g0x: number, g0y: number, g1x: number, g1y: number;\n      if (horiz) {\n        g0x = dx > 0 ? tw : 0; g1x = dx > 0 ? tw - bandDevPx : bandDevPx;\n        g0y = th * 0.5; g1y = th * 0.5;\n      } else {\n        g0y = dy > 0 ? th : 0; g1y = dy > 0 ? th - bandDevPx : bandDevPx;\n        g0x = tw * 0.5; g1x = tw * 0.5;\n      }\n      const grad = ctx.createLinearGradient(g0x, g0y, g1x, g1y);\n      grad.addColorStop(0, `rgba(0,0,0,${GRAD_NEAR})`);\n      grad.addColorStop(0.5, `rgba(0,0,0,${GRAD_MID})`);\n      grad.addColorStop(1, `rgba(0,0,0,${GRAD_FAR})`);\n\n      const anchorCssW = sw / dpr;\n      const refWdpr = glyph\n        ? Math.max(1, Math.min(horiz ? tw : th, Math.round(horiz ? sw : sh)))\n        : Math.max(1, Math.round(REF_DRAW_CSS_W * Math.max(0.1, anchorCssW / 140) * dpr));\n\n      let drawX: number, drawY: number, drawW: number, drawH: number;\n      let flipX = false, flipY = false;\n      if (horiz) {\n        const overlapTop = Math.max(aRect.top, tRect.top);\n        const overlapBot = Math.min(aRect.bottom, tRect.bottom);\n        flipX = true;\n        drawX = dx > 0 ? tw - refWdpr : 0;\n        drawY = Math.round((overlapTop - tRect.top + overscanCssPx) * dpr);\n        drawW = refWdpr;\n        drawH = Math.max(1, Math.round((overlapBot - overlapTop) * dpr));\n      } else {\n        const overlapLeft = Math.max(aRect.left, tRect.left);\n        const overlapRight = Math.min(aRect.right, tRect.right);\n        flipY = true;\n        drawX = Math.round((overlapLeft - tRect.left + overscanCssPx) * dpr);\n        drawY = dy > 0 ? th - refWdpr : 0;\n        drawW = Math.max(1, Math.round((overlapRight - overlapLeft) * dpr));\n        drawH = refWdpr;\n      }\n      const drawDst: DrawDst = { x: drawX, y: drawY, w: drawW, h: drawH, flipX, flipY, sx: ssx, sy: ssy };\n\n      const strokeBox: BoxRect = { x: 0, y: 0, w: tw, h: th, r: Math.max(0, t.cornerRadius * dpr) };\n\n      // Glyphs: one pass, never over 1 — stacking `lighter` passes clips the\n      // metal's highlights to white and the colour is gone.\n      const fillReflectionAlpha = glyph\n        ? Math.min(1, reflectionAlpha * FILL_OPACITY_MUL)\n        : Math.min(MAX_ALPHA_STACK, reflectionAlpha * FILL_EXTRA_ALPHA * FILL_OPACITY_MUL * FILL_CIRCLE_ATTENUATION);\n      maskedFillPasses(fCtx, anchorCanvas, sw, sh, tw, th, fillReflectionAlpha, grad, drawDst, strokeBox, dpr, glyph ? Math.max(tw, th) : undefined);\n\n      if (!glyph) {\n        maskedStrokePasses(\n          sCtx, anchorCanvas, sw, sh, tw, th,\n          strokeBox, reflectionAlpha, strokeBandPx, grad, STROKE_EXTRA_ALPHA, drawDst\n        );\n\n        drawBorderHighlight(\n          sCtx, strokeBox, borderHighlightPx,\n          g0x, g0y, g1x, g1y,\n          Math.min(0.85, BORDER_HILITE_ALPHA * reflectionAlpha)\n        );\n      }\n\n      if (viaScratch) {\n        ctx.globalCompositeOperation = 'lighter';\n        ctx.drawImage(scratchFill as HTMLCanvasElement, 0, 0);\n        strokeCtx.globalCompositeOperation = 'lighter';\n        strokeCtx.drawImage(scratchStroke as HTMLCanvasElement, 0, 0);\n      }\n    }\n\n    for (const horiz of layouts) {\n      applyOccluderShadow(ctx, strokeCtx, aRect, tRect, horiz, tw, th, overscanCssPx, dpr);\n    }\n\n    ctx.globalCompositeOperation = 'source-over';\n    strokeCtx.globalCompositeOperation = 'source-over';\n  }\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/reflection/constants.ts",
          "target": "@components/effects/metal-fx/upstream/engine/reflection/constants.ts",
          "type": "registry:component",
          "content": "/**\n * Canonical constants and types for proximity reflections.\n *\n * Verbatim from `Image loader/index.html` L5851-5915. Shared across\n * the observer, geometry, and paint modules.\n */\nimport type { MetalFxInstance } from '../renderer/core';\n\nexport const RANGE_PX = 12;\nexport const ATTACH_RANGE_PX = 32;\nexport const OVERLAP_MIN_PX = 1;\nexport const BASE_ALPHA = 0.55;\nexport const BOOST_ALPHA = 1.0;\nexport const GRAD_NEAR = 1.0;\nexport const GRAD_MID = 0.85;\nexport const GRAD_FAR = 0.0;\nexport const INTENSITY_MULT = 1.3;\nexport const MAX_ALPHA_STACK = 3.6;\nexport const GLOBAL_ATTENUATION = 0.7;\nexport const STROKE_CSS_PX = 1;\nexport const STROKE_EXTRA_ALPHA = 0.52;\nexport const BORDER_HILITE_PX = 1.0;\nexport const BORDER_HILITE_ALPHA = 0.044;\nexport const REF_DRAW_CSS_W = 235;\nexport const FILL_EXTRA_ALPHA = 2.535;\nexport const FILL_OPACITY_MUL = 0.7;\nexport const FILL_CIRCLE_ATTENUATION = 0.5;\n\nexport const REFLECTION_BLOCKED_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT', 'OPTION']);\n\nexport interface ReflectionTarget {\n  el: HTMLElement;\n  anchor: MetalFxInstance;\n  anchorEl: HTMLElement;\n  /** Per-target alpha multiplier from the public API. 1 = canonical. */\n  strength: number;\n  wrap: HTMLDivElement;\n  canvas: HTMLCanvasElement;\n  ctx: CanvasRenderingContext2D;\n  strokeCanvas: HTMLCanvasElement;\n  strokeCtx: CanvasRenderingContext2D;\n  cornerRadius: number;\n  hairlineWidth: number;\n  hairlineOuterCssPx: number;\n  appliedPositionRelative: boolean;\n  appliedIsolation: boolean;\n  resizeObserver: ResizeObserver | null;\n  mutationObserver: MutationObserver | null;\n  /** Glyph-target canvas styling applied (see paint). */\n  glyphStyled?: boolean;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/reflection/geometry.ts",
          "target": "@components/effects/metal-fx/upstream/engine/reflection/geometry.ts",
          "type": "registry:component",
          "content": "/**\n * Canvas 2D drawing primitives for proximity reflections.\n *\n * All the low-level compositing passes — rounded-rect paths, ring clips,\n * fill/stroke multi-pass alpha stacking, mirror-flip drawImage, and the\n * border-highlight gradient stroke.\n */\nimport { RANGE_PX } from './constants';\n\n// ─── Layout helpers ───────────────────────────────────────────────────────\n\nexport function shortestRectDistance(a: DOMRect, b: DOMRect): number {\n  const dx = Math.max(a.left - b.right, b.left - a.right, 0);\n  const dy = Math.max(a.top - b.bottom, b.top - a.bottom, 0);\n  return Math.sqrt(dx * dx + dy * dy);\n}\n\nexport function isHorizontalNeighbour(anchorRect: DOMRect, targetRect: DOMRect, overlapMin: number, attachRange: number): boolean {\n  const verticalOverlap =\n    Math.min(anchorRect.bottom, targetRect.bottom) -\n    Math.max(anchorRect.top, targetRect.top);\n  if (verticalOverlap < overlapMin) return false;\n  const horizontalGap = Math.max(\n    anchorRect.left - targetRect.right,\n    targetRect.left - anchorRect.right,\n    0\n  );\n  if (horizontalGap > attachRange) return false;\n  return true;\n}\n\nexport function isVerticalNeighbour(anchorRect: DOMRect, targetRect: DOMRect, overlapMin: number, attachRange: number): boolean {\n  const horizontalOverlap =\n    Math.min(anchorRect.right, targetRect.right) -\n    Math.max(anchorRect.left, targetRect.left);\n  if (horizontalOverlap < overlapMin) return false;\n  const verticalGap = Math.max(\n    anchorRect.top - targetRect.bottom,\n    targetRect.top - anchorRect.bottom,\n    0\n  );\n  return verticalGap <= attachRange;\n}\n\n// ─── Path helpers ─────────────────────────────────────────────────────────\n\nexport function roundRectPath(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  w: number,\n  h: number,\n  r: number\n): void {\n  const rr = Math.max(0, Math.min(r, w * 0.5, h * 0.5));\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const native = (ctx as any).roundRect;\n  if (typeof native === 'function') {\n    native.call(ctx, x, y, w, h, rr);\n    return;\n  }\n  ctx.moveTo(x + rr, y);\n  ctx.lineTo(x + w - rr, y);\n  ctx.quadraticCurveTo(x + w, y, x + w, y + rr);\n  ctx.lineTo(x + w, y + h - rr);\n  ctx.quadraticCurveTo(x + w, y + h, x + w - rr, y + h);\n  ctx.lineTo(x + rr, y + h);\n  ctx.quadraticCurveTo(x, y + h, x, y + h - rr);\n  ctx.lineTo(x, y + rr);\n  ctx.quadraticCurveTo(x, y, x + rr, y);\n}\n\n// ─── Draw source (mirror flip) ───────────────────────────────────────────\n\nexport interface DrawDst {\n  x: number;\n  y: number;\n  w: number;\n  h: number;\n  flipX: boolean;\n  flipY: boolean;\n  /** Source-rect origin in the anchor canvas, device px. Non-zero while the\n   *  anchor is overscanned (vector bend) so only its CSS box is sampled. */\n  sx?: number;\n  sy?: number;\n}\n\nexport function drawSource(\n  ctx: CanvasRenderingContext2D,\n  src: CanvasImageSource,\n  sw: number,\n  sh: number,\n  dst: DrawDst\n): void {\n  if (!dst.flipX && !dst.flipY) {\n    ctx.drawImage(src, dst.sx ?? 0, dst.sy ?? 0, sw, sh, dst.x, dst.y, dst.w, dst.h);\n    return;\n  }\n  ctx.save();\n  if (dst.flipX) {\n    ctx.translate(dst.x + dst.w, 0);\n    ctx.scale(-1, 1);\n  }\n  if (dst.flipY) {\n    ctx.translate(0, dst.y + dst.h);\n    ctx.scale(1, -1);\n  }\n  ctx.drawImage(\n    src,\n    dst.sx ?? 0,\n    dst.sy ?? 0,\n    sw,\n    sh,\n    dst.flipX ? 0 : dst.x,\n    dst.flipY ? 0 : dst.y,\n    dst.w,\n    dst.h\n  );\n  ctx.restore();\n}\n\n// ─── Clip + compositing passes ────────────────────────────────────────────\n\nexport interface BoxRect {\n  x: number;\n  y: number;\n  w: number;\n  h: number;\n  r: number;\n}\n\nconst FILL_BLUR_CSS_PX = 4;\n\nfunction fillRingClip(\n  ctx: CanvasRenderingContext2D,\n  x: number, y: number, w: number, h: number,\n  radiusDevPx: number, bandDevPx: number\n): void {\n  if (w <= 2 * bandDevPx || h <= 2 * bandDevPx) {\n    ctx.beginPath();\n    roundRectPath(ctx, x, y, w, h, radiusDevPx);\n    ctx.clip();\n    return;\n  }\n  ctx.beginPath();\n  roundRectPath(ctx, x, y, w, h, radiusDevPx);\n  roundRectPath(ctx, x + bandDevPx, y + bandDevPx, w - 2 * bandDevPx, h - 2 * bandDevPx, Math.max(0, radiusDevPx - bandDevPx));\n  ctx.clip('evenodd');\n}\n\nexport function maskedFillPasses(\n  ctx: CanvasRenderingContext2D,\n  src: CanvasImageSource,\n  sw: number, sh: number,\n  tw: number, th: number,\n  totalAlpha: number,\n  grad: CanvasGradient,\n  dst: DrawDst,\n  fillBox: BoxRect,\n  dpr: number,\n  /** Override for the edge band the fill is clipped to, device px. Glyph\n   *  targets pass the whole box — letters have no \"rim\" to hug. */\n  bandDevPxOverride?: number\n): void {\n  const fillBandDevPx = bandDevPxOverride ?? Math.max(1, Math.round((RANGE_PX + FILL_BLUR_CSS_PX * 3) * dpr));\n  let remaining = Math.max(0, totalAlpha);\n  let firstChunk = true;\n  for (let i = 0; i < 3 && remaining > 1e-4; i++) {\n    const a = Math.min(1, remaining);\n    ctx.save();\n    fillRingClip(ctx, fillBox.x, fillBox.y, fillBox.w, fillBox.h, fillBox.r, fillBandDevPx);\n    ctx.globalCompositeOperation = firstChunk ? 'source-over' : 'lighter';\n    firstChunk = false;\n    ctx.globalAlpha = a;\n    drawSource(ctx, src, sw, sh, dst);\n    ctx.globalAlpha = 1;\n    ctx.globalCompositeOperation = 'destination-in';\n    ctx.fillStyle = grad;\n    ctx.fillRect(0, 0, tw, th);\n    ctx.restore();\n    remaining -= a;\n  }\n}\n\nfunction insideStrokeEvenOddClip(\n  ctx: CanvasRenderingContext2D,\n  x: number, y: number, w: number, h: number,\n  radiusDevPx: number, strokeDevPx: number\n): void {\n  const r = strokeDevPx | 0;\n  if (r < 1 || w <= 2 * r || h <= 2 * r) {\n    ctx.beginPath();\n    roundRectPath(ctx, x, y, w, h, radiusDevPx);\n    ctx.clip();\n    return;\n  }\n  ctx.beginPath();\n  roundRectPath(ctx, x, y, w, h, radiusDevPx);\n  roundRectPath(ctx, x + r, y + r, w - 2 * r, h - 2 * r, Math.max(0, radiusDevPx - r));\n  ctx.clip('evenodd');\n}\n\nexport function maskedStrokePasses(\n  ctx: CanvasRenderingContext2D,\n  src: CanvasImageSource,\n  sw: number, sh: number,\n  tw: number, th: number,\n  strokeBox: BoxRect,\n  intensity: number,\n  strokeBandPx: number,\n  grad: CanvasGradient,\n  strokeExtraAlpha: number,\n  dst: DrawDst\n): void {\n  let remaining = intensity * strokeExtraAlpha;\n  let firstChunk = true;\n  for (let i = 0; i < 3 && remaining > 1e-4; i++) {\n    const a = Math.min(1, remaining);\n    ctx.save();\n    insideStrokeEvenOddClip(ctx, strokeBox.x, strokeBox.y, strokeBox.w, strokeBox.h, strokeBox.r, strokeBandPx);\n    ctx.globalCompositeOperation = firstChunk ? 'source-over' : 'lighter';\n    firstChunk = false;\n    ctx.globalAlpha = a;\n    drawSource(ctx, src, sw, sh, dst);\n    ctx.globalAlpha = 1;\n    ctx.globalCompositeOperation = 'destination-in';\n    ctx.fillStyle = grad;\n    ctx.fillRect(0, 0, tw, th);\n    ctx.restore();\n    remaining -= a;\n  }\n}\n\nexport function drawBorderHighlight(\n  ctx: CanvasRenderingContext2D,\n  strokeBox: BoxRect,\n  strokeDevPx: number,\n  g0x: number, g0y: number,\n  g1x: number, g1y: number,\n  alpha: number\n): void {\n  const grad = ctx.createLinearGradient(g0x, g0y, g1x, g1y);\n  grad.addColorStop(0, `rgba(255,255,255,${alpha.toFixed(3)})`);\n  grad.addColorStop(0.5, `rgba(255,255,255,${(alpha * 0.45).toFixed(3)})`);\n  grad.addColorStop(1, 'rgba(255,255,255,0)');\n\n  ctx.save();\n  insideStrokeEvenOddClip(ctx, strokeBox.x, strokeBox.y, strokeBox.w, strokeBox.h, strokeBox.r, strokeDevPx);\n  ctx.globalCompositeOperation = 'lighter';\n  ctx.lineWidth = strokeDevPx * 2;\n  ctx.strokeStyle = grad;\n  ctx.beginPath();\n  roundRectPath(ctx, strokeBox.x, strokeBox.y, strokeBox.w, strokeBox.h, strokeBox.r);\n  ctx.stroke();\n  ctx.restore();\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/reflection/observers.ts",
          "target": "@components/effects/metal-fx/upstream/engine/reflection/observers.ts",
          "type": "registry:component",
          "content": "/**\n * Style observation for reflection targets.\n *\n * Reads corner radii and hairline specs from computed styles, and\n * attaches ResizeObserver / MutationObserver so values stay fresh\n * without per-frame getComputedStyle calls.\n */\nimport type { ReflectionTarget } from './constants';\n\nexport function readCornerRadius(el: HTMLElement): number {\n  const cs = getComputedStyle(el);\n  const radii = [\n    parseFloat(cs.borderTopLeftRadius) || 0,\n    parseFloat(cs.borderTopRightRadius) || 0,\n    parseFloat(cs.borderBottomRightRadius) || 0,\n    parseFloat(cs.borderBottomLeftRadius) || 0,\n  ].filter((v) => v > 0);\n  return radii.length ? Math.min.apply(null, radii) : 0;\n}\n\n/**\n * Read the visible \"hairline\" geometry of the host so the 1-px stroke\n * reflection sits exactly on the host's existing ring.\n *\n * Returns the visible thickness (`width`) and the OUTWARD extent past the\n * padding-box edge (`outerCssPx`) — the wrap is overscanned by `outerCssPx`\n * on every side so its outer rim lines up with the host's visible silhouette.\n *\n * Source contributions:\n *   - CSS `border-*-width` (max across the 4 sides)\n *   - smallest `inset` `box-shadow` with spread > 0\n *   - smallest outset `box-shadow` with spread > 0\n */\nexport function readHairlineSpec(el: HTMLElement): { width: number; outerCssPx: number } {\n  const cs = getComputedStyle(el);\n  const borderMax = Math.max(\n    parseFloat(cs.borderTopWidth) || 0,\n    parseFloat(cs.borderRightWidth) || 0,\n    parseFloat(cs.borderBottomWidth) || 0,\n    parseFloat(cs.borderLeftWidth) || 0\n  );\n\n  let smallestInsetSpread = 0;\n  let smallestOutsetSpread = 0;\n  const shadow = cs.boxShadow;\n  if (shadow && shadow !== 'none') {\n    const safe = shadow.replace(/rgba?\\([^)]*\\)/g, (m) => m.replace(/,/g, '\\u0000'));\n    const parts = safe.split(/,\\s*/);\n    let inset = Infinity;\n    let outset = Infinity;\n    for (const part of parts) {\n      const nums = part.match(/-?\\d+(?:\\.\\d+)?px/g);\n      if (!nums || nums.length < 4) continue;\n      const spread = parseFloat(nums[3]);\n      if (!(spread > 0)) continue;\n      if (/\\binset\\b/.test(part)) {\n        if (spread < inset) inset = spread;\n      } else if (spread < outset) {\n        outset = spread;\n      }\n    }\n    if (Number.isFinite(inset)) smallestInsetSpread = inset;\n    if (Number.isFinite(outset)) smallestOutsetSpread = outset;\n  }\n\n  const outerCssPx = Math.max(borderMax, smallestOutsetSpread);\n  const width =\n    Math.max(borderMax, smallestInsetSpread, smallestOutsetSpread) || 1;\n\n  return { width, outerCssPx };\n}\n\nfunction refreshTargetStyles(t: ReflectionTarget): void {\n  t.cornerRadius = readCornerRadius(t.el);\n  const spec = readHairlineSpec(t.el);\n  t.hairlineWidth = spec.width;\n  t.hairlineOuterCssPx = spec.outerCssPx;\n}\n\nexport function attachObservers(t: ReflectionTarget): void {\n  if (typeof ResizeObserver !== 'undefined') {\n    t.resizeObserver = new ResizeObserver(() => refreshTargetStyles(t));\n    t.resizeObserver.observe(t.el);\n  }\n  if (typeof MutationObserver !== 'undefined') {\n    t.mutationObserver = new MutationObserver(() => refreshTargetStyles(t));\n    t.mutationObserver.observe(t.el, {\n      attributes: true,\n      attributeFilter: ['style', 'class'],\n    });\n  }\n}\n\nexport function detachObservers(t: ReflectionTarget): void {\n  t.resizeObserver?.disconnect();\n  t.resizeObserver = null;\n  t.mutationObserver?.disconnect();\n  t.mutationObserver = null;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/reflection/reflectionScheduler.ts",
          "target": "@components/effects/metal-fx/upstream/engine/reflection/reflectionScheduler.ts",
          "type": "registry:component",
          "content": "/**\n * Auxiliary RAF driver for *target-side* work (currently: dark-mode reflections).\n *\n * Reflections run at 15 fps — the CSS blur(4px) on the fill canvas hides\n * temporal stepping completely. The scheduler coalesces rapid calls and\n * skips frames that arrive faster than the target interval.\n */\nimport { REFLECTION_INTERVAL_MS } from '../perfConfig';\nimport { paintReflections } from './paint';\n\nlet scheduled = false;\nlet lastReflectionMs = 0;\n\nexport function scheduleReflectionPaint(): void {\n  if (scheduled) return;\n  scheduled = true;\n  if (typeof requestAnimationFrame === 'undefined') return;\n  requestAnimationFrame((now) => {\n    scheduled = false;\n    if (now - lastReflectionMs < REFLECTION_INTERVAL_MS) return;\n    lastReflectionMs = now;\n    paintReflections();\n  });\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/styles.ts",
          "target": "@components/effects/metal-fx/upstream/styles.ts",
          "type": "registry:component",
          "content": "const STYLE_ID = 'metal-fx-styles';\n\nconst CSS = /* css */ `\n.metal-fx-root {\n  position: relative;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  isolation: isolate;\n  overflow: visible;\n  background: #272727;\n  color: #f8f8f8;\n}\n.metal-fx-root[data-theme='light'] {\n  background: #ffffff;\n  color: #1d1d1d;\n}\n\n.metal-fx-root::before {\n  content: '';\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  pointer-events: none;\n  z-index: 2;\n  box-shadow: inset 0 0 50px 0 rgba(255, 255, 255, 0.02);\n}\n.metal-fx-root[data-theme='light']::before {\n  box-shadow: inset 0 0 50px 0 rgba(0, 0, 0, 0.02);\n}\n\n.metal-fx-root::after {\n  content: '';\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  pointer-events: none;\n  z-index: 4;\n  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);\n}\n.metal-fx-root[data-theme='light']::after {\n  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06);\n}\n/* Circle variant gets a thicker outer rim than the button variant. */\n.metal-fx-root[data-variant='circle']::after {\n  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.1);\n}\n.metal-fx-root[data-theme='light'][data-variant='circle']::after {\n  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.06);\n}\n\n.metal-fx-canvas {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  display: block;\n  z-index: 0;\n  pointer-events: none;\n  border-radius: inherit;\n}\n\n/* The inner spacer — defines the inset geometry where the metal ring meets\n   the interior (3 px for Button, 1-2 px for Circle) and carries the Circle dark\n   hairline ('box-shadow: inset' rules below). Intentionally transparent so\n   the wrapper's background propagates through to the punched shader centre,\n   giving consumers a single surface tone to override. See \"Single-surface\n   background\" in the file header for the rationale. */\n.metal-fx-inner {\n  position: absolute;\n  inset: 3px;\n  border-radius: inherit;\n  z-index: 1;\n  pointer-events: none;\n}\n\n.metal-fx-root[data-variant='button'][data-shape='pill'] .metal-fx-inner {\n  border-radius: calc(var(--mfx-radius, 20px) - 3px);\n}\n.metal-fx-root[data-variant='button'][data-shape='circle'] .metal-fx-inner {\n  border-radius: calc(var(--mfx-radius, 16px) - 3px);\n}\n.metal-fx-root[data-variant='circle'][data-shape='pill'] .metal-fx-inner {\n  inset: 0;\n  border-radius: var(--mfx-radius, 20px);\n  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45);\n}\n.metal-fx-root[data-variant='circle'][data-shape='circle'] .metal-fx-inner {\n  inset: 0;\n  border-radius: var(--mfx-radius, 16px);\n  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45);\n}\n/* Circle-variant hairline alpha — light mode.\n   Source-of-truth: index.html L2261-2267. The 0.45-alpha black inset that\n   reads as a single-pixel frame against the dark interior is too heavy\n   on a #ffffff inner: it ends up looking like a hard 2-px black ring\n   against the iridescent shader. Suppressed entirely (alpha 0) — the\n   shader's own iridescent rim already defines the silhouette in light\n   mode, so an extra dark hairline only competes with it. The rule is\n   kept (rather than deleted) as a tunable hook in case a future variant\n   wants to re-introduce a soft edge. NOTE: we keep the dark-mode inset\n   and border-radius values because — unlike index.html — our renderer\n   does NOT overscan the canvas in light mode, so there is no 1-px gap\n   between inner element and shader to compensate for. */\n.metal-fx-root[data-theme='light'][data-variant='circle'][data-shape='pill'] .metal-fx-inner,\n.metal-fx-root[data-theme='light'][data-variant='circle'][data-shape='circle'] .metal-fx-inner {\n  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0);\n}\n\n/* ─── Combined glow SVG (z=3) ──────────────────────────────────────────────\n   Single SVG per instance that holds BOTH the wide-halo group\n   (#mfx_haloTravel) and the catch-light group (#mfx_extraTravel), exactly\n   mirroring canonical's _buildGlowSvgInner (index.html L8078). One\n   mix-blend-mode: screen lifts the combined composite onto the shader\n   ring; per-frame opacity attributes on each inner group still drive the\n   independent fade-in / fade-out cycles for the halo and the catch-light.\n\n   Why a single SVG: the circle variant anchors halo + catch-light at the same\n   perimeter point, so they overlap in the bright zone. Two separately-\n   screened SVGs would double-screen the overlap (A + B + C - AB - AC -\n   BC + ABC instead of A + B + C - AB - AC once both groups composite\n   in source-over inside one SVG and then screen against the host once).\n   That overlap looked muted versus canonical specifically on the circle\n   variant where both layers travel together.\n\n   Source-of-truth opacity: #btnGlowSvg drops to 0.7 in dark and 0.2746 in\n   light (index.html L632/L643). */\n.metal-fx-glow-svg {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  overflow: visible;\n  z-index: 3;\n  pointer-events: none;\n  opacity: 0.7;\n}\n.metal-fx-root[data-theme='light'] .metal-fx-glow-svg {\n  /* Light-mode 1-px overscan mirrors .btn-glow-svg in metal.html so the\n     halo stays glued to the visible silhouette (the shader ring there sits\n     1 px outside the host's padding box). */\n  inset: -1px;\n  width: calc(100% + 2px);\n  height: calc(100% + 2px);\n  mix-blend-mode: multiply;\n  /* Source-of-truth: html[data-theme=\"light\"] #btnGlowSvg { opacity: 0.2746 }\n     → −35 % from 0.4225 from the original 0.7 dark-mode opacity. */\n  opacity: 0.2746;\n  filter: saturate(5.355) brightness(0.78);\n}\n/* Circle light-mode small variants (e.g. 36×36 send button): the geometrically\n   shrunk halo loses density when multiplied against #ffffff. Mirror the\n   canonical override at index.html L2316 — bump saturation + drop brightness\n   so the small glow holds together visually. */\n.metal-fx-root[data-variant='circle'][data-shape='circle'][data-theme='light'] .metal-fx-glow-svg {\n  filter: saturate(7.5) brightness(0.6);\n}\n\n/* The wrapped child — hoisted into z=5 so it sits above every overlay, with\n   normalized chrome so consumer button styles don't fight the metal frame. */\n.metal-fx-content {\n  position: relative;\n  z-index: 5;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 100%;\n  pointer-events: none;\n}\n.metal-fx-content > * {\n  pointer-events: auto;\n}\n.metal-fx-root[data-normalize='true'] .metal-fx-content > * {\n  background: transparent !important;\n  border: 0 !important;\n  outline: 0 !important;\n  box-shadow: none !important;\n  /* Sizing: we deliberately DO NOT force \\`width: 100%; height: 100%\\` on the\n     child here. That used to be the contract (\"the wrapper is the visible\n     button surface; the child stretches to fill it\"), but it created a cyclic\n     percentage dependency: the wrapper is \\`inline-flex\\` with no intrinsic\n     size, .metal-fx-content is \\`width/height: 100%\\` of the wrapper, and the\n     child was \\`100%\\` of .metal-fx-content. With nothing breaking the cycle,\n     icon-only / class-sized children collapsed.\n\n     The new contract: the child sizes itself (intrinsic content, CSS class,\n     or inline style — all work), and the wrapper's \\`inline-flex\\` wraps it\n     tightly. Consumers who want a metal frame BIGGER than the child (e.g.\n     padding around an icon) size <MetalFx style={{ width, height }}> AND\n     explicitly set width/height on the child to fill (or accept that the\n     child renders at its intrinsic size, centered).\n\n     Typography is intentionally NOT touched. We used to apply\n     \\`color: inherit; font: inherit;\\` here to \"match\" the wrapper, but\n     \\`font: inherit\\` is a shorthand that overrides font-family, font-size,\n     font-weight, AND line-height on the child — which (a) shrank the\n     button height (line-height changes propagate through the flex\n     content box) and (b) scaled em-based icons / font-icons inside the\n     child to whatever the wrapper inherited. The wrapper now stays out\n     of the child's typography entirely; consumers who want typographic\n     normalization can apply it themselves on the child element. */\n}\n\n[data-metal-fx-reflection] {\n  position: absolute;\n  inset: 0;\n  pointer-events: none;\n  border-radius: inherit;\n  overflow: hidden;\n  z-index: 0;\n  isolation: isolate;\n}\n.metal-fx-reflection-canvas {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  display: block;\n  filter: blur(4px) saturate(1.2) brightness(1.58);\n}\n.metal-fx-reflection-stroke-canvas {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  display: block;\n  filter: saturate(1.35) brightness(1.75);\n}\n/* Hosts that participate as reflection targets need positioning + isolation\n   so the wrap composites only against the host (not the parent stack). The\n   wrap injects these inline as well, but stating them here keeps reflections\n   working on hosts that already have other inline styles applied. */\n[data-metal-fx-reflect-host] {\n  isolation: isolate;\n}\n`;\n\nlet injected = false;\n\nexport function ensureStylesInjected(): void {\n  if (injected) return;\n  if (typeof document === 'undefined') return;\n  if (document.getElementById(STYLE_ID)) { injected = true; return; }\n  const style = document.createElement('style');\n  style.id = STYLE_ID;\n  style.textContent = CSS;\n  document.head.appendChild(style);\n  injected = true;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/types.ts",
          "target": "@components/effects/metal-fx/upstream/types.ts",
          "type": "registry:component",
          "content": "import type { CSSProperties, ReactNode, HTMLAttributes, RefObject } from 'react';\nimport type { MaskFn } from './engine/renderer/core';\n\n/**\n * Variant for the metal effect.\n * - 'button' (default): pill-shaped 134×40 baseline with shaderScale 1.6\n * - 'circle': compact 32×32 circle baseline with shaderScale 1.3\n *\n * In practice the wrapped child's measured dimensions drive the visible size —\n * the variant only controls the shader sampling scale and ring thickness.\n */\nexport type MetalFxVariant = 'button' | 'circle';\n\n/**\n * Theme mode for the metal effect.\n *\n * - `auto` (default): follows the user's `prefers-color-scheme` and updates\n *   live when the OS / browser theme changes (also gracefully falls back to\n *   `dark` during SSR or when `matchMedia` is unavailable).\n * - `dark`: pin to the dark-mode tunings regardless of system preference.\n * - `light`: pin to the light-mode tunings regardless of system preference.\n *\n * Drive this from your app's theme state if you have a manual toggle that\n * doesn't follow the OS — otherwise `auto` is the right default.\n */\nexport type MetalFxTheme = 'dark' | 'light' | 'auto';\n\n/**\n * Bundled preset names. Each preset ships both a dark and light mode block.\n */\nexport type MetalFxPreset = 'chromatic' | 'silver' | 'gold';\n\n/**\n * A reflection target: either a bare ref, or a ref plus a per-target\n * `strength` multiplier (0..1+). Use the object form when a surface should\n * only catch a faint echo of the metal — a container the button sits inside,\n * for example — without turning down every other target.\n */\nexport type MetalFxReflectionTarget =\n  | RefObject<HTMLElement | null>\n  | { ref: RefObject<HTMLElement | null>; strength?: number };\n\n/**\n * Props for the MetalFx React component.\n */\nexport interface MetalFxProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n  /**\n   * The single host element to wrap with the metal effect. Must be a single\n   * React node (button, anchor, div, ...). MetalFx measures this element each\n   * frame via `ResizeObserver` and paints its canvas + glow on top.\n   */\n  children: ReactNode;\n\n  /**\n   * Variant — controls the shader sampling scale + ring width.\n   * - `button` (default): pill-style ring at 1 px wide, scale 1.6\n   * - `circle`: compact circle with a 2 px ring, scale 1.3\n   */\n  variant?: MetalFxVariant;\n\n  /**\n   * Color preset. All three presets ship both dark and light mode tunings —\n   * `theme` picks the right side at runtime.\n   * @default 'chromatic'\n   */\n  preset?: MetalFxPreset;\n\n  /**\n   * Theme mode. `'auto'` (default) resolves via\n   * `matchMedia('(prefers-color-scheme: dark)')` and switches live when the\n   * OS theme changes. Pass `'dark'` or `'light'` to pin a specific mode.\n   * @default 'auto'\n   */\n  theme?: MetalFxTheme;\n\n  /**\n   * Effect strength (0..1). Multiplies the shader bitmap opacity and the glow\n   * SVG alpha. The shader continues to animate at full intensity at any value;\n   * only the rendered alpha onto the host is scaled. Lighter values let the\n   * underlying child surface show through more strongly.\n   * @default 1\n   */\n  strength?: number;\n\n  /**\n   * Multiplier on the glow only (halo + catch-light), on top of `strength`.\n   * Use it when the shader runs at low `strength` but the glow should still\n   * read — e.g. metal text. Clamped to 0..1 after multiplying.\n   * @default 1\n   */\n  glowGain?: number;\n\n  /**\n   * Pause the shader animation. The visible canvas keeps the last painted\n   * frame so the metal silhouette stays on screen.\n   * @default false\n   */\n  paused?: boolean;\n\n  /**\n   * Optional explicit border radius (CSS px). When omitted, MetalFx reads the\n   * computed border-radius of the wrapped child each resize.\n   */\n  borderRadius?: number;\n\n  /**\n   * When true, MetalFx normalizes the host element's outer chrome (border /\n   * outline / box-shadow) so user-provided component styles don't clash with\n   * the metal ring. Inner fills, typography, and content remain untouched.\n   * @default true\n   */\n  normalizeHostStyles?: boolean;\n\n  /**\n   * Neighbour elements that should receive a soft proximity reflection of the\n   * metal effect. Reflections only render when the resolved theme is `dark` —\n   * pass-through in light mode (no DOM scan, no per-frame work).\n   *\n   * Pass refs to the sibling DOM elements you want to receive the reflection\n   * (chips next to a send button, search field next to an Upgrade pill, ...).\n   *\n   * A target that *contains* the wrapped element (its parent card, say)\n   * receives the reflection on both the nearest vertical and horizontal\n   * inner edges. Pair with `{ ref, strength }` to keep that subtle.\n   */\n  reflectionTargets?: ReadonlyArray<MetalFxReflectionTarget>;\n\n  /**\n   * Disable the wandering halo overlay. The shader ring still renders.\n   * @default false\n   */\n  disableGlow?: boolean;\n\n  /**\n   * Light rim along the top inside edge of the ring — an inner shadow from\n   * above, like the one on metal text. `true` uses the design defaults\n   * (white 90 %, offset 1 px, blur 0.5 px); pass an object to tune.\n   * @default undefined (off)\n   */\n  innerShadow?: boolean | { offsetY?: number; blur?: number; alpha?: number; color?: string };\n\n  /**\n   * Override the shader sampling scale. Larger values zoom into the shared\n   * shader (visibly bigger pattern features); smaller values zoom out.\n   * Defaults to the variant's baseline (1.6 for `'button'`, 1.3 for\n   * `'circle'`) multiplied by `scale`.\n   */\n  shaderScale?: number;\n\n  /**\n   * Override the ring thickness in CSS pixels. Defaults to the variant's\n   * baseline (1 for `'button'`, 2 for `'circle'`) multiplied by `scale`.\n   */\n  ringCssPx?: number;\n\n  /**\n   * Master scale multiplier for every absolute-pixel constant the engine\n   * uses internally. Set this when you render the wrapped element at a\n   * non-1× size (e.g. inside a CSS `zoom: 2` container, or when you've\n   * doubled all your Tailwind sizes by hand). It scales:\n   *   - shader sampling (so pattern features grow proportionally)\n   *   - ring thickness on the canvas\n   *   - glow SVG stroke widths, blur radii, fade-circle radius, and the\n   *     small inset/outward offsets that position the catch-light\n   *   - reflection canvas stroke band, border-highlight thickness, and the\n   *     reference draw width baseline\n   * @default 1\n   */\n  scale?: number;\n\n  /**\n   * Custom alpha mask painter. When set, the shader is kept only where the\n   * mask paints (device px, origin at the wrapper's top-left) and the ring\n   * punch is skipped — for metal-filled text or glyphs. Pair with\n   * `disableGlow`; the glow assumes a ring perimeter.\n   */\n  mask?: MaskFn;\n\n  /**\n   * How the glow is placed when `mask` is set. `'mask'` (default) samples\n   * points inside the mask and clips the halo to it — right for metal text.\n   * `'ring'` keeps the rounded-rect perimeter behaviour — a halo along the\n   * element's edge — for a full-fill mask like a badge.\n   */\n  glowMode?: 'mask' | 'ring';\n\n  /**\n   * Forwarded class name for the wrapper element.\n   */\n  className?: string;\n\n  /**\n   * Forwarded inline styles for the wrapper element.\n   */\n  style?: CSSProperties;\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/MetalText.tsx",
          "target": "@components/effects/metal-fx/upstream/MetalText.tsx",
          "type": "registry:component",
          "content": "/**\n * Bare metal-filled text — the Pro badge's glyph treatment without the pill.\n * Figma: Portfolio › 1471:40925 (\"Plan Pro\" card).\n *\n * MetalFx's `mask` paints the word with the same font and metrics as the\n * live span, so layout and hit-testing stay DOM. The metal is composited\n * over the live text, so `color` is the tone the shader blends onto — the\n * design's own colour, not white. The canvas is lifted above the content\n * layer and the glow (clipped to the glyphs) above that.\n */\nimport React, { useCallback, useEffect, useRef, type CSSProperties } from 'react';\nimport { MetalFx } from './MetalFx';\nimport type { MetalFxReflectionTarget, MetalFxTheme } from './types';\nimport type { MaskFn } from './engine/renderer/core';\nimport { gaussBlur } from './engine/glow/bake';\nimport { paintTextRun } from './engine/textMask';\n\n/**\n * Figma inner shadow on the text (1471:40930): white 90 %, offset 0/1,\n * blur 0.5 — a hairline of light along the top inside edge of every glyph.\n * CSS has no inner shadow for text, so it's computed: glyph alpha minus the\n * same alpha shifted down by the offset leaves exactly that top rim, which is\n * then blurred and drawn white on an overlay above the metal.\n */\nexport interface TextInnerShadow { offsetY: number; blur: number; alpha: number }\nconst FIGMA_INNER_SHADOW: TextInnerShadow = { offsetY: 1, blur: 0.5, alpha: 0.9 };\n/** Tuned on the demo's \"Plan Pro\" card. */\nexport const METAL_TEXT_DEFAULTS = Object.freeze({ metalOpacity: 0.62, shaderScale: 2.8, glowGain: 2.5, innerShadow: FIGMA_INNER_SHADOW });\n\nfunction drawInnerShadow(cv: HTMLCanvasElement, root: HTMLElement, textEl: HTMLElement, sh: TextInnerShadow): void {\n  const dpr = window.devicePixelRatio || 1;\n  const rr = root.getBoundingClientRect();\n  const w = Math.max(1, Math.round(rr.width * dpr)), h = Math.max(1, Math.round(rr.height * dpr));\n  const off = document.createElement('canvas');\n  off.width = w; off.height = h;\n  const og = off.getContext('2d', { willReadFrequently: true });\n  const g = cv.getContext('2d');\n  if (!og || !g) return;\n  og.fillStyle = '#fff';\n  paintTextRun(og, root, textEl, dpr);\n  const d = og.getImageData(0, 0, w, h).data;\n  const n = w * h;\n  const a = new Float32Array(n);\n  for (let i = 0, j = 3; i < n; i++, j += 4) a[i] = d[j] / 255;\n  const shift = Math.max(1, Math.round(sh.offsetY * dpr)) * w;\n  const rim = new Float32Array(n);\n  for (let i = 0; i < n; i++) {\n    const above = i >= shift ? a[i - shift] : 0;\n    // Coverage the shifted glyph doesn't cover — the strip along the top\n    // edge. A difference, not a product: on anti-aliased side edges both\n    // values are partial and a product lit every edge of every glyph.\n    rim[i] = Math.max(0, a[i] - above);\n  }\n  const blurred = gaussBlur(rim, w, h, sh.blur * dpr);\n  cv.width = w; cv.height = h;\n  cv.style.width = `${rr.width}px`; cv.style.height = `${rr.height}px`;\n  const img = g.createImageData(w, h);\n  const o = img.data;\n  for (let i = 0, j = 0; i < n; i++, j += 4) {\n    o[j] = 255; o[j + 1] = 255; o[j + 2] = 255;\n    // Inner shadow: clipped to the glyph, so the blur never leaks outside\n    // the letterform (it read as a halo, worst when zoomed in).\n    o[j + 3] = Math.round(Math.min(1, blurred[i] * a[i] * sh.alpha) * 255);\n  }\n  g.putImageData(img, 0, 0);\n}\n\n// MetalFx dresses its root as a button: fill, inset rims (::before/::after)\n// and the inner hairline. Bare text wants none of that — only the glyphs.\nconst BARE_STYLE_ID = 'mfx-bare-style';\nconst BARE_CSS =\n  '.metal-fx-root[data-mfx-bare]{background:transparent!important}' +\n  '.metal-fx-root[data-mfx-bare]::before,.metal-fx-root[data-mfx-bare]::after{box-shadow:none!important}' +\n  '.metal-fx-root[data-mfx-bare] .metal-fx-inner{display:none!important}';\n\nexport function MetalText({\n  children,\n  font,\n  color,\n  strength = 1,\n  theme,\n  reflectionTargets,\n  className,\n  innerShadow = FIGMA_INNER_SHADOW,\n  glow = false,\n  glowGain = METAL_TEXT_DEFAULTS.glowGain,\n  metalOpacity = METAL_TEXT_DEFAULTS.metalOpacity,\n  shaderScale = METAL_TEXT_DEFAULTS.shaderScale,\n}: {\n  children: string;\n  /** CSS `font` shorthand for the live span, e.g. `500 24px/1 Inter, sans-serif`. */\n  font: string;\n  /** Base text colour from the design; the metal composites over it. */\n  color: string;\n  strength?: number;\n  theme?: MetalFxTheme;\n  reflectionTargets?: ReadonlyArray<MetalFxReflectionTarget>;\n  className?: string;\n  /** Top-edge light rim inside the glyphs. Pass null to disable. */\n  innerShadow?: TextInnerShadow | null;\n  /** Halo on the glyphs. Off by default — the design has none. */\n  glow?: boolean;\n  /** Glow multiplier when `glow` is on. */\n  glowGain?: number;\n  /** How much metal shows over the base colour (0..1), multiplied with `strength`. */\n  metalOpacity?: number;\n  /** Zoom of the metal inside the glyphs. */\n  shaderScale?: number;\n}) {\n  const rootRef = useRef<HTMLDivElement>(null);\n  const textRef = useRef<HTMLSpanElement>(null);\n  useEffect(() => {\n    if (!document.getElementById(BARE_STYLE_ID)) {\n      const st = document.createElement('style');\n      st.id = BARE_STYLE_ID;\n      st.textContent = BARE_CSS;\n      document.head.appendChild(st);\n    }\n    rootRef.current?.setAttribute('data-mfx-bare', '');\n    const cv = rootRef.current?.querySelector<HTMLCanvasElement>('canvas.metal-fx-canvas');\n    if (cv) cv.style.zIndex = '6';\n    const host = rootRef.current?.querySelector<HTMLElement>('.metal-fx-glow-svg')?.parentElement;\n    if (host) host.style.zIndex = '7';\n  }, []);\n\n  // Inner-shadow overlay: above the metal (6) and the glow (7), redrawn when\n  // fonts land or the box changes. Static otherwise.\n  useEffect(() => {\n    const root = rootRef.current, t = textRef.current;\n    if (!root || !t || !innerShadow) return;\n    const cv = document.createElement('canvas');\n    cv.className = 'metal-fx-text-rim';\n    cv.setAttribute('aria-hidden', 'true');\n    cv.style.cssText = 'position:absolute;left:0;top:0;pointer-events:none;z-index:8';\n    root.appendChild(cv);\n    const draw = () => drawInnerShadow(cv, root, t, innerShadow);\n    draw();\n    let alive = true;\n    document.fonts?.ready.then(() => { if (alive) draw(); });\n    const ro = new ResizeObserver(draw);\n    ro.observe(root);\n    // Browser zoom changes the DPR without changing the CSS box, so the\n    // ResizeObserver stays quiet; re-rasterise from a resolution query.\n    let mql: MediaQueryList | null = null;\n    const watchDpr = () => {\n      mql?.removeEventListener('change', onDpr);\n      mql = typeof window.matchMedia === 'function' ? window.matchMedia(`(resolution: ${window.devicePixelRatio || 1}dppx)`) : null;\n      mql?.addEventListener('change', onDpr);\n    };\n    const onDpr = () => { if (!alive) return; draw(); watchDpr(); };\n    watchDpr();\n    return () => { alive = false; ro.disconnect(); mql?.removeEventListener('change', onDpr); cv.remove(); };\n  }, [innerShadow]);\n\n  const mask = useCallback<MaskFn>((ctx, _w, _h, dpr) => {\n    const root = rootRef.current, t = textRef.current;\n    if (root && t) paintTextRun(ctx, root, t, dpr);\n  }, []);\n\n  const style: CSSProperties = { font, color, letterSpacing: 0, whiteSpace: 'nowrap' };\n\n  return (\n    <MetalFx\n      ref={rootRef}\n      preset=\"chromatic\"\n      theme={theme}\n      strength={strength * metalOpacity}\n      glowGain={glowGain}\n      disableGlow={!glow}\n      mask={mask}\n      reflectionTargets={reflectionTargets}\n      shaderScale={shaderScale}\n      borderRadius={4}\n      style={{ background: 'transparent', borderRadius: 4 }}\n    >\n      <span ref={textRef} className={className} style={style} aria-label={children}>\n        {children}\n      </span>\n    </MetalFx>\n  );\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/textMask.ts",
          "target": "@components/effects/metal-fx/upstream/engine/textMask.ts",
          "type": "registry:component",
          "content": "/**\n * Paint an element's text run onto a canvas with the DOM's own font and\n * metrics, so canvas glyphs land on the DOM glyphs to within a device px.\n * Shared by the Pro badge's metal fill and the text reflection mask.\n *\n * `ctx` is expected in device px with origin at `root`'s top-left; the\n * function scales by `dpr` internally.\n */\nexport function paintTextRun(\n  ctx: CanvasRenderingContext2D,\n  root: HTMLElement,\n  textEl: HTMLElement,\n  dpr: number\n): void {\n  const cs = getComputedStyle(textEl);\n  const rr = root.getBoundingClientRect();\n  const range = document.createRange();\n  range.selectNodeContents(textEl);\n  const tr = range.getBoundingClientRect();\n  range.detach();\n  ctx.save();\n  ctx.scale(dpr, dpr);\n  ctx.font = `${cs.fontStyle} ${cs.fontWeight} ${cs.fontSize} ${cs.fontFamily}`;\n  ctx.textAlign = 'left';\n  ctx.textBaseline = 'alphabetic';\n  const text = textEl.textContent ?? '';\n  const m = ctx.measureText(text);\n  const asc = m.fontBoundingBoxAscent ?? parseFloat(cs.fontSize) * 0.9;\n  const desc = m.fontBoundingBoxDescent ?? parseFloat(cs.fontSize) * 0.2;\n  const x = tr.left - rr.left;\n  const baseline = tr.top - rr.top + (tr.height - (asc + desc)) / 2 + asc;\n  ctx.fillText(text, x, baseline);\n  ctx.restore();\n}\n\n/** Render `textEl`'s glyphs white-on-transparent over `root`'s box → data URL. */\nexport function textMaskDataUrl(root: HTMLElement, textEl: HTMLElement): string | null {\n  const dpr = window.devicePixelRatio || 1;\n  const rr = root.getBoundingClientRect();\n  const c = document.createElement('canvas');\n  c.width = Math.max(1, Math.round(rr.width * dpr));\n  c.height = Math.max(1, Math.round(rr.height * dpr));\n  const g = c.getContext('2d');\n  if (!g) return null;\n  g.fillStyle = '#fff';\n  paintTextRun(g, root, textEl, dpr);\n  return c.toDataURL('image/png');\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/MetalBadge.tsx",
          "target": "@components/effects/metal-fx/upstream/MetalBadge.tsx",
          "type": "registry:component",
          "content": "/**\n * \"New\" badge — Figma: Portfolio › tab 3 (1458:40880), applied verbatim.\n *\n *   45×25, pill r 55.556. Layers bottom→top:\n *     1. white fill\n *     2. metal texture (a static PNG in Figma — here the live shader, via a\n *        full-pill mask so it covers the fill)\n *     3. gradient rgba(255,255,255,.6) → 0, top→bottom\n *     3b. clean white core under the label — transitions.dev get-pro-button\n *         mechanism inverted: radial ellipse 46%, solid to `core`, ramp over\n *         `coreBlur`, so the text sits on white and metal creeps in at the rim\n *     4. text: Inter Semi Bold 12.222/1.4 #323232, box 26.667×13.333\n *     5. inset shadows: 0 0 8.333 #fff ×2, 0 0 0 0.833 rgba(255,255,255,.5),\n *        0 0.833 0 rgba(255,255,255,.78)\n *\n * The gradient AND the inset shadows have to sit above the metal canvas\n * (z 0) and below the text (content z 5) — on the root they'd be painted\n * under the opaque metal and vanish. Both live on one overlay inside the\n * content layer, one level down: MetalFx normalises the *direct* child's\n * background/box-shadow to transparent/none, so the overlay is nested under\n * a plain wrapper to keep them.\n */\nimport React, { useCallback, useRef } from 'react';\nimport { MetalFx } from './MetalFx';\nimport type { MetalFxReflectionTarget, MetalFxTheme } from './types';\nimport type { MaskFn } from './engine/renderer/core';\n\nconst RADIUS = 55.556;\nconst W = 45, H = 25;\nconst TEXT_W = 26.667;\nconst PAD_X = (W - TEXT_W) / 2;\n\nconst LAYER: React.CSSProperties = { position: 'absolute', inset: 0, pointerEvents: 'none' };\n\n/** `glow` scales the two soft inner glows; the hairline rims stay as designed. */\nconst shadowFor = (k: number, glow: number) =>\n  `inset 0px 0px ${8.333 * k}px 0px rgba(255,255,255,${glow}), ` +\n  `inset 0px 0px ${8.333 * k}px 0px rgba(255,255,255,${glow}), ` +\n  `inset 0px 0px 0px ${0.833 * k}px rgba(255,255,255,0.5), ` +\n  `inset 0px ${0.833 * k}px 0px 0px rgba(255,255,255,0.78)`;\n\n/** Tuned on the demo's \"Live mode · New\" card. */\nexport const METAL_BADGE_DEFAULTS = Object.freeze({\n  metalOpacity: 0.8,\n  shaderScale: 1.6,\n  /** White core under the label: solid radius (% of ellipse), ramp width, opacity, ellipse size (% of box). */\n  core: Object.freeze({ r: 46, blur: 100, a: 0.94, size: 49 }),\n  gradient: 0,\n  glow: 0.41,\n});\n\nexport interface MetalBadgeCore { r: number; blur: number; a: number; size: number }\n\nexport function MetalBadge({\n  children = 'New',\n  strength = 1,\n  theme,\n  scale = 1,\n  reflectionTargets,\n  metalOpacity = METAL_BADGE_DEFAULTS.metalOpacity,\n  shaderScale = METAL_BADGE_DEFAULTS.shaderScale,\n  core = METAL_BADGE_DEFAULTS.core,\n  gradient = METAL_BADGE_DEFAULTS.gradient,\n  glow = METAL_BADGE_DEFAULTS.glow,\n  textColor = '#323232',\n}: {\n  children?: string;\n  strength?: number;\n  theme?: MetalFxTheme;\n  /** Size multiplier on the Figma metrics (45×25, 12.222px). */\n  scale?: number;\n  reflectionTargets?: ReadonlyArray<MetalFxReflectionTarget>;\n  /** How much metal shows over the white fill (0..1), multiplied with `strength`. */\n  metalOpacity?: number;\n  shaderScale?: number;\n  core?: MetalBadgeCore;\n  /** Top→bottom white wash strength (0..1). */\n  gradient?: number;\n  /** Inner white glow strength (0..1). */\n  glow?: number;\n  textColor?: string;\n}) {\n  const rootRef = useRef<HTMLDivElement>(null);\n  const opacity = metalOpacity;\n\n  // Full-fill mask: the pill itself.\n  const mask = useCallback<MaskFn>((ctx, w, h, dpr) => {\n    ctx.beginPath();\n    ctx.roundRect(0, 0, w, h, RADIUS * dpr);\n    ctx.fill();\n  }, []);\n\n  return (\n    <MetalFx\n      ref={rootRef}\n      preset=\"chromatic\"\n      theme={theme}\n      strength={strength * opacity}\n      shaderScale={shaderScale}\n      mask={mask}\n      glowMode=\"ring\"\n      reflectionTargets={reflectionTargets}\n      borderRadius={RADIUS * scale}\n      style={{ background: '#ffffff', borderRadius: RADIUS * scale }}\n    >\n      {/* Inline layout only — no utility classes, so the badge renders the\n          same with or without a CSS framework on the host page. */}\n      <div style={{ position: 'relative', width: W * scale, height: H * scale, borderRadius: RADIUS * scale }}>\n        {/* layer 3b — clean white core under the label (rim-only metal) */}\n        <div\n          aria-hidden=\"true\"\n          style={{\n            ...LAYER,\n            borderRadius: RADIUS * scale,\n            // Stops are relative to the ellipse radius, so 100% = its edge.\n            background: `radial-gradient(ellipse ${core.size}% ${core.size}% at 50% 50%, rgba(255,255,255,1) ${core.r}%, rgba(255,255,255,0) ${Math.min(100, core.r + core.blur)}%)`,\n            opacity: core.a,\n          }}\n        />\n        {/* layers 3 + 5 — white gradient and inset rims, over the metal */}\n        <div\n          aria-hidden=\"true\"\n          style={{\n            ...LAYER,\n            borderRadius: RADIUS * scale,\n            background: `linear-gradient(to bottom, rgba(255,255,255,${gradient}), rgba(255,255,255,0))`,\n            boxShadow: shadowFor(scale, glow),\n          }}\n        />\n        <span\n          style={{\n            position: 'relative',\n            display: 'flex',\n            alignItems: 'center',\n            justifyContent: 'center',\n            boxSizing: 'border-box',\n            width: W * scale,\n            height: H * scale,\n            paddingLeft: PAD_X * scale,\n            paddingRight: PAD_X * scale,\n            font: `600 ${12.222 * scale}px/1.4 Inter, sans-serif`,\n            color: textColor,\n            letterSpacing: 0,\n            whiteSpace: 'nowrap',\n          }}\n          aria-label={children}\n        >\n          {children}\n        </span>\n      </div>\n    </MetalFx>\n  );\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/useMetalBend.ts",
          "target": "@components/effects/metal-fx/upstream/useMetalBend.ts",
          "type": "registry:component",
          "content": "import { useEffect, type RefObject } from 'react';\nimport { redrawInstance, setInstanceDeform } from './engine/renderer/loop';\nimport type { DeformLayers } from './engine/renderer/core';\nimport { BEND, type BendConfig } from './engine/bend/config';\n\n/**\n * Cursor-driven local deformation (\"liquid dent\") for a MetalFx root.\n *\n * Field\n * ─────\n * Two gaussian blobs centred at `c` (which lags the cursor by `follow`):\n *   • directional: `amp · g_bend(r)` — a 2-D spring chasing the cursor's\n *     smoothed velocity × gain, so motion toward the centre pushes the ring\n *     in and motion away drags it out; recoils on release.\n *   • liquid: `(p − c)/σ · g_liq(r) · la` — the gradient of a bump, i.e. a\n *     divergent push away from the contact point. This term *stretches*\n *     material rather than sliding it, so the stroke thins under the cursor\n *     and thickens either side. `la` is its own slower spring; pressure is 1\n *     with the cursor on the ring, fading over `liquidReach`.\n *\n * Two render paths, chosen by `applyTo`:\n *\n * `ring` — vector. The engine masks the ring with a rounded-rect outline it\n * traces every frame; we hand it a `DeformFn` that displaces those outline\n * points, plus the fill / rim / hairline that normally live on CSS boxes so\n * they bend along. Edges stay anti-aliased at any stretch. The instance is\n * redrawn from here at the pointer's frame rate, since the shared loop only\n * composites at 15 fps.\n *\n * `all` — SVG `feDisplacementMap` on the whole root. Bends the content too,\n * but the sampler duplicates source pixels where material is stretched, so\n * quality degrades with amplitude. Kept for comparison.\n */\nexport function useMetalBend(ref: RefObject<HTMLElement | null>, getCfg: () => BendConfig = () => BEND): void {\n  useEffect(() => {\n    const el = ref.current;\n    if (!el || typeof document === 'undefined') return;\n\n    const ring = el.querySelector<HTMLCanvasElement>('canvas.metal-fx-canvas');\n    const inner = el.querySelector<HTMLElement>('.metal-fx-inner');\n\n    // ── shared field state ──────────────────────────────────────────\n    let pointer: { x: number; y: number } | null = null;\n    let lastPointer: { x: number; y: number; t: number } | null = null;\n    let pressed = false;\n    let active = false;\n    let cx = 0, cy = 0;          // blob centre, element-local px\n    let ax = 0, ay = 0;          // directional displacement (px)\n    let vax = 0, vay = 0;\n    let la = 0, vla = 0;         // liquid amplitude\n    let stx = 0, sty = 0, stl = 0; // low-passed targets (see smoothMs)\n    let pressure = 0;\n    let env = 0;                 // hover envelope 0..1 — no pops on enter/leave\n    let svx = 0, svy = 0;        // smoothed cursor velocity, px/s\n    let raf = 0, last = 0;\n    // Redraw gate: physics integrates at display rate, but the canvas +\n    // glow-mask rebuild is capped at 60 fps and skipped when nothing moved\n    // more than 0.05 px — on a 120 Hz display that halves the bend's cost.\n    let drawT = 0, dAx = NaN, dAy = NaN, dLa = NaN, dCx = NaN, dCy = NaN;\n\n    // Per-frame constants for the field evaluators.\n    let fDirX = 0, fDirY = 0, fRadK = 0, fS2b = 1, fS2l = 1;\n    const evalField = (x: number, y: number, out: { x: number; y: number }) => {\n      const dx = x - cx, dy = y - cy;\n      const q = dx * dx + dy * dy;\n      const gb = Math.exp(-q / fS2b);\n      const gl = Math.exp(-q / fS2l);\n      out.x = fDirX * gb + dx * fRadK * gl;\n      out.y = fDirY * gb + dy * fRadK * gl;\n    };\n    const _f = { x: 0, y: 0 };\n    const deform = (x: number, y: number, out: { x: number; y: number }) => {\n      evalField(x, y, _f);\n      out.x = x + _f.x;\n      out.y = y + _f.y;\n    };\n\n    // ── vector path (ring mode) ─────────────────────────────────────\n    const STYLE_ID = 'mfx-bend-style';\n    if (!document.getElementById(STYLE_ID)) {\n      const st = document.createElement('style');\n      st.id = STYLE_ID;\n      st.textContent = '.metal-fx-root[data-mfx-bend]::before,.metal-fx-root[data-mfx-bend]::after{box-shadow:none!important}';\n      document.head.appendChild(st);\n    }\n    let vectorOn = false;\n    let layers: DeformLayers | null = null;\n    const prevRootBg = el.style.background;\n    const prevInnerVis = inner?.style.visibility ?? '';\n\n    /** \"rgba(…) 0px 0px 0px 2px inset\" → { color, spread } for the first shadow. */\n    const parseShadow = (v: string): { color: string; spread: number } | null => {\n      if (!v || v === 'none') return null;\n      const m = v.match(/^(rgba?\\([^)]*\\)|#[0-9a-fA-F]+|[a-z]+)\\s+(-?[\\d.]+)px\\s+(-?[\\d.]+)px\\s+(-?[\\d.]+)px\\s+(-?[\\d.]+)px/);\n      if (!m) return null;\n      return { color: m[1], spread: Math.abs(parseFloat(m[5])) };\n    };\n    const vectorStart = (overscan: number) => {\n      if (vectorOn || !ring) return;\n      const rim = parseShadow(getComputedStyle(el, '::after').boxShadow);\n      const hair = inner ? parseShadow(getComputedStyle(inner).boxShadow) : null;\n      const innerInset = inner ? parseFloat(getComputedStyle(inner).inset) || 0 : 0;\n      layers = {\n        fill: getComputedStyle(el).backgroundColor,\n        rim: rim && rim.spread > 0 ? { inset: 0, width: rim.spread, color: rim.color } : null,\n        hairline: hair && hair.spread > 0 ? { inset: innerInset, width: hair.spread, color: hair.color } : null,\n      };\n      el.style.background = 'transparent';\n      el.setAttribute('data-mfx-bend', '');\n      if (inner) inner.style.visibility = 'hidden';\n      setInstanceDeform(ring, deform, layers, overscan);\n      vectorOn = true;\n    };\n    const vectorStop = () => {\n      if (!vectorOn || !ring) return;\n      setInstanceDeform(ring, null, null, 0);\n      el.style.background = prevRootBg;\n      el.removeAttribute('data-mfx-bend');\n      if (inner) inner.style.visibility = prevInnerVis;\n      vectorOn = false;\n    };\n\n    // ── filter path (all mode) ──────────────────────────────────────\n    const id = `mfx-bend-${Math.random().toString(36).slice(2, 8)}`;\n    const NS = 'http://www.w3.org/2000/svg';\n    const REGION = 0.75;\n    const svg = document.createElementNS(NS, 'svg');\n    svg.setAttribute('aria-hidden', 'true');\n    svg.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden;pointer-events:none';\n    const filter = document.createElementNS(NS, 'filter');\n    filter.setAttribute('id', id);\n    filter.setAttribute('x', `-${REGION * 100}%`); filter.setAttribute('y', `-${REGION * 100}%`);\n    filter.setAttribute('width', `${(1 + 2 * REGION) * 100}%`); filter.setAttribute('height', `${(1 + 2 * REGION) * 100}%`);\n    filter.setAttribute('color-interpolation-filters', 'sRGB');\n    const feFlood = document.createElementNS(NS, 'feFlood');\n    feFlood.setAttribute('flood-color', 'rgb(128,128,0)');\n    feFlood.setAttribute('flood-opacity', '1');\n    feFlood.setAttribute('result', 'neutral');\n    const feImage = document.createElementNS(NS, 'feImage');\n    feImage.setAttribute('result', 'img');\n    feImage.setAttribute('preserveAspectRatio', 'none');\n    const feComp = document.createElementNS(NS, 'feComposite');\n    feComp.setAttribute('in', 'img'); feComp.setAttribute('in2', 'neutral');\n    feComp.setAttribute('operator', 'over'); feComp.setAttribute('result', 'map');\n    const feDisp = document.createElementNS(NS, 'feDisplacementMap');\n    feDisp.setAttribute('in', 'SourceGraphic'); feDisp.setAttribute('in2', 'map');\n    feDisp.setAttribute('xChannelSelector', 'R'); feDisp.setAttribute('yChannelSelector', 'G');\n    feDisp.setAttribute('result', 'bent');\n    const feSmooth = document.createElementNS(NS, 'feGaussianBlur');\n    feSmooth.setAttribute('in', 'bent'); feSmooth.setAttribute('stdDeviation', '0');\n    for (const n of [feFlood, feImage, feComp, feDisp, feSmooth]) filter.appendChild(n);\n    svg.appendChild(filter);\n    document.body.appendChild(svg);\n\n    const map = document.createElement('canvas');\n    const mctx = map.getContext('2d', { alpha: false, willReadFrequently: true });\n    let img: ImageData | null = null;\n    let img32: Uint32Array | null = null;\n    const NEUTRAL = 0xff008080;\n    let filterOn = false;\n    const prevFilter = el.style.filter;\n    const filterStop = () => {\n      if (!filterOn) return;\n      el.style.filter = prevFilter;\n      filterOn = false;\n    };\n    const filterFrame = (cfg: BendConfig, W: number, H: number, scale: number) => {\n      if (!mctx) return;\n      const res = Math.max(0.25, cfg.mapRes);\n      const mx = -W * REGION, my = -H * REGION, mw = W * (1 + 2 * REGION), mh = H * (1 + 2 * REGION);\n      const pw = Math.max(2, Math.round(mw * res)), ph = Math.max(2, Math.round(mh * res));\n      if (map.width !== pw || map.height !== ph || !img || !img32) {\n        map.width = pw; map.height = ph;\n        img = mctx.createImageData(pw, ph);\n        img32 = new Uint32Array(img.data.buffer);\n      }\n      img32.fill(NEUTRAL);\n      const data = img.data;\n      const ext = 3 * Math.max(cfg.blob, cfg.liquidBlob);\n      const px0 = Math.max(0, Math.floor((cx - ext - mx) * res));\n      const px1 = Math.min(pw - 1, Math.ceil((cx + ext - mx) * res));\n      const py0 = Math.max(0, Math.floor((cy - ext - my) * res));\n      const py1 = Math.min(ph - 1, Math.ceil((cy + ext - my) * res));\n      const inv = 255 / scale;\n      for (let py = py0; py <= py1; py++) {\n        const y = my + (py + 0.5) / res;\n        let i = (py * pw + px0) * 4;\n        for (let px = px0; px <= px1; px++, i += 4) {\n          const x = mx + (px + 0.5) / res;\n          evalField(x, y, _f);\n          let r = 127.5 - _f.x * inv; r = r < 0 ? 0 : r > 255 ? 255 : r;\n          let g = 127.5 - _f.y * inv; g = g < 0 ? 0 : g > 255 ? 255 : g;\n          data[i] = r; data[i + 1] = g;\n        }\n      }\n      mctx.putImageData(img, 0, 0);\n      feImage.setAttribute('x', mx.toFixed(2)); feImage.setAttribute('y', my.toFixed(2));\n      feImage.setAttribute('width', mw.toFixed(2)); feImage.setAttribute('height', mh.toFixed(2));\n      feImage.setAttribute('href', map.toDataURL('image/png'));\n      feDisp.setAttribute('scale', scale.toFixed(2));\n      feSmooth.setAttribute('stdDeviation', Math.max(0, cfg.smooth).toFixed(3));\n      if (!filterOn) { el.style.filter = `url(#${id})`; filterOn = true; }\n    };\n\n    // ── simulation ──────────────────────────────────────────────────\n    const kick = () => {\n      if (raf !== 0) return;\n      last = performance.now();\n      raf = requestAnimationFrame(step);\n    };\n\n    const step = (now: number) => {\n      raf = 0;\n      const cfg = getCfg();\n      const dt = Math.min(0.032, Math.max(0.001, (now - last) / 1000));\n      last = now;\n\n      const r = el.getBoundingClientRect();\n      const W = r.width, H = r.height;\n      const ecx = W / 2, ecy = H / 2;\n\n      let tx = 0, ty = 0;\n      pressure = 0;\n      if (cfg.enabled && pointer) {\n        const lx = pointer.x - r.left, ly = pointer.y - r.top;\n        const ddx = lx - ecx, ddy = ly - ecy;\n        const d = Math.hypot(ddx, ddy);\n        const R = Math.min(W, H) / 2;\n        const reach = Math.max(W, H) / 2 + cfg.reach;\n        const wasActive = active;\n        active = d < reach;\n        const u = Math.max(0, 1 - Math.abs(d - R) / Math.max(1, cfg.liquidReach));\n        pressure = u * u * (3 - 2 * u);\n        if (active) {\n          if (!wasActive) { cx = lx; cy = ly; }\n          // `follow` is defined per 60 Hz frame; convert to this frame's dt.\n          const fa = 1 - Math.pow(1 - Math.min(0.999, cfg.follow), dt * 60);\n          cx += (lx - cx) * fa;\n          cy += (ly - cy) * fa;\n          const edgeFade = 1 - Math.max(0, (d - (reach - cfg.reach)) / cfg.reach);\n          // Transient kick from cursor speed.\n          tx = svx * (cfg.gain / 100) * edgeFade;\n          ty = svy * (cfg.gain / 100) * edgeFade;\n          // Position-based, so the dent holds while the cursor sits there.\n          // Inside the edge: press toward the centre by penetration.\n          // Outside: pull toward the cursor, fading to zero at reach.\n          const ux = d > 0.001 ? ddx / d : 0, uy = d > 0.001 ? ddy / d : 0;\n          const pen = R - d;\n          if (pen > 0) {\n            const m = pen * cfg.pressGain;\n            tx -= ux * m; ty -= uy * m;\n          } else {\n            const out = -pen;\n            const f = Math.max(0, 1 - out / Math.max(1, cfg.reach));\n            const m = out * cfg.pullGain * (f * f * (3 - 2 * f));\n            tx += ux * m; ty += uy * m;\n          }\n          const tm = Math.hypot(tx, ty);\n          if (tm > cfg.maxDisp) { tx *= cfg.maxDisp / tm; ty *= cfg.maxDisp / tm; }\n        }\n      } else {\n        active = false;\n      }\n      svx *= Math.exp(-dt * 12); svy *= Math.exp(-dt * 12);\n\n      // Low-pass the targets. Springs then chase a smooth signal instead of a\n      // stepping one — the stepping is what read as \"unnatural\" on fast sweeps.\n      const sa = 1 - Math.exp(-(dt * 1000) / Math.max(1, cfg.smoothMs));\n      stx += (tx - stx) * sa;\n      sty += (ty - sty) * sa;\n\n      const m = Math.max(0.05, cfg.mass);\n      vax += ((-cfg.stiffness * (ax - stx) - cfg.damping * vax) / m) * dt;\n      vay += ((-cfg.stiffness * (ay - sty) - cfg.damping * vay) / m) * dt;\n      ax += vax * dt; ay += vay * dt;\n\n      const pressAmt = pressed && active && cfg.enabled ? cfg.press : 0;\n      const tl = active && cfg.enabled ? cfg.liquid * (pressure + (pressed ? 0.5 : 0)) : 0;\n      stl += (tl - stl) * sa;\n      vla += ((-cfg.liquidStiffness * (la - stl) - cfg.liquidDamping * vla) / m) * dt;\n      la += vla * dt;\n\n      // Envelope: exponential approach, ~95% of the way by fadeIn/OutMs.\n      const envTarget = active && cfg.enabled ? 1 : 0;\n      const tauMs = Math.max(1, envTarget ? cfg.fadeInMs : cfg.fadeOutMs) / 3;\n      env += (envTarget - env) * (1 - Math.exp(-(dt * 1000) / tauMs));\n      if (env < 0.002 && envTarget === 0) env = 0;\n\n      const amp = Math.hypot(ax, ay);\n      const idle = !active && env === 0 && amp < 0.05 && Math.hypot(vax, vay) < 1 && Math.abs(la) < 0.05 && pressAmt === 0;\n\n      // Mode switch releases whichever path was active.\n      if (cfg.applyTo === 'ring') filterStop(); else vectorStop();\n\n      if (idle) {\n        ax = ay = vax = vay = la = vla = 0;\n        stx = sty = stl = 0;\n        dAx = dAy = dLa = dCx = dCy = NaN;\n        vectorStop();\n        filterStop();\n        return;\n      }\n\n      // Field constants for this frame. The envelope scales the whole field.\n      const k = Math.max(0, cfg.strength) * env;\n      let pdx = ecx - cx, pdy = ecy - cy;\n      const pl = Math.hypot(pdx, pdy) || 1; pdx /= pl; pdy /= pl;\n      const sb = Math.max(0.5, cfg.blob), sl = Math.max(0.5, cfg.liquidBlob);\n      fS2b = 2 * sb * sb; fS2l = 2 * sl * sl;\n      fDirX = (ax + pdx * pressAmt) * k;\n      fDirY = (ay + pdy * pressAmt) * k;\n      fRadK = (la / sl) * k;\n\n      const moved = !(Math.abs(ax - dAx) < 0.05 && Math.abs(ay - dAy) < 0.05 && Math.abs(la - dLa) < 0.05 &&\n                      Math.abs(cx - dCx) < 0.05 && Math.abs(cy - dCy) < 0.05);\n      const due = now - drawT >= 1000 / 60 - 0.5;\n      if (moved && due) {\n        drawT = now; dAx = ax; dAy = ay; dLa = la; dCx = cx; dCy = cy;\n        if (cfg.applyTo === 'ring' && ring) {\n          // Overscan budget: the furthest any point can travel.\n          const reachPx = Math.ceil((cfg.maxDisp + cfg.liquid * 1.5) * Math.max(1, cfg.strength)) + 4;\n          vectorStart(reachPx);\n          redrawInstance(ring);\n        } else {\n          const scale = Math.max(1, (cfg.maxDisp + cfg.liquid * 1.5) * 2 * Math.max(1, cfg.strength));\n          filterFrame(cfg, W, H, scale);\n        }\n      } else if (cfg.applyTo === 'ring' && ring && !vectorOn) {\n        vectorStart(Math.ceil((cfg.maxDisp + cfg.liquid * 1.5) * Math.max(1, cfg.strength)) + 4);\n      }\n\n      raf = requestAnimationFrame(step);\n    };\n\n    const onMove = (e: PointerEvent) => {\n      const now = performance.now();\n      if (lastPointer) {\n        const dt = Math.max(0.004, (now - lastPointer.t) / 1000);\n        // ~40 ms time constant regardless of event rate.\n        const a = 1 - Math.exp(-dt / 0.04);\n        svx += ((e.clientX - lastPointer.x) / dt - svx) * a;\n        svy += ((e.clientY - lastPointer.y) / dt - svy) * a;\n      }\n      lastPointer = { x: e.clientX, y: e.clientY, t: now };\n      pointer = { x: e.clientX, y: e.clientY };\n      kick();\n    };\n    const onLeave = () => { pointer = null; lastPointer = null; kick(); };\n    const onDown = () => { pressed = true; kick(); };\n    const onUp = () => { pressed = false; kick(); };\n\n    document.addEventListener('pointermove', onMove, { passive: true });\n    document.addEventListener('pointerleave', onLeave);\n    window.addEventListener('blur', onLeave);\n    el.addEventListener('pointerdown', onDown);\n    document.addEventListener('pointerup', onUp);\n    document.addEventListener('pointercancel', onUp);\n\n    return () => {\n      if (raf !== 0) cancelAnimationFrame(raf);\n      document.removeEventListener('pointermove', onMove);\n      document.removeEventListener('pointerleave', onLeave);\n      window.removeEventListener('blur', onLeave);\n      el.removeEventListener('pointerdown', onDown);\n      document.removeEventListener('pointerup', onUp);\n      document.removeEventListener('pointercancel', onUp);\n      vectorStop();\n      filterStop();\n      if (svg.parentNode) svg.parentNode.removeChild(svg);\n    };\n  }, [ref, getCfg]);\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/engine/bend/config.ts",
          "target": "@components/effects/metal-fx/upstream/engine/bend/config.ts",
          "type": "registry:component",
          "content": "/**\n * Live config for the cursor \"bend\" effect — a local liquid dent.\n *\n * The cursor carries a blob of displacement that rides the ring: moving\n * toward the button's centre dents the edge inward, moving away drags it\n * outward, and on release the bulge springs back. Implemented as an SVG\n * `feDisplacementMap` over the whole MetalFx root (button, ring, glow), with\n * the vector field regenerated each frame into a small canvas.\n *\n * Mutable singleton, read every frame by `useBend`.\n */\nexport interface BendConfig {\n  enabled: boolean;\n  /** What deforms. `ring` = the metal canvas only; button content and glow\n   *  stay rigid. `all` = the whole MetalFx root. */\n  applyTo: 'ring' | 'all';\n  /** Global amplitude multiplier on the whole displacement field. */\n  strength: number;\n  /** Time for the effect to ease in after the cursor arrives, ms. Without\n   *  this the directional spring lands the dent in 2–3 frames — a pop. */\n  fadeInMs: number;\n  /** Time for the effect to ease out after the cursor leaves, ms. */\n  fadeOutMs: number;\n  /** Low-pass on the field's *target* before the spring sees it, ms. A fast\n   *  sweep across the ring flips press→pull and swings the direction vector\n   *  within a frame; this keeps the dent from snapping to each new target. */\n  smoothMs: number;\n  /** How far beyond the element's edge the cursor is still felt, CSS px. */\n  reach: number;\n  /** Area of the directional bend (gaussian σ), CSS px. */\n  blob: number;\n  /** Area of the liquid push (gaussian σ), CSS px. Independent of `blob`. */\n  liquidBlob: number;\n  /** Displacement cap, CSS px. Also sets the filter's `scale`. */\n  maxDisp: number;\n  /** Displacement px produced per 100 px/s of cursor speed — a transient\n   *  kick on fast moves. 0 disables. */\n  gain: number;\n  /** Position-based press: dent px per px the cursor sits inside the ring's\n   *  edge, pushing toward the centre. Holds while the cursor stays. */\n  pressGain: number;\n  /** Position-based pull: bulge px per px the cursor sits outside the edge\n   *  (within `reach`), dragging the ring toward the cursor — the sticky part. */\n  pullGain: number;\n  /** Extra inward dent (toward element centre) while pressed, px. */\n  press: number;\n  /** Radial push away from the contact point, px at full pressure. This is\n   *  the divergent part of the field — it *stretches* material rather than\n   *  sliding it, so the stroke thins under the cursor and bulges around it.\n   *  Pressure is 1 with the cursor on the ring, fading to 0 at `reach`. */\n  liquid: number;\n  /** Distance from the ring (either side) over which liquid pressure fades\n   *  to zero, px. Keep this small — a large value lets a cursor sitting\n   *  inside the button push the whole ring outward, which reads as a scale. */\n  liquidReach: number;\n  /** Spring constant for the liquid push. Lower = slower swell. */\n  liquidStiffness: number;\n  /** Damping for the liquid push. Below 2·√k it overshoots on release. */\n  liquidDamping: number;\n  /** Spring on the displacement vector — snap back speed. */\n  stiffness: number;\n  /** Below 2·√(k·m) the surface wobbles after release. */\n  damping: number;\n  mass: number;\n  /** Blob-centre tracking, as a per-frame lerp at 60 Hz (0..1); applied\n   *  time-based so 120 Hz pointers don't track twice as hard. Lower = the\n   *  blob lags and stretches behind the cursor — stickier. */\n  follow: number;\n  /** Map resolution multiplier. 1 = one texel per CSS px, 2 = device parity\n   *  on a 2× display. Steps in the field are visible below device parity. */\n  mapRes: number;\n  /** Post-displacement blur, CSS px. `feDisplacementMap` samples the source\n   *  nearest-neighbour, which shows as stepping where material is stretched;\n   *  a quarter-pixel blur hides it. 0 disables. */\n  smooth: number;\n}\n\nexport const BEND_DEFAULTS: Readonly<BendConfig> = Object.freeze({\n  enabled: true,\n  applyTo: 'ring',\n  strength: 0.74,\n  fadeInMs: 200,\n  fadeOutMs: 350,\n  smoothMs: 140,\n  reach: 36,\n  blob: 13,\n  liquidBlob: 10,\n  maxDisp: 9,\n  gain: 0.6,\n  pressGain: 0.55,\n  pullGain: 0.49,\n  press: 5,\n  liquid: 7.5,\n  liquidReach: 8,\n  liquidStiffness: 53,\n  liquidDamping: 9,\n  stiffness: 260,\n  damping: 13,\n  mass: 1,\n  follow: 0.32,\n  mapRes: 2,\n  smooth: 0.25,\n});\n\nexport const BEND: BendConfig = { ...BEND_DEFAULTS };\n\nexport function setBendConfig(patch: Partial<BendConfig>): void {\n  Object.assign(BEND, patch);\n}\n\nexport function resetBendConfig(): void {\n  Object.assign(BEND, BEND_DEFAULTS);\n}\n"
        },
        {
          "path": "components/effects/metal-fx/upstream/useMetalTextReflection.ts",
          "target": "@components/effects/metal-fx/upstream/useMetalTextReflection.ts",
          "type": "registry:component",
          "content": "import { useEffect, type RefObject } from 'react';\nimport { textMaskDataUrl } from './engine/textMask';\n\n/**\n * Confine a proximity reflection to an element's glyphs.\n *\n * The engine paints reflections into a wrapper it inserts inside the target\n * (`[data-metal-fx-reflection]`, canvases inset:0). For a text node that\n * would light the whole line box and stroke its rectangle. This masks the\n * wrapper with the text rendered white-on-transparent, so only the\n * letterforms catch the light. Re-rendered on resize and once fonts load.\n */\nexport function useMetalTextReflection(ref: RefObject<HTMLElement | null>): void {\n  useEffect(() => {\n    const el = ref.current;\n    if (!el) return;\n    // Tells the engine to light this as letterforms, not as a chip: mirrored\n    // metal only, no rim stroke / border highlight.\n    el.setAttribute('data-metal-fx-text', '');\n    let raf = 0;\n    let disposed = false;\n    let tries = 0;\n\n    const apply = () => {\n      if (disposed) return;\n      const wrap = el.querySelector<HTMLElement>(':scope > [data-metal-fx-reflection]');\n      // Engine attaches the wrapper after mount (and only in dark theme) —\n      // wait a few seconds for it, then give up quietly.\n      if (!wrap) { if (tries++ < 300) raf = requestAnimationFrame(apply); return; }\n      tries = 0;\n      const url = textMaskDataUrl(el, el);\n      if (!url) return;\n      const v = `url(\"${url}\")`;\n      wrap.style.maskImage = v;\n      wrap.style.webkitMaskImage = v;\n      wrap.style.maskRepeat = 'no-repeat';\n      wrap.style.webkitMaskRepeat = 'no-repeat';\n      wrap.style.maskSize = '100% 100%';\n      wrap.style.webkitMaskSize = '100% 100%';\n      // A mirror *replaces* what's under it. Additive blending on light-grey\n      // text pushed everything to white and erased the metal's stripes and\n      // dispersion fringes; normal compositing keeps them.\n      wrap.style.mixBlendMode = 'normal';\n    };\n\n    apply();\n    const ro = new ResizeObserver(() => apply());\n    ro.observe(el);\n    document.fonts?.ready.then(() => apply());\n    // The engine tears down and re-inserts the wrapper whenever the owning\n    // MetalFx's reflection effect re-runs — every new wrapper needs the mask.\n    const mo = new MutationObserver((recs) => {\n      for (const r of recs) {\n        for (const n of Array.from(r.addedNodes)) {\n          if (n instanceof HTMLElement && n.hasAttribute('data-metal-fx-reflection')) { apply(); return; }\n        }\n      }\n    });\n    mo.observe(el, { childList: true });\n\n    return () => {\n      disposed = true;\n      if (raf) cancelAnimationFrame(raf);\n      ro.disconnect();\n      mo.disconnect();\n    };\n  }, [ref]);\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/effects/metal-fx/LICENSE",
          "target": "@components/effects/metal-fx/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Jakub Antalik\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/effects/metal-fx/SOURCE.json",
          "target": "@components/effects/metal-fx/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"metal-fx\",\n  \"repository\": \"https://github.com/Jakubantalik/Libraries.dev\",\n  \"revision\": \"422180dd7a5ac646c85deedc65500c4a74339127\",\n  \"packageVersion\": \"2.0.10\",\n  \"license\": \"MIT\",\n  \"copiedPath\": \"upstream/\",\n  \"sourcePath\": \"packages/metal-fx/src/\",\n  \"copiedFiles\": [\"src/**\"],\n  \"thirdPartyFiles\": [\n    \"PAPER_SHADERS_LICENSE\",\n    \"PAPER_SHADERS_NOTICE\"\n  ],\n  \"relationship\": \"Source-faithful copy of the pinned public React package. The top-level client facade re-exports its complete API.\"\n}\n"
        },
        {
          "path": "components/effects/metal-fx/PAPER_SHADERS_LICENSE",
          "target": "@components/effects/metal-fx/PAPER_SHADERS_LICENSE",
          "type": "registry:file",
          "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
        },
        {
          "path": "components/effects/metal-fx/PAPER_SHADERS_NOTICE",
          "target": "@components/effects/metal-fx/PAPER_SHADERS_NOTICE",
          "type": "registry:file",
          "content": "Paper Shaders\nCopyright 2026 Paper\n\nPowered by Paper Shaders:\nhttps://shaders.paper.design\n"
        }
      ],
      "categories": [
        "Libraries.dev"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-agent",
      "type": "registry:block",
      "title": "Ai Elements Agent",
      "description": "agent",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/agent.tsx",
          "target": "@components/ai-elements/agent.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Accordion,\n  AccordionContent,\n  AccordionItem,\n  AccordionTrigger,\n} from \"@/components/ai-elements/_ui/accordion\"\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport { cn } from \"@/lib/utils\"\nimport type { Tool } from \"ai\"\nimport { BotIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport { memo } from \"react\"\nimport { CodeBlock } from \"./code-block\"\n\nexport type AgentProps = ComponentProps<\"div\">\n\nexport const Agent = memo(({ className, ...props }: AgentProps) => (\n  <div\n    className={cn(\"not-prose w-full rounded-md border\", className)}\n    {...props}\n  />\n))\n\nexport type AgentHeaderProps = ComponentProps<\"div\"> & {\n  name: string\n  model?: string\n}\n\nexport const AgentHeader = memo(\n  ({ className, name, model, ...props }: AgentHeaderProps) => (\n    <div\n      className={cn(\n        \"flex w-full items-center justify-between gap-4 p-3\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"flex items-center gap-2\">\n        <BotIcon className=\"text-muted-foreground size-4\" />\n        <span className=\"text-sm font-medium\">{name}</span>\n        {model && (\n          <Badge className=\"font-mono text-xs\" variant=\"secondary\">\n            {model}\n          </Badge>\n        )}\n      </div>\n    </div>\n  )\n)\n\nexport type AgentContentProps = ComponentProps<\"div\">\n\nexport const AgentContent = memo(\n  ({ className, ...props }: AgentContentProps) => (\n    <div className={cn(\"space-y-4 p-4 pt-0\", className)} {...props} />\n  )\n)\n\nexport type AgentInstructionsProps = ComponentProps<\"div\"> & {\n  children: string\n}\n\nexport const AgentInstructions = memo(\n  ({ className, children, ...props }: AgentInstructionsProps) => (\n    <div className={cn(\"space-y-2\", className)} {...props}>\n      <span className=\"text-muted-foreground text-sm font-medium\">\n        Instructions\n      </span>\n      <div className=\"bg-muted/50 text-muted-foreground rounded-md p-3 text-sm\">\n        <p>{children}</p>\n      </div>\n    </div>\n  )\n)\n\nexport type AgentToolsProps = ComponentProps<typeof Accordion>\n\nexport const AgentTools = memo(({ className, ...props }: AgentToolsProps) => (\n  <div className={cn(\"space-y-2\", className)}>\n    <span className=\"text-muted-foreground text-sm font-medium\">Tools</span>\n    <Accordion className=\"rounded-md border\" {...props} />\n  </div>\n))\n\nexport type AgentToolProps = ComponentProps<typeof AccordionItem> & {\n  tool: Tool\n}\n\nexport const AgentTool = memo(\n  ({ className, tool, value, ...props }: AgentToolProps) => {\n    const schema =\n      \"jsonSchema\" in tool && tool.jsonSchema\n        ? tool.jsonSchema\n        : tool.inputSchema\n\n    return (\n      <AccordionItem\n        className={cn(\"border-b last:border-b-0\", className)}\n        value={value}\n        {...props}\n      >\n        <AccordionTrigger className=\"px-3 py-2 text-sm hover:no-underline\">\n          {tool.description ?? \"No description\"}\n        </AccordionTrigger>\n        <AccordionContent className=\"px-3 pb-3\">\n          <div className=\"bg-muted/50 rounded-md\">\n            <CodeBlock code={JSON.stringify(schema, null, 2)} language=\"json\" />\n          </div>\n        </AccordionContent>\n      </AccordionItem>\n    )\n  }\n)\n\nexport type AgentOutputProps = ComponentProps<\"div\"> & {\n  schema: string\n}\n\nexport const AgentOutput = memo(\n  ({ className, schema, ...props }: AgentOutputProps) => (\n    <div className={cn(\"space-y-2\", className)} {...props}>\n      <span className=\"text-muted-foreground text-sm font-medium\">\n        Output Schema\n      </span>\n      <div className=\"bg-muted/50 rounded-md\">\n        <CodeBlock code={schema} language=\"typescript\" />\n      </div>\n    </div>\n  )\n)\n\nAgent.displayName = \"Agent\"\nAgentHeader.displayName = \"AgentHeader\"\nAgentContent.displayName = \"AgentContent\"\nAgentInstructions.displayName = \"AgentInstructions\"\nAgentTools.displayName = \"AgentTools\"\nAgentTool.displayName = \"AgentTool\"\nAgentOutput.displayName = \"AgentOutput\"\n"
        },
        {
          "path": "components/ai-elements/_ui/accordion.tsx",
          "target": "@components/ai-elements/_ui/accordion.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Accordion({\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Root>) {\n  return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />\n}\n\nfunction AccordionItem({\n  className,\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Item>) {\n  return (\n    <AccordionPrimitive.Item\n      data-slot=\"accordion-item\"\n      className={cn(\"border-b last:border-b-0\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction AccordionTrigger({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {\n  return (\n    <AccordionPrimitive.Header className=\"flex\">\n      <AccordionPrimitive.Trigger\n        data-slot=\"accordion-trigger\"\n        className={cn(\n          \"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <ChevronDownIcon className=\"text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200\" />\n      </AccordionPrimitive.Trigger>\n    </AccordionPrimitive.Header>\n  )\n}\n\nfunction AccordionContent({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n  return (\n    <AccordionPrimitive.Content\n      data-slot=\"accordion-content\"\n      className=\"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm\"\n      {...props}\n    >\n      <div className={cn(\"pt-0 pb-4\", className)}>{children}</div>\n    </AccordionPrimitive.Content>\n  )\n}\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "components/ai-elements/code-block.tsx",
          "target": "@components/ai-elements/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ai-elements/_ui/select\"\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, CopyIcon } from \"lucide-react\"\nimport type { ComponentProps, CSSProperties, HTMLAttributes } from \"react\"\nimport {\n  createContext,\n  memo,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport type {\n  BundledLanguage,\n  BundledTheme,\n  HighlighterGeneric,\n  ThemedToken,\n} from \"shiki\"\nimport { createHighlighter } from \"shiki\"\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2\nconst isUnderline = (fontStyle: number | undefined) =>\n  // oxlint-disable-next-line eslint(no-bitwise)\n  fontStyle && fontStyle & 4\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n  token: ThemedToken\n  key: string\n}\ninterface KeyedLine {\n  tokens: KeyedToken[]\n  key: string\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n  lines.map((line, lineIdx) => ({\n    key: `line-${lineIdx}`,\n    tokens: line.map((token, tokenIdx) => ({\n      key: `line-${lineIdx}-${tokenIdx}`,\n      token,\n    })),\n  }))\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n  <span\n    className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n    style={\n      {\n        backgroundColor: token.bgColor,\n        color: token.color,\n        fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n        fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n        textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n        ...token.htmlStyle,\n      } as CSSProperties\n    }\n  >\n    {token.content}\n  </span>\n)\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n  \"block\",\n  \"before:content-[counter(line)]\",\n  \"before:inline-block\",\n  \"before:[counter-increment:line]\",\n  \"before:w-8\",\n  \"before:mr-4\",\n  \"before:text-right\",\n  \"before:text-muted-foreground/50\",\n  \"before:font-mono\",\n  \"before:select-none\"\n)\n\n// Line rendering component\nconst LineSpan = ({\n  keyedLine,\n  showLineNumbers,\n}: {\n  keyedLine: KeyedLine\n  showLineNumbers: boolean\n}) => (\n  <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n    {keyedLine.tokens.length === 0\n      ? \"\\n\"\n      : keyedLine.tokens.map(({ token, key }) => (\n          <TokenSpan key={key} token={token} />\n        ))}\n  </span>\n)\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n  code: string\n  language: BundledLanguage\n  showLineNumbers?: boolean\n}\n\ninterface TokenizedCode {\n  tokens: ThemedToken[][]\n  fg: string\n  bg: string\n}\n\ninterface CodeBlockContextType {\n  code: string\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n  code: \"\",\n})\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n  string,\n  Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>()\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>()\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>()\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n  const start = code.slice(0, 100)\n  const end = code.length > 100 ? code.slice(-100) : \"\"\n  return `${language}:${code.length}:${start}:${end}`\n}\n\nconst getHighlighter = (\n  language: BundledLanguage\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n  const cached = highlighterCache.get(language)\n  if (cached) {\n    return cached\n  }\n\n  const highlighterPromise = createHighlighter({\n    langs: [language],\n    themes: [\"github-light\", \"github-dark\"],\n  })\n\n  highlighterCache.set(language, highlighterPromise)\n  return highlighterPromise\n}\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n  bg: \"transparent\",\n  fg: \"inherit\",\n  tokens: code.split(\"\\n\").map((line) =>\n    line === \"\"\n      ? []\n      : [\n          {\n            color: \"inherit\",\n            content: line,\n          } as ThemedToken,\n        ]\n  ),\n})\n\n// Synchronous highlight with callback for async results\nexport const highlightCode = (\n  code: string,\n  language: BundledLanguage,\n  // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-callbacks)\n  callback?: (result: TokenizedCode) => void\n): TokenizedCode | null => {\n  const tokensCacheKey = getTokensCacheKey(code, language)\n\n  // Return cached result if available\n  const cached = tokensCache.get(tokensCacheKey)\n  if (cached) {\n    return cached\n  }\n\n  // Subscribe callback if provided\n  if (callback) {\n    if (!subscribers.has(tokensCacheKey)) {\n      subscribers.set(tokensCacheKey, new Set())\n    }\n    subscribers.get(tokensCacheKey)?.add(callback)\n  }\n\n  // Start highlighting in background - fire-and-forget async pattern\n  getHighlighter(language)\n    // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then)\n    .then((highlighter) => {\n      const availableLangs = highlighter.getLoadedLanguages()\n      const langToUse = availableLangs.includes(language) ? language : \"text\"\n\n      const result = highlighter.codeToTokens(code, {\n        lang: langToUse,\n        themes: {\n          dark: \"github-dark\",\n          light: \"github-light\",\n        },\n      })\n\n      const tokenized: TokenizedCode = {\n        bg: result.bg ?? \"transparent\",\n        fg: result.fg ?? \"inherit\",\n        tokens: result.tokens,\n      }\n\n      // Cache the result\n      tokensCache.set(tokensCacheKey, tokenized)\n\n      // Notify all subscribers\n      const subs = subscribers.get(tokensCacheKey)\n      if (subs) {\n        for (const sub of subs) {\n          sub(tokenized)\n        }\n        subscribers.delete(tokensCacheKey)\n      }\n    })\n    // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then), eslint-plugin-promise(prefer-await-to-callbacks)\n    .catch((error) => {\n      console.error(\"Failed to highlight code:\", error)\n      subscribers.delete(tokensCacheKey)\n    })\n\n  return null\n}\n\nconst CodeBlockBody = memo(\n  ({\n    tokenized,\n    showLineNumbers,\n    className,\n  }: {\n    tokenized: TokenizedCode\n    showLineNumbers: boolean\n    className?: string\n  }) => {\n    const preStyle = useMemo(\n      () => ({\n        backgroundColor: tokenized.bg,\n        color: tokenized.fg,\n      }),\n      [tokenized.bg, tokenized.fg]\n    )\n\n    const keyedLines = useMemo(\n      () => addKeysToTokens(tokenized.tokens),\n      [tokenized.tokens]\n    )\n\n    return (\n      <pre\n        className={cn(\n          \"m-0 p-4 text-sm dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\",\n          className\n        )}\n        style={preStyle}\n      >\n        <code\n          className={cn(\n            \"font-mono text-sm\",\n            showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\"\n          )}\n        >\n          {keyedLines.map((keyedLine) => (\n            <LineSpan\n              key={keyedLine.key}\n              keyedLine={keyedLine}\n              showLineNumbers={showLineNumbers}\n            />\n          ))}\n        </code>\n      </pre>\n    )\n  },\n  (prevProps, nextProps) =>\n    prevProps.tokenized === nextProps.tokenized &&\n    prevProps.showLineNumbers === nextProps.showLineNumbers &&\n    prevProps.className === nextProps.className\n)\n\nCodeBlockBody.displayName = \"CodeBlockBody\"\n\nexport const CodeBlockContainer = ({\n  className,\n  language,\n  style,\n  ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n  <div\n    className={cn(\n      \"group bg-background text-foreground relative w-full overflow-hidden rounded-md border\",\n      className\n    )}\n    data-language={language}\n    style={{\n      containIntrinsicSize: \"auto 200px\",\n      contentVisibility: \"auto\",\n      ...style,\n    }}\n    {...props}\n  />\n)\n\nexport const CodeBlockHeader = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"bg-muted/80 text-muted-foreground flex items-center justify-between border-b px-3 py-2 text-xs\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport const CodeBlockTitle = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport const CodeBlockFilename = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n  <span className={cn(\"font-mono\", className)} {...props}>\n    {children}\n  </span>\n)\n\nexport const CodeBlockActions = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport const CodeBlockContent = ({\n  code,\n  language,\n  showLineNumbers = false,\n}: {\n  code: string\n  language: BundledLanguage\n  showLineNumbers?: boolean\n}) => {\n  // Memoized raw tokens for immediate display\n  const rawTokens = useMemo(() => createRawTokens(code), [code])\n\n  // Synchronous cache lookup — avoids setState in effect for cached results\n  const syncTokens = useMemo(\n    () => highlightCode(code, language) ?? rawTokens,\n    [code, language, rawTokens]\n  )\n\n  // Async highlighting result (populated after shiki loads)\n  const [asyncTokens, setAsyncTokens] = useState<TokenizedCode | null>(null)\n  const asyncKeyRef = useRef({ code, language })\n\n  // Invalidate stale async tokens synchronously during render\n  if (\n    asyncKeyRef.current.code !== code ||\n    asyncKeyRef.current.language !== language\n  ) {\n    asyncKeyRef.current = { code, language }\n    setAsyncTokens(null)\n  }\n\n  useEffect(() => {\n    let cancelled = false\n\n    highlightCode(code, language, (result) => {\n      if (!cancelled) {\n        setAsyncTokens(result)\n      }\n    })\n\n    return () => {\n      cancelled = true\n    }\n  }, [code, language])\n\n  const tokenized = asyncTokens ?? syncTokens\n\n  return (\n    <div className=\"relative overflow-auto\">\n      <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n    </div>\n  )\n}\n\nexport const CodeBlock = ({\n  code,\n  language,\n  showLineNumbers = false,\n  className,\n  children,\n  ...props\n}: CodeBlockProps) => {\n  const contextValue = useMemo(() => ({ code }), [code])\n\n  return (\n    <CodeBlockContext.Provider value={contextValue}>\n      <CodeBlockContainer className={className} language={language} {...props}>\n        {children}\n        <CodeBlockContent\n          code={code}\n          language={language}\n          showLineNumbers={showLineNumbers}\n        />\n      </CodeBlockContainer>\n    </CodeBlockContext.Provider>\n  )\n}\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const CodeBlockCopyButton = ({\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  className,\n  ...props\n}: CodeBlockCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n  const { code } = useContext(CodeBlockContext)\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      if (!isCopied) {\n        await navigator.clipboard.writeText(code)\n        setIsCopied(true)\n        onCopy?.()\n        timeoutRef.current = window.setTimeout(\n          () => setIsCopied(false),\n          timeout\n        )\n      }\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [code, onCopy, onError, timeout, isCopied])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <Button\n      className={cn(\"shrink-0\", className)}\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>\n\nexport const CodeBlockLanguageSelector = (\n  props: CodeBlockLanguageSelectorProps\n) => <Select {...props} />\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<\n  typeof SelectTrigger\n>\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n  className,\n  ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n  <SelectTrigger\n    className={cn(\n      \"h-7 border-none bg-transparent px-2 text-xs shadow-none\",\n      className\n    )}\n    size=\"sm\"\n    {...props}\n  />\n)\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<\n  typeof SelectValue\n>\n\nexport const CodeBlockLanguageSelectorValue = (\n  props: CodeBlockLanguageSelectorValueProps\n) => <SelectValue {...props} />\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<\n  typeof SelectContent\n>\n\nexport const CodeBlockLanguageSelectorContent = ({\n  align = \"end\",\n  ...props\n}: CodeBlockLanguageSelectorContentProps) => (\n  <SelectContent align={align} {...props} />\n)\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<\n  typeof SelectItem\n>\n\nexport const CodeBlockLanguageSelectorItem = (\n  props: CodeBlockLanguageSelectorItemProps\n) => <SelectItem {...props} />\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ai-elements/_ui/select.tsx",
          "target": "@components/ai-elements/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"popper\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-artifact",
      "type": "registry:block",
      "title": "Ai Elements Artifact",
      "description": "artifact",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/artifact.tsx",
          "target": "@components/ai-elements/artifact.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ai-elements/_ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport type { LucideIcon } from \"lucide-react\"\nimport { XIcon } from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\n\nexport type ArtifactProps = HTMLAttributes<HTMLDivElement>\n\nexport const Artifact = ({ className, ...props }: ArtifactProps) => (\n  <div\n    className={cn(\n      \"bg-background flex flex-col overflow-hidden rounded-lg border shadow-sm\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type ArtifactHeaderProps = HTMLAttributes<HTMLDivElement>\n\nexport const ArtifactHeader = ({\n  className,\n  ...props\n}: ArtifactHeaderProps) => (\n  <div\n    className={cn(\n      \"bg-muted/50 flex items-center justify-between border-b px-4 py-3\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type ArtifactCloseProps = ComponentProps<typeof Button>\n\nexport const ArtifactClose = ({\n  className,\n  children,\n  size = \"sm\",\n  variant = \"ghost\",\n  ...props\n}: ArtifactCloseProps) => (\n  <Button\n    className={cn(\n      \"text-muted-foreground hover:text-foreground size-8 p-0\",\n      className\n    )}\n    size={size}\n    type=\"button\"\n    variant={variant}\n    {...props}\n  >\n    {children ?? <XIcon className=\"size-4\" />}\n    <span className=\"sr-only\">Close</span>\n  </Button>\n)\n\nexport type ArtifactTitleProps = HTMLAttributes<HTMLParagraphElement>\n\nexport const ArtifactTitle = ({ className, ...props }: ArtifactTitleProps) => (\n  <p\n    className={cn(\"text-foreground text-sm font-medium\", className)}\n    {...props}\n  />\n)\n\nexport type ArtifactDescriptionProps = HTMLAttributes<HTMLParagraphElement>\n\nexport const ArtifactDescription = ({\n  className,\n  ...props\n}: ArtifactDescriptionProps) => (\n  <p className={cn(\"text-muted-foreground text-sm\", className)} {...props} />\n)\n\nexport type ArtifactActionsProps = HTMLAttributes<HTMLDivElement>\n\nexport const ArtifactActions = ({\n  className,\n  ...props\n}: ArtifactActionsProps) => (\n  <div className={cn(\"flex items-center gap-1\", className)} {...props} />\n)\n\nexport type ArtifactActionProps = ComponentProps<typeof Button> & {\n  tooltip?: string\n  label?: string\n  icon?: LucideIcon\n}\n\nexport const ArtifactAction = ({\n  tooltip,\n  label,\n  icon: Icon,\n  children,\n  className,\n  size = \"sm\",\n  variant = \"ghost\",\n  ...props\n}: ArtifactActionProps) => {\n  const button = (\n    <Button\n      className={cn(\n        \"text-muted-foreground hover:text-foreground size-8 p-0\",\n        className\n      )}\n      size={size}\n      type=\"button\"\n      variant={variant}\n      {...props}\n    >\n      {Icon ? <Icon className=\"size-4\" /> : children}\n      <span className=\"sr-only\">{label || tooltip}</span>\n    </Button>\n  )\n\n  if (tooltip) {\n    return (\n      <TooltipProvider>\n        <Tooltip>\n          <TooltipTrigger asChild>{button}</TooltipTrigger>\n          <TooltipContent>\n            <p>{tooltip}</p>\n          </TooltipContent>\n        </Tooltip>\n      </TooltipProvider>\n    )\n  }\n\n  return button\n}\n\nexport type ArtifactContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const ArtifactContent = ({\n  className,\n  ...props\n}: ArtifactContentProps) => (\n  <div className={cn(\"flex-1 overflow-auto p-4\", className)} {...props} />\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/tooltip.tsx",
          "target": "@components/ai-elements/_ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 0,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-attachments",
      "type": "registry:block",
      "title": "Ai Elements Attachments",
      "description": "attachments",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/attachments.tsx",
          "target": "@components/ai-elements/attachments.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  HoverCard,\n  HoverCardContent,\n  HoverCardTrigger,\n} from \"@/components/ai-elements/_ui/hover-card\"\nimport { cn } from \"@/lib/utils\"\nimport type { FileUIPart, SourceDocumentUIPart } from \"ai\"\nimport {\n  FileTextIcon,\n  GlobeIcon,\n  ImageIcon,\n  Music2Icon,\n  PaperclipIcon,\n  VideoIcon,\n  XIcon,\n} from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes, ReactNode } from \"react\"\nimport { createContext, useCallback, useContext, useMemo } from \"react\"\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type AttachmentData =\n  | (FileUIPart & { id: string })\n  | (SourceDocumentUIPart & { id: string })\n\nexport type AttachmentMediaCategory =\n  | \"image\"\n  | \"video\"\n  | \"audio\"\n  | \"document\"\n  | \"source\"\n  | \"unknown\"\n\nexport type AttachmentVariant = \"grid\" | \"inline\" | \"list\"\n\nconst mediaCategoryIcons: Record<AttachmentMediaCategory, typeof ImageIcon> = {\n  audio: Music2Icon,\n  document: FileTextIcon,\n  image: ImageIcon,\n  source: GlobeIcon,\n  unknown: PaperclipIcon,\n  video: VideoIcon,\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nexport const getMediaCategory = (\n  data: AttachmentData\n): AttachmentMediaCategory => {\n  if (data.type === \"source-document\") {\n    return \"source\"\n  }\n\n  const mediaType = data.mediaType ?? \"\"\n\n  if (mediaType.startsWith(\"image/\")) {\n    return \"image\"\n  }\n  if (mediaType.startsWith(\"video/\")) {\n    return \"video\"\n  }\n  if (mediaType.startsWith(\"audio/\")) {\n    return \"audio\"\n  }\n  if (mediaType.startsWith(\"application/\") || mediaType.startsWith(\"text/\")) {\n    return \"document\"\n  }\n\n  return \"unknown\"\n}\n\nexport const getAttachmentLabel = (data: AttachmentData): string => {\n  if (data.type === \"source-document\") {\n    return data.title || data.filename || \"Source\"\n  }\n\n  const category = getMediaCategory(data)\n  return data.filename || (category === \"image\" ? \"Image\" : \"Attachment\")\n}\n\nconst renderAttachmentImage = (\n  url: string,\n  filename: string | undefined,\n  isGrid: boolean\n) =>\n  isGrid ? (\n    <img\n      alt={filename || \"Image\"}\n      className=\"size-full object-cover\"\n      height={96}\n      src={url}\n      width={96}\n    />\n  ) : (\n    <img\n      alt={filename || \"Image\"}\n      className=\"size-full rounded object-cover\"\n      height={20}\n      src={url}\n      width={20}\n    />\n  )\n\n// ============================================================================\n// Contexts\n// ============================================================================\n\ninterface AttachmentsContextValue {\n  variant: AttachmentVariant\n}\n\nconst AttachmentsContext = createContext<AttachmentsContextValue | null>(null)\n\ninterface AttachmentContextValue {\n  data: AttachmentData\n  mediaCategory: AttachmentMediaCategory\n  onRemove?: () => void\n  variant: AttachmentVariant\n}\n\nconst AttachmentContext = createContext<AttachmentContextValue | null>(null)\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\nexport const useAttachmentsContext = () =>\n  useContext(AttachmentsContext) ?? { variant: \"grid\" as const }\n\nexport const useAttachmentContext = () => {\n  const ctx = useContext(AttachmentContext)\n  if (!ctx) {\n    throw new Error(\"Attachment components must be used within <Attachment>\")\n  }\n  return ctx\n}\n\n// ============================================================================\n// Attachments - Container\n// ============================================================================\n\nexport type AttachmentsProps = HTMLAttributes<HTMLDivElement> & {\n  variant?: AttachmentVariant\n}\n\nexport const Attachments = ({\n  variant = \"grid\",\n  className,\n  children,\n  ...props\n}: AttachmentsProps) => {\n  const contextValue = useMemo(() => ({ variant }), [variant])\n\n  return (\n    <AttachmentsContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"flex items-start\",\n          variant === \"list\" ? \"flex-col gap-2\" : \"flex-wrap gap-2\",\n          variant === \"grid\" && \"ml-auto w-fit\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n      </div>\n    </AttachmentsContext.Provider>\n  )\n}\n\n// ============================================================================\n// Attachment - Item\n// ============================================================================\n\nexport type AttachmentProps = HTMLAttributes<HTMLDivElement> & {\n  data: AttachmentData\n  onRemove?: () => void\n}\n\nexport const Attachment = ({\n  data,\n  onRemove,\n  className,\n  children,\n  ...props\n}: AttachmentProps) => {\n  const { variant } = useAttachmentsContext()\n  const mediaCategory = getMediaCategory(data)\n\n  const contextValue = useMemo<AttachmentContextValue>(\n    () => ({ data, mediaCategory, onRemove, variant }),\n    [data, mediaCategory, onRemove, variant]\n  )\n\n  return (\n    <AttachmentContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"group relative\",\n          variant === \"grid\" && \"size-24 overflow-hidden rounded-lg\",\n          variant === \"inline\" && [\n            \"flex h-8 cursor-pointer items-center gap-1.5 select-none\",\n            \"border-border rounded-md border px-1.5\",\n            \"text-sm font-medium transition-all\",\n            \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n          ],\n          variant === \"list\" && [\n            \"flex w-full items-center gap-3 rounded-lg border p-3\",\n            \"hover:bg-accent/50\",\n          ],\n          className\n        )}\n        {...props}\n      >\n        {children}\n      </div>\n    </AttachmentContext.Provider>\n  )\n}\n\n// ============================================================================\n// AttachmentPreview - Media preview\n// ============================================================================\n\nexport type AttachmentPreviewProps = HTMLAttributes<HTMLDivElement> & {\n  fallbackIcon?: ReactNode\n}\n\nexport const AttachmentPreview = ({\n  fallbackIcon,\n  className,\n  ...props\n}: AttachmentPreviewProps) => {\n  const { data, mediaCategory, variant } = useAttachmentContext()\n\n  const iconSize = variant === \"inline\" ? \"size-3\" : \"size-4\"\n\n  const renderIcon = (Icon: typeof ImageIcon) => (\n    <Icon className={cn(iconSize, \"text-muted-foreground\")} />\n  )\n\n  const renderContent = () => {\n    if (mediaCategory === \"image\" && data.type === \"file\" && data.url) {\n      return renderAttachmentImage(data.url, data.filename, variant === \"grid\")\n    }\n\n    if (mediaCategory === \"video\" && data.type === \"file\" && data.url) {\n      return <video className=\"size-full object-cover\" muted src={data.url} />\n    }\n\n    const Icon = mediaCategoryIcons[mediaCategory]\n    return fallbackIcon ?? renderIcon(Icon)\n  }\n\n  return (\n    <div\n      className={cn(\n        \"flex shrink-0 items-center justify-center overflow-hidden\",\n        variant === \"grid\" && \"bg-muted size-full\",\n        variant === \"inline\" && \"bg-background size-5 rounded\",\n        variant === \"list\" && \"bg-muted size-12 rounded\",\n        className\n      )}\n      {...props}\n    >\n      {renderContent()}\n    </div>\n  )\n}\n\n// ============================================================================\n// AttachmentInfo - Name and type display\n// ============================================================================\n\nexport type AttachmentInfoProps = HTMLAttributes<HTMLDivElement> & {\n  showMediaType?: boolean\n}\n\nexport const AttachmentInfo = ({\n  showMediaType = false,\n  className,\n  ...props\n}: AttachmentInfoProps) => {\n  const { data, variant } = useAttachmentContext()\n  const label = getAttachmentLabel(data)\n\n  if (variant === \"grid\") {\n    return null\n  }\n\n  return (\n    <div className={cn(\"min-w-0 flex-1\", className)} {...props}>\n      <span className=\"block truncate\">{label}</span>\n      {showMediaType && data.mediaType && (\n        <span className=\"text-muted-foreground block truncate text-xs\">\n          {data.mediaType}\n        </span>\n      )}\n    </div>\n  )\n}\n\n// ============================================================================\n// AttachmentRemove - Remove button\n// ============================================================================\n\nexport type AttachmentRemoveProps = ComponentProps<typeof Button> & {\n  label?: string\n}\n\nexport const AttachmentRemove = ({\n  label = \"Remove\",\n  className,\n  children,\n  ...props\n}: AttachmentRemoveProps) => {\n  const { onRemove, variant } = useAttachmentContext()\n\n  const handleClick = useCallback(\n    (e: React.MouseEvent) => {\n      e.stopPropagation()\n      onRemove?.()\n    },\n    [onRemove]\n  )\n\n  if (!onRemove) {\n    return null\n  }\n\n  return (\n    <Button\n      aria-label={label}\n      className={cn(\n        variant === \"grid\" && [\n          \"absolute top-2 right-2 size-6 rounded-full p-0\",\n          \"bg-background/80 backdrop-blur-sm\",\n          \"opacity-0 transition-opacity group-hover:opacity-100\",\n          \"hover:bg-background\",\n          \"[&>svg]:size-3\",\n        ],\n        variant === \"inline\" && [\n          \"size-5 rounded p-0\",\n          \"opacity-0 transition-opacity group-hover:opacity-100\",\n          \"[&>svg]:size-2.5\",\n        ],\n        variant === \"list\" && [\"size-8 shrink-0 rounded p-0\", \"[&>svg]:size-4\"],\n        className\n      )}\n      onClick={handleClick}\n      type=\"button\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <XIcon />}\n      <span className=\"sr-only\">{label}</span>\n    </Button>\n  )\n}\n\n// ============================================================================\n// AttachmentHoverCard - Hover preview\n// ============================================================================\n\nexport type AttachmentHoverCardProps = ComponentProps<typeof HoverCard>\n\nexport const AttachmentHoverCard = ({\n  openDelay = 0,\n  closeDelay = 0,\n  ...props\n}: AttachmentHoverCardProps) => (\n  <HoverCard closeDelay={closeDelay} openDelay={openDelay} {...props} />\n)\n\nexport type AttachmentHoverCardTriggerProps = ComponentProps<\n  typeof HoverCardTrigger\n>\n\nexport const AttachmentHoverCardTrigger = (\n  props: AttachmentHoverCardTriggerProps\n) => <HoverCardTrigger {...props} />\n\nexport type AttachmentHoverCardContentProps = ComponentProps<\n  typeof HoverCardContent\n>\n\nexport const AttachmentHoverCardContent = ({\n  align = \"start\",\n  className,\n  ...props\n}: AttachmentHoverCardContentProps) => (\n  <HoverCardContent\n    align={align}\n    className={cn(\"w-auto p-2\", className)}\n    {...props}\n  />\n)\n\n// ============================================================================\n// AttachmentEmpty - Empty state\n// ============================================================================\n\nexport type AttachmentEmptyProps = HTMLAttributes<HTMLDivElement>\n\nexport const AttachmentEmpty = ({\n  className,\n  children,\n  ...props\n}: AttachmentEmptyProps) => (\n  <div\n    className={cn(\n      \"text-muted-foreground flex items-center justify-center p-4 text-sm\",\n      className\n    )}\n    {...props}\n  >\n    {children ?? \"No attachments\"}\n  </div>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/hover-card.tsx",
          "target": "@components/ai-elements/_ui/hover-card.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { HoverCard as HoverCardPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction HoverCard({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n  return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />\n}\n\nfunction HoverCardTrigger({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n  return (\n    <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n  )\n}\n\nfunction HoverCardContent({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n  return (\n    <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n      <HoverCardPrimitive.Content\n        data-slot=\"hover-card-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n          className\n        )}\n        {...props}\n      />\n    </HoverCardPrimitive.Portal>\n  )\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-audio-player",
      "type": "registry:block",
      "title": "Ai Elements Audio Player",
      "description": "audio player",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "media-chrome@4.17.2",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/audio-player.tsx",
          "target": "@components/ai-elements/audio-player.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  ButtonGroup,\n  ButtonGroupText,\n} from \"@/components/ai-elements/_ui/button-group\"\nimport { cn } from \"@/lib/utils\"\nimport type { Experimental_SpeechResult as SpeechResult } from \"ai\"\nimport {\n  MediaControlBar,\n  MediaController,\n  MediaDurationDisplay,\n  MediaMuteButton,\n  MediaPlayButton,\n  MediaSeekBackwardButton,\n  MediaSeekForwardButton,\n  MediaTimeDisplay,\n  MediaTimeRange,\n  MediaVolumeRange,\n} from \"media-chrome/react\"\nimport type { ComponentProps, CSSProperties } from \"react\"\n\nexport type AudioPlayerProps = Omit<\n  ComponentProps<typeof MediaController>,\n  \"audio\"\n>\n\nexport const AudioPlayer = ({\n  className,\n  children,\n  style,\n  ...props\n}: AudioPlayerProps) => (\n  <MediaController\n    audio\n    className={cn(\"w-full min-w-0\", className)}\n    data-slot=\"audio-player\"\n    style={\n      {\n        \"--media-background-color\": \"transparent\",\n        \"--media-button-icon-height\": \"1rem\",\n        \"--media-button-icon-width\": \"1rem\",\n        \"--media-control-background\": \"transparent\",\n        \"--media-control-hover-background\": \"var(--color-accent)\",\n        \"--media-control-padding\": \"0\",\n        \"--media-font\": \"var(--font-sans)\",\n        \"--media-font-size\": \"10px\",\n        \"--media-icon-color\": \"currentColor\",\n        \"--media-preview-time-background\": \"var(--color-background)\",\n        \"--media-preview-time-border-radius\": \"var(--radius-md)\",\n        \"--media-preview-time-text-shadow\": \"none\",\n        \"--media-primary-color\": \"var(--color-primary)\",\n        \"--media-range-bar-color\": \"var(--color-primary)\",\n        \"--media-range-track-background\": \"var(--color-secondary)\",\n        \"--media-secondary-color\": \"var(--color-secondary)\",\n        \"--media-text-color\": \"var(--color-foreground)\",\n        \"--media-tooltip-arrow-display\": \"none\",\n        \"--media-tooltip-background\": \"var(--color-background)\",\n        \"--media-tooltip-border-radius\": \"var(--radius-md)\",\n        ...style,\n      } as CSSProperties\n    }\n    {...props}\n  >\n    {children}\n  </MediaController>\n)\n\nexport type AudioPlayerElementProps = Omit<ComponentProps<\"audio\">, \"src\"> &\n  (\n    | {\n        data: SpeechResult[\"audio\"]\n      }\n    | {\n        src: string\n      }\n  )\n\nexport const AudioPlayerElement = ({ ...props }: AudioPlayerElementProps) => (\n  // oxlint-disable-next-line eslint-plugin-jsx-a11y(media-has-caption) -- audio player captions are provided by consumer\n  <audio\n    data-slot=\"audio-player-element\"\n    slot=\"media\"\n    src={\n      \"src\" in props\n        ? props.src\n        : `data:${props.data.mediaType};base64,${props.data.base64}`\n    }\n    {...props}\n  />\n)\n\nexport type AudioPlayerControlBarProps = ComponentProps<typeof MediaControlBar>\n\nexport const AudioPlayerControlBar = ({\n  className,\n  children,\n  ...props\n}: AudioPlayerControlBarProps) => (\n  <MediaControlBar\n    className={cn(\"w-full min-w-0\", className)}\n    data-slot=\"audio-player-control-bar\"\n    {...props}\n  >\n    <ButtonGroup className=\"w-full min-w-0\" orientation=\"horizontal\">\n      {children}\n    </ButtonGroup>\n  </MediaControlBar>\n)\n\nexport type AudioPlayerPlayButtonProps = ComponentProps<typeof MediaPlayButton>\n\nexport const AudioPlayerPlayButton = ({\n  className,\n  ...props\n}: AudioPlayerPlayButtonProps) => (\n  <Button asChild size=\"icon-sm\" variant=\"outline\">\n    <MediaPlayButton\n      className={cn(\"bg-transparent\", className)}\n      data-slot=\"audio-player-play-button\"\n      {...props}\n    />\n  </Button>\n)\n\nexport type AudioPlayerSeekBackwardButtonProps = ComponentProps<\n  typeof MediaSeekBackwardButton\n>\n\nexport const AudioPlayerSeekBackwardButton = ({\n  seekOffset = 10,\n  ...props\n}: AudioPlayerSeekBackwardButtonProps) => (\n  <Button asChild size=\"icon-sm\" variant=\"outline\">\n    <MediaSeekBackwardButton\n      data-slot=\"audio-player-seek-backward-button\"\n      seekOffset={seekOffset}\n      {...props}\n    />\n  </Button>\n)\n\nexport type AudioPlayerSeekForwardButtonProps = ComponentProps<\n  typeof MediaSeekForwardButton\n>\n\nexport const AudioPlayerSeekForwardButton = ({\n  seekOffset = 10,\n  ...props\n}: AudioPlayerSeekForwardButtonProps) => (\n  <Button asChild size=\"icon-sm\" variant=\"outline\">\n    <MediaSeekForwardButton\n      data-slot=\"audio-player-seek-forward-button\"\n      seekOffset={seekOffset}\n      {...props}\n    />\n  </Button>\n)\n\nexport type AudioPlayerTimeDisplayProps = ComponentProps<\n  typeof MediaTimeDisplay\n>\n\nexport const AudioPlayerTimeDisplay = ({\n  className,\n  ...props\n}: AudioPlayerTimeDisplayProps) => (\n  <ButtonGroupText asChild className=\"bg-transparent\">\n    <MediaTimeDisplay\n      className={cn(\"tabular-nums\", className)}\n      data-slot=\"audio-player-time-display\"\n      {...props}\n    />\n  </ButtonGroupText>\n)\n\nexport type AudioPlayerTimeRangeProps = ComponentProps<typeof MediaTimeRange>\n\nexport const AudioPlayerTimeRange = ({\n  className,\n  ...props\n}: AudioPlayerTimeRangeProps) => (\n  <ButtonGroupText asChild className=\"bg-transparent\">\n    <MediaTimeRange\n      className={cn(\"min-w-0 flex-1\", className)}\n      data-slot=\"audio-player-time-range\"\n      {...props}\n    />\n  </ButtonGroupText>\n)\n\nexport type AudioPlayerDurationDisplayProps = ComponentProps<\n  typeof MediaDurationDisplay\n>\n\nexport const AudioPlayerDurationDisplay = ({\n  className,\n  ...props\n}: AudioPlayerDurationDisplayProps) => (\n  <ButtonGroupText asChild className=\"bg-transparent\">\n    <MediaDurationDisplay\n      className={cn(\"tabular-nums\", className)}\n      data-slot=\"audio-player-duration-display\"\n      {...props}\n    />\n  </ButtonGroupText>\n)\n\nexport type AudioPlayerMuteButtonProps = ComponentProps<typeof MediaMuteButton>\n\nexport const AudioPlayerMuteButton = ({\n  className,\n  ...props\n}: AudioPlayerMuteButtonProps) => (\n  <ButtonGroupText asChild className=\"bg-transparent\">\n    <MediaMuteButton\n      className={cn(\"\", className)}\n      data-slot=\"audio-player-mute-button\"\n      {...props}\n    />\n  </ButtonGroupText>\n)\n\nexport type AudioPlayerVolumeRangeProps = ComponentProps<\n  typeof MediaVolumeRange\n>\n\nexport const AudioPlayerVolumeRange = ({\n  className,\n  ...props\n}: AudioPlayerVolumeRangeProps) => (\n  <ButtonGroupText asChild className=\"bg-transparent\">\n    <MediaVolumeRange\n      className={cn(\"min-w-0 flex-1\", className)}\n      data-slot=\"audio-player-volume-range\"\n      {...props}\n    />\n  </ButtonGroupText>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button-group.tsx",
          "target": "@components/ai-elements/_ui/button-group.tsx",
          "type": "registry:component",
          "content": "import { Separator } from \"@/components/ai-elements/_ui/separator\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\n\nconst buttonGroupVariants = cva(\n  \"flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2\",\n  {\n    variants: {\n      orientation: {\n        horizontal:\n          \"[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none\",\n        vertical:\n          \"flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none\",\n      },\n    },\n    defaultVariants: {\n      orientation: \"horizontal\",\n    },\n  }\n)\n\nfunction ButtonGroup({\n  className,\n  orientation,\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof buttonGroupVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"button-group\"\n      data-orientation={orientation}\n      className={cn(buttonGroupVariants({ orientation }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction ButtonGroupText({\n  className,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  asChild?: boolean\n}) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"div\"\n\n  return (\n    <Comp\n      className={cn(\n        \"bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ButtonGroupSeparator({\n  className,\n  orientation = \"vertical\",\n  ...props\n}: React.ComponentProps<typeof Separator>) {\n  return (\n    <Separator\n      data-slot=\"button-group-separator\"\n      orientation={orientation}\n      className={cn(\n        \"bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  ButtonGroup,\n  ButtonGroupSeparator,\n  ButtonGroupText,\n  buttonGroupVariants,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/separator.tsx",
          "target": "@components/ai-elements/_ui/separator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Separator as SeparatorPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Separator({\n  className,\n  orientation = \"horizontal\",\n  decorative = true,\n  ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n  return (\n    <SeparatorPrimitive.Root\n      data-slot=\"separator\"\n      decorative={decorative}\n      orientation={orientation}\n      className={cn(\n        \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Separator }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-canvas",
      "type": "registry:block",
      "title": "Ai Elements Canvas",
      "description": "canvas",
      "dependencies": [
        "@xyflow/react@12.10.0",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/canvas.tsx",
          "target": "@components/ai-elements/canvas.tsx",
          "type": "registry:component",
          "content": "import type { ReactFlowProps } from \"@xyflow/react\"\nimport { Background, ReactFlow } from \"@xyflow/react\"\nimport type { ReactNode } from \"react\"\nimport \"@xyflow/react/dist/style.css\"\n\ntype CanvasProps = ReactFlowProps & {\n  children?: ReactNode\n}\n\nconst deleteKeyCode = [\"Backspace\", \"Delete\"]\n\nexport const Canvas = ({ children, ...props }: CanvasProps) => (\n  <ReactFlow\n    deleteKeyCode={deleteKeyCode}\n    fitView\n    panOnDrag={false}\n    panOnScroll\n    selectionOnDrag={true}\n    zoomOnDoubleClick={false}\n    {...props}\n  >\n    <Background bgColor=\"var(--sidebar)\" />\n    {children}\n  </ReactFlow>\n)\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-chain-of-thought",
      "type": "registry:block",
      "title": "Ai Elements Chain Of Thought",
      "description": "chain of thought",
      "dependencies": [
        "@radix-ui/react-use-controllable-state@1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/chain-of-thought.tsx",
          "target": "@components/ai-elements/chain-of-thought.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\"\nimport type { LucideIcon } from \"lucide-react\"\nimport { BrainIcon, ChevronDownIcon, DotIcon } from \"lucide-react\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport { createContext, memo, useContext, useMemo } from \"react\"\n\ninterface ChainOfThoughtContextValue {\n  isOpen: boolean\n  setIsOpen: (open: boolean) => void\n}\n\nconst ChainOfThoughtContext = createContext<ChainOfThoughtContextValue | null>(\n  null\n)\n\nconst useChainOfThought = () => {\n  const context = useContext(ChainOfThoughtContext)\n  if (!context) {\n    throw new Error(\n      \"ChainOfThought components must be used within ChainOfThought\"\n    )\n  }\n  return context\n}\n\nexport type ChainOfThoughtProps = ComponentProps<\"div\"> & {\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nexport const ChainOfThought = memo(\n  ({\n    className,\n    open,\n    defaultOpen = false,\n    onOpenChange,\n    children,\n    ...props\n  }: ChainOfThoughtProps) => {\n    const [isOpen, setIsOpen] = useControllableState({\n      defaultProp: defaultOpen,\n      onChange: onOpenChange,\n      prop: open,\n    })\n\n    const chainOfThoughtContext = useMemo(\n      () => ({ isOpen, setIsOpen }),\n      [isOpen, setIsOpen]\n    )\n\n    return (\n      <ChainOfThoughtContext.Provider value={chainOfThoughtContext}>\n        <div className={cn(\"not-prose w-full space-y-4\", className)} {...props}>\n          {children}\n        </div>\n      </ChainOfThoughtContext.Provider>\n    )\n  }\n)\n\nexport type ChainOfThoughtHeaderProps = ComponentProps<\n  typeof CollapsibleTrigger\n>\n\nexport const ChainOfThoughtHeader = memo(\n  ({ className, children, ...props }: ChainOfThoughtHeaderProps) => {\n    const { isOpen, setIsOpen } = useChainOfThought()\n\n    return (\n      <Collapsible onOpenChange={setIsOpen} open={isOpen}>\n        <CollapsibleTrigger\n          className={cn(\n            \"text-muted-foreground hover:text-foreground flex w-full items-center gap-2 text-sm transition-colors\",\n            className\n          )}\n          {...props}\n        >\n          <BrainIcon className=\"size-4\" />\n          <span className=\"flex-1 text-left\">\n            {children ?? \"Chain of Thought\"}\n          </span>\n          <ChevronDownIcon\n            className={cn(\n              \"size-4 transition-transform\",\n              isOpen ? \"rotate-180\" : \"rotate-0\"\n            )}\n          />\n        </CollapsibleTrigger>\n      </Collapsible>\n    )\n  }\n)\n\nexport type ChainOfThoughtStepProps = ComponentProps<\"div\"> & {\n  icon?: LucideIcon\n  label: ReactNode\n  description?: ReactNode\n  status?: \"complete\" | \"active\" | \"pending\"\n}\n\nconst stepStatusStyles = {\n  active: \"text-foreground\",\n  complete: \"text-muted-foreground\",\n  pending: \"text-muted-foreground/50\",\n}\n\nexport const ChainOfThoughtStep = memo(\n  ({\n    className,\n    icon: Icon = DotIcon,\n    label,\n    description,\n    status = \"complete\",\n    children,\n    ...props\n  }: ChainOfThoughtStepProps) => (\n    <div\n      className={cn(\n        \"flex gap-2 text-sm\",\n        stepStatusStyles[status],\n        \"fade-in-0 slide-in-from-top-2 animate-in\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"relative mt-0.5\">\n        <Icon className=\"size-4\" />\n        <div className=\"bg-border absolute top-7 bottom-0 left-1/2 -mx-px w-px\" />\n      </div>\n      <div className=\"flex-1 space-y-2 overflow-hidden\">\n        <div>{label}</div>\n        {description && (\n          <div className=\"text-muted-foreground text-xs\">{description}</div>\n        )}\n        {children}\n      </div>\n    </div>\n  )\n)\n\nexport type ChainOfThoughtSearchResultsProps = ComponentProps<\"div\">\n\nexport const ChainOfThoughtSearchResults = memo(\n  ({ className, ...props }: ChainOfThoughtSearchResultsProps) => (\n    <div\n      className={cn(\"flex flex-wrap items-center gap-2\", className)}\n      {...props}\n    />\n  )\n)\n\nexport type ChainOfThoughtSearchResultProps = ComponentProps<typeof Badge>\n\nexport const ChainOfThoughtSearchResult = memo(\n  ({ className, children, ...props }: ChainOfThoughtSearchResultProps) => (\n    <Badge\n      className={cn(\"gap-1 px-2 py-0.5 text-xs font-normal\", className)}\n      variant=\"secondary\"\n      {...props}\n    >\n      {children}\n    </Badge>\n  )\n)\n\nexport type ChainOfThoughtContentProps = ComponentProps<\n  typeof CollapsibleContent\n>\n\nexport const ChainOfThoughtContent = memo(\n  ({ className, children, ...props }: ChainOfThoughtContentProps) => {\n    const { isOpen } = useChainOfThought()\n\n    return (\n      <Collapsible open={isOpen}>\n        <CollapsibleContent\n          className={cn(\n            \"mt-2 space-y-3\",\n            \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground data-[state=closed]:animate-out data-[state=open]:animate-in outline-none\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </CollapsibleContent>\n      </Collapsible>\n    )\n  }\n)\n\nexport type ChainOfThoughtImageProps = ComponentProps<\"div\"> & {\n  caption?: string\n}\n\nexport const ChainOfThoughtImage = memo(\n  ({ className, children, caption, ...props }: ChainOfThoughtImageProps) => (\n    <div className={cn(\"mt-2 space-y-2\", className)} {...props}>\n      <div className=\"bg-muted relative flex max-h-[22rem] items-center justify-center overflow-hidden rounded-lg p-3\">\n        {children}\n      </div>\n      {caption && <p className=\"text-muted-foreground text-xs\">{caption}</p>}\n    </div>\n  )\n)\n\nChainOfThought.displayName = \"ChainOfThought\"\nChainOfThoughtHeader.displayName = \"ChainOfThoughtHeader\"\nChainOfThoughtStep.displayName = \"ChainOfThoughtStep\"\nChainOfThoughtSearchResults.displayName = \"ChainOfThoughtSearchResults\"\nChainOfThoughtSearchResult.displayName = \"ChainOfThoughtSearchResult\"\nChainOfThoughtContent.displayName = \"ChainOfThoughtContent\"\nChainOfThoughtImage.displayName = \"ChainOfThoughtImage\"\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-checkpoint",
      "type": "registry:block",
      "title": "Ai Elements Checkpoint",
      "description": "checkpoint",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/checkpoint.tsx",
          "target": "@components/ai-elements/checkpoint.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { Separator } from \"@/components/ai-elements/_ui/separator\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipTrigger,\n} from \"@/components/ai-elements/_ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport type { LucideProps } from \"lucide-react\"\nimport { BookmarkIcon } from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\n\nexport type CheckpointProps = HTMLAttributes<HTMLDivElement>\n\nexport const Checkpoint = ({\n  className,\n  children,\n  ...props\n}: CheckpointProps) => (\n  <div\n    className={cn(\n      \"text-muted-foreground flex items-center gap-0.5 overflow-hidden\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n    <Separator />\n  </div>\n)\n\nexport type CheckpointIconProps = LucideProps\n\nexport const CheckpointIcon = ({\n  className,\n  children,\n  ...props\n}: CheckpointIconProps) =>\n  children ?? (\n    <BookmarkIcon className={cn(\"size-4 shrink-0\", className)} {...props} />\n  )\n\nexport type CheckpointTriggerProps = ComponentProps<typeof Button> & {\n  tooltip?: string\n}\n\nexport const CheckpointTrigger = ({\n  children,\n  variant = \"ghost\",\n  size = \"sm\",\n  tooltip,\n  ...props\n}: CheckpointTriggerProps) =>\n  tooltip ? (\n    <Tooltip>\n      <TooltipTrigger asChild>\n        <Button size={size} type=\"button\" variant={variant} {...props}>\n          {children}\n        </Button>\n      </TooltipTrigger>\n      <TooltipContent align=\"start\" side=\"bottom\">\n        {tooltip}\n      </TooltipContent>\n    </Tooltip>\n  ) : (\n    <Button size={size} type=\"button\" variant={variant} {...props}>\n      {children}\n    </Button>\n  )\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/separator.tsx",
          "target": "@components/ai-elements/_ui/separator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Separator as SeparatorPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Separator({\n  className,\n  orientation = \"horizontal\",\n  decorative = true,\n  ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n  return (\n    <SeparatorPrimitive.Root\n      data-slot=\"separator\"\n      decorative={decorative}\n      orientation={orientation}\n      className={cn(\n        \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Separator }\n"
        },
        {
          "path": "components/ai-elements/_ui/tooltip.tsx",
          "target": "@components/ai-elements/_ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 0,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-code-block",
      "type": "registry:block",
      "title": "Ai Elements Code Block",
      "description": "code block",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/code-block.tsx",
          "target": "@components/ai-elements/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ai-elements/_ui/select\"\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, CopyIcon } from \"lucide-react\"\nimport type { ComponentProps, CSSProperties, HTMLAttributes } from \"react\"\nimport {\n  createContext,\n  memo,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport type {\n  BundledLanguage,\n  BundledTheme,\n  HighlighterGeneric,\n  ThemedToken,\n} from \"shiki\"\nimport { createHighlighter } from \"shiki\"\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2\nconst isUnderline = (fontStyle: number | undefined) =>\n  // oxlint-disable-next-line eslint(no-bitwise)\n  fontStyle && fontStyle & 4\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n  token: ThemedToken\n  key: string\n}\ninterface KeyedLine {\n  tokens: KeyedToken[]\n  key: string\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n  lines.map((line, lineIdx) => ({\n    key: `line-${lineIdx}`,\n    tokens: line.map((token, tokenIdx) => ({\n      key: `line-${lineIdx}-${tokenIdx}`,\n      token,\n    })),\n  }))\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n  <span\n    className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n    style={\n      {\n        backgroundColor: token.bgColor,\n        color: token.color,\n        fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n        fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n        textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n        ...token.htmlStyle,\n      } as CSSProperties\n    }\n  >\n    {token.content}\n  </span>\n)\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n  \"block\",\n  \"before:content-[counter(line)]\",\n  \"before:inline-block\",\n  \"before:[counter-increment:line]\",\n  \"before:w-8\",\n  \"before:mr-4\",\n  \"before:text-right\",\n  \"before:text-muted-foreground/50\",\n  \"before:font-mono\",\n  \"before:select-none\"\n)\n\n// Line rendering component\nconst LineSpan = ({\n  keyedLine,\n  showLineNumbers,\n}: {\n  keyedLine: KeyedLine\n  showLineNumbers: boolean\n}) => (\n  <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n    {keyedLine.tokens.length === 0\n      ? \"\\n\"\n      : keyedLine.tokens.map(({ token, key }) => (\n          <TokenSpan key={key} token={token} />\n        ))}\n  </span>\n)\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n  code: string\n  language: BundledLanguage\n  showLineNumbers?: boolean\n}\n\ninterface TokenizedCode {\n  tokens: ThemedToken[][]\n  fg: string\n  bg: string\n}\n\ninterface CodeBlockContextType {\n  code: string\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n  code: \"\",\n})\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n  string,\n  Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>()\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>()\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>()\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n  const start = code.slice(0, 100)\n  const end = code.length > 100 ? code.slice(-100) : \"\"\n  return `${language}:${code.length}:${start}:${end}`\n}\n\nconst getHighlighter = (\n  language: BundledLanguage\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n  const cached = highlighterCache.get(language)\n  if (cached) {\n    return cached\n  }\n\n  const highlighterPromise = createHighlighter({\n    langs: [language],\n    themes: [\"github-light\", \"github-dark\"],\n  })\n\n  highlighterCache.set(language, highlighterPromise)\n  return highlighterPromise\n}\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n  bg: \"transparent\",\n  fg: \"inherit\",\n  tokens: code.split(\"\\n\").map((line) =>\n    line === \"\"\n      ? []\n      : [\n          {\n            color: \"inherit\",\n            content: line,\n          } as ThemedToken,\n        ]\n  ),\n})\n\n// Synchronous highlight with callback for async results\nexport const highlightCode = (\n  code: string,\n  language: BundledLanguage,\n  // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-callbacks)\n  callback?: (result: TokenizedCode) => void\n): TokenizedCode | null => {\n  const tokensCacheKey = getTokensCacheKey(code, language)\n\n  // Return cached result if available\n  const cached = tokensCache.get(tokensCacheKey)\n  if (cached) {\n    return cached\n  }\n\n  // Subscribe callback if provided\n  if (callback) {\n    if (!subscribers.has(tokensCacheKey)) {\n      subscribers.set(tokensCacheKey, new Set())\n    }\n    subscribers.get(tokensCacheKey)?.add(callback)\n  }\n\n  // Start highlighting in background - fire-and-forget async pattern\n  getHighlighter(language)\n    // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then)\n    .then((highlighter) => {\n      const availableLangs = highlighter.getLoadedLanguages()\n      const langToUse = availableLangs.includes(language) ? language : \"text\"\n\n      const result = highlighter.codeToTokens(code, {\n        lang: langToUse,\n        themes: {\n          dark: \"github-dark\",\n          light: \"github-light\",\n        },\n      })\n\n      const tokenized: TokenizedCode = {\n        bg: result.bg ?? \"transparent\",\n        fg: result.fg ?? \"inherit\",\n        tokens: result.tokens,\n      }\n\n      // Cache the result\n      tokensCache.set(tokensCacheKey, tokenized)\n\n      // Notify all subscribers\n      const subs = subscribers.get(tokensCacheKey)\n      if (subs) {\n        for (const sub of subs) {\n          sub(tokenized)\n        }\n        subscribers.delete(tokensCacheKey)\n      }\n    })\n    // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then), eslint-plugin-promise(prefer-await-to-callbacks)\n    .catch((error) => {\n      console.error(\"Failed to highlight code:\", error)\n      subscribers.delete(tokensCacheKey)\n    })\n\n  return null\n}\n\nconst CodeBlockBody = memo(\n  ({\n    tokenized,\n    showLineNumbers,\n    className,\n  }: {\n    tokenized: TokenizedCode\n    showLineNumbers: boolean\n    className?: string\n  }) => {\n    const preStyle = useMemo(\n      () => ({\n        backgroundColor: tokenized.bg,\n        color: tokenized.fg,\n      }),\n      [tokenized.bg, tokenized.fg]\n    )\n\n    const keyedLines = useMemo(\n      () => addKeysToTokens(tokenized.tokens),\n      [tokenized.tokens]\n    )\n\n    return (\n      <pre\n        className={cn(\n          \"m-0 p-4 text-sm dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\",\n          className\n        )}\n        style={preStyle}\n      >\n        <code\n          className={cn(\n            \"font-mono text-sm\",\n            showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\"\n          )}\n        >\n          {keyedLines.map((keyedLine) => (\n            <LineSpan\n              key={keyedLine.key}\n              keyedLine={keyedLine}\n              showLineNumbers={showLineNumbers}\n            />\n          ))}\n        </code>\n      </pre>\n    )\n  },\n  (prevProps, nextProps) =>\n    prevProps.tokenized === nextProps.tokenized &&\n    prevProps.showLineNumbers === nextProps.showLineNumbers &&\n    prevProps.className === nextProps.className\n)\n\nCodeBlockBody.displayName = \"CodeBlockBody\"\n\nexport const CodeBlockContainer = ({\n  className,\n  language,\n  style,\n  ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n  <div\n    className={cn(\n      \"group bg-background text-foreground relative w-full overflow-hidden rounded-md border\",\n      className\n    )}\n    data-language={language}\n    style={{\n      containIntrinsicSize: \"auto 200px\",\n      contentVisibility: \"auto\",\n      ...style,\n    }}\n    {...props}\n  />\n)\n\nexport const CodeBlockHeader = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"bg-muted/80 text-muted-foreground flex items-center justify-between border-b px-3 py-2 text-xs\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport const CodeBlockTitle = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport const CodeBlockFilename = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n  <span className={cn(\"font-mono\", className)} {...props}>\n    {children}\n  </span>\n)\n\nexport const CodeBlockActions = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport const CodeBlockContent = ({\n  code,\n  language,\n  showLineNumbers = false,\n}: {\n  code: string\n  language: BundledLanguage\n  showLineNumbers?: boolean\n}) => {\n  // Memoized raw tokens for immediate display\n  const rawTokens = useMemo(() => createRawTokens(code), [code])\n\n  // Synchronous cache lookup — avoids setState in effect for cached results\n  const syncTokens = useMemo(\n    () => highlightCode(code, language) ?? rawTokens,\n    [code, language, rawTokens]\n  )\n\n  // Async highlighting result (populated after shiki loads)\n  const [asyncTokens, setAsyncTokens] = useState<TokenizedCode | null>(null)\n  const asyncKeyRef = useRef({ code, language })\n\n  // Invalidate stale async tokens synchronously during render\n  if (\n    asyncKeyRef.current.code !== code ||\n    asyncKeyRef.current.language !== language\n  ) {\n    asyncKeyRef.current = { code, language }\n    setAsyncTokens(null)\n  }\n\n  useEffect(() => {\n    let cancelled = false\n\n    highlightCode(code, language, (result) => {\n      if (!cancelled) {\n        setAsyncTokens(result)\n      }\n    })\n\n    return () => {\n      cancelled = true\n    }\n  }, [code, language])\n\n  const tokenized = asyncTokens ?? syncTokens\n\n  return (\n    <div className=\"relative overflow-auto\">\n      <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n    </div>\n  )\n}\n\nexport const CodeBlock = ({\n  code,\n  language,\n  showLineNumbers = false,\n  className,\n  children,\n  ...props\n}: CodeBlockProps) => {\n  const contextValue = useMemo(() => ({ code }), [code])\n\n  return (\n    <CodeBlockContext.Provider value={contextValue}>\n      <CodeBlockContainer className={className} language={language} {...props}>\n        {children}\n        <CodeBlockContent\n          code={code}\n          language={language}\n          showLineNumbers={showLineNumbers}\n        />\n      </CodeBlockContainer>\n    </CodeBlockContext.Provider>\n  )\n}\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const CodeBlockCopyButton = ({\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  className,\n  ...props\n}: CodeBlockCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n  const { code } = useContext(CodeBlockContext)\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      if (!isCopied) {\n        await navigator.clipboard.writeText(code)\n        setIsCopied(true)\n        onCopy?.()\n        timeoutRef.current = window.setTimeout(\n          () => setIsCopied(false),\n          timeout\n        )\n      }\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [code, onCopy, onError, timeout, isCopied])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <Button\n      className={cn(\"shrink-0\", className)}\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>\n\nexport const CodeBlockLanguageSelector = (\n  props: CodeBlockLanguageSelectorProps\n) => <Select {...props} />\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<\n  typeof SelectTrigger\n>\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n  className,\n  ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n  <SelectTrigger\n    className={cn(\n      \"h-7 border-none bg-transparent px-2 text-xs shadow-none\",\n      className\n    )}\n    size=\"sm\"\n    {...props}\n  />\n)\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<\n  typeof SelectValue\n>\n\nexport const CodeBlockLanguageSelectorValue = (\n  props: CodeBlockLanguageSelectorValueProps\n) => <SelectValue {...props} />\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<\n  typeof SelectContent\n>\n\nexport const CodeBlockLanguageSelectorContent = ({\n  align = \"end\",\n  ...props\n}: CodeBlockLanguageSelectorContentProps) => (\n  <SelectContent align={align} {...props} />\n)\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<\n  typeof SelectItem\n>\n\nexport const CodeBlockLanguageSelectorItem = (\n  props: CodeBlockLanguageSelectorItemProps\n) => <SelectItem {...props} />\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/select.tsx",
          "target": "@components/ai-elements/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"popper\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-commit",
      "type": "registry:block",
      "title": "Ai Elements Commit",
      "description": "commit",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/commit.tsx",
          "target": "@components/ai-elements/commit.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Avatar, AvatarFallback } from \"@/components/ai-elements/_ui/avatar\"\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  CheckIcon,\n  CopyIcon,\n  FileIcon,\n  GitCommitIcon,\n  MinusIcon,\n  PlusIcon,\n} from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nexport type CommitProps = ComponentProps<typeof Collapsible>\n\nexport const Commit = ({ className, children, ...props }: CommitProps) => (\n  <Collapsible\n    className={cn(\"bg-background rounded-lg border\", className)}\n    {...props}\n  >\n    {children}\n  </Collapsible>\n)\n\nexport type CommitHeaderProps = ComponentProps<typeof CollapsibleTrigger>\n\nexport const CommitHeader = ({\n  className,\n  children,\n  ...props\n}: CommitHeaderProps) => (\n  <CollapsibleTrigger asChild {...props}>\n    <div\n      className={cn(\n        \"group flex cursor-pointer items-center justify-between gap-4 p-3 text-left transition-colors hover:opacity-80\",\n        className\n      )}\n    >\n      {children}\n    </div>\n  </CollapsibleTrigger>\n)\n\nexport type CommitHashProps = HTMLAttributes<HTMLSpanElement>\n\nexport const CommitHash = ({\n  className,\n  children,\n  ...props\n}: CommitHashProps) => (\n  <span className={cn(\"font-mono text-xs\", className)} {...props}>\n    <GitCommitIcon className=\"mr-1 inline-block size-3\" />\n    {children}\n  </span>\n)\n\nexport type CommitMessageProps = HTMLAttributes<HTMLSpanElement>\n\nexport const CommitMessage = ({\n  className,\n  children,\n  ...props\n}: CommitMessageProps) => (\n  <span className={cn(\"text-sm font-medium\", className)} {...props}>\n    {children}\n  </span>\n)\n\nexport type CommitMetadataProps = HTMLAttributes<HTMLDivElement>\n\nexport const CommitMetadata = ({\n  className,\n  children,\n  ...props\n}: CommitMetadataProps) => (\n  <div\n    className={cn(\n      \"text-muted-foreground flex items-center gap-2 text-xs\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type CommitSeparatorProps = HTMLAttributes<HTMLSpanElement>\n\nexport const CommitSeparator = ({\n  className,\n  children,\n  ...props\n}: CommitSeparatorProps) => (\n  <span className={className} {...props}>\n    {children ?? \"•\"}\n  </span>\n)\n\nexport type CommitInfoProps = HTMLAttributes<HTMLDivElement>\n\nexport const CommitInfo = ({\n  className,\n  children,\n  ...props\n}: CommitInfoProps) => (\n  <div className={cn(\"flex flex-1 flex-col\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type CommitAuthorProps = HTMLAttributes<HTMLDivElement>\n\nexport const CommitAuthor = ({\n  className,\n  children,\n  ...props\n}: CommitAuthorProps) => (\n  <div className={cn(\"flex items-center\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type CommitAuthorAvatarProps = ComponentProps<typeof Avatar> & {\n  initials: string\n}\n\nexport const CommitAuthorAvatar = ({\n  initials,\n  className,\n  ...props\n}: CommitAuthorAvatarProps) => (\n  <Avatar className={cn(\"size-8\", className)} {...props}>\n    <AvatarFallback className=\"text-xs\">{initials}</AvatarFallback>\n  </Avatar>\n)\n\nexport type CommitTimestampProps = HTMLAttributes<HTMLTimeElement> & {\n  date: Date\n}\n\nconst relativeTimeFormat = new Intl.RelativeTimeFormat(\"en\", {\n  numeric: \"auto\",\n})\n\nconst formatRelativeDate = (date: Date) => {\n  const days = Math.round((date.getTime() - Date.now()) / (1000 * 60 * 60 * 24))\n  return relativeTimeFormat.format(days, \"day\")\n}\n\nexport const CommitTimestamp = ({\n  date,\n  className,\n  children,\n  ...props\n}: CommitTimestampProps) => {\n  const [formatted, setFormatted] = useState(\"\")\n\n  const updateFormatted = useCallback(() => {\n    setFormatted(formatRelativeDate(date))\n  }, [date])\n\n  useEffect(() => {\n    updateFormatted()\n  }, [updateFormatted])\n\n  return (\n    <time\n      className={cn(\"text-xs\", className)}\n      dateTime={date.toISOString()}\n      {...props}\n    >\n      {children ?? formatted}\n    </time>\n  )\n}\n\nexport type CommitActionsProps = HTMLAttributes<HTMLDivElement>\n\nconst handleActionsClick = (e: React.MouseEvent) => e.stopPropagation()\nconst handleActionsKeyDown = (e: React.KeyboardEvent) => e.stopPropagation()\n\nexport const CommitActions = ({\n  className,\n  children,\n  ...props\n}: CommitActionsProps) => (\n  <div\n    className={cn(\"flex items-center gap-1\", className)}\n    onClick={handleActionsClick}\n    onKeyDown={handleActionsKeyDown}\n    role=\"group\"\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type CommitCopyButtonProps = ComponentProps<typeof Button> & {\n  hash: string\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const CommitCopyButton = ({\n  hash,\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  className,\n  ...props\n}: CommitCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      if (!isCopied) {\n        await navigator.clipboard.writeText(hash)\n        setIsCopied(true)\n        onCopy?.()\n        timeoutRef.current = window.setTimeout(\n          () => setIsCopied(false),\n          timeout\n        )\n      }\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [hash, onCopy, onError, timeout, isCopied])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <Button\n      className={cn(\"size-7 shrink-0\", className)}\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type CommitContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const CommitContent = ({\n  className,\n  children,\n  ...props\n}: CommitContentProps) => (\n  <CollapsibleContent className={cn(\"border-t p-3\", className)} {...props}>\n    {children}\n  </CollapsibleContent>\n)\n\nexport type CommitFilesProps = HTMLAttributes<HTMLDivElement>\n\nexport const CommitFiles = ({\n  className,\n  children,\n  ...props\n}: CommitFilesProps) => (\n  <div className={cn(\"space-y-1\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type CommitFileProps = HTMLAttributes<HTMLDivElement>\n\nexport const CommitFile = ({\n  className,\n  children,\n  ...props\n}: CommitFileProps) => (\n  <div\n    className={cn(\n      \"hover:bg-muted/50 flex items-center justify-between gap-2 rounded px-2 py-1 text-sm\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type CommitFileInfoProps = HTMLAttributes<HTMLDivElement>\n\nexport const CommitFileInfo = ({\n  className,\n  children,\n  ...props\n}: CommitFileInfoProps) => (\n  <div className={cn(\"flex min-w-0 items-center gap-2\", className)} {...props}>\n    {children}\n  </div>\n)\n\nconst fileStatusStyles = {\n  added: \"text-green-600 dark:text-green-400\",\n  deleted: \"text-red-600 dark:text-red-400\",\n  modified: \"text-yellow-600 dark:text-yellow-400\",\n  renamed: \"text-blue-600 dark:text-blue-400\",\n}\n\nconst fileStatusLabels = {\n  added: \"A\",\n  deleted: \"D\",\n  modified: \"M\",\n  renamed: \"R\",\n}\n\nexport type CommitFileStatusProps = HTMLAttributes<HTMLSpanElement> & {\n  status: \"added\" | \"modified\" | \"deleted\" | \"renamed\"\n}\n\nexport const CommitFileStatus = ({\n  status,\n  className,\n  children,\n  ...props\n}: CommitFileStatusProps) => (\n  <span\n    className={cn(\n      \"font-mono text-xs font-medium\",\n      fileStatusStyles[status],\n      className\n    )}\n    {...props}\n  >\n    {children ?? fileStatusLabels[status]}\n  </span>\n)\n\nexport type CommitFileIconProps = ComponentProps<typeof FileIcon>\n\nexport const CommitFileIcon = ({\n  className,\n  ...props\n}: CommitFileIconProps) => (\n  <FileIcon\n    className={cn(\"text-muted-foreground size-3.5 shrink-0\", className)}\n    {...props}\n  />\n)\n\nexport type CommitFilePathProps = HTMLAttributes<HTMLSpanElement>\n\nexport const CommitFilePath = ({\n  className,\n  children,\n  ...props\n}: CommitFilePathProps) => (\n  <span className={cn(\"truncate font-mono text-xs\", className)} {...props}>\n    {children}\n  </span>\n)\n\nexport type CommitFileChangesProps = HTMLAttributes<HTMLDivElement>\n\nexport const CommitFileChanges = ({\n  className,\n  children,\n  ...props\n}: CommitFileChangesProps) => (\n  <div\n    className={cn(\n      \"flex shrink-0 items-center gap-1 font-mono text-xs\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type CommitFileAdditionsProps = HTMLAttributes<HTMLSpanElement> & {\n  count: number\n}\n\nexport const CommitFileAdditions = ({\n  count,\n  className,\n  children,\n  ...props\n}: CommitFileAdditionsProps) => {\n  if (count <= 0) {\n    return null\n  }\n\n  return (\n    <span\n      className={cn(\"text-green-600 dark:text-green-400\", className)}\n      {...props}\n    >\n      {children ?? (\n        <>\n          <PlusIcon className=\"inline-block size-3\" />\n          {count}\n        </>\n      )}\n    </span>\n  )\n}\n\nexport type CommitFileDeletionsProps = HTMLAttributes<HTMLSpanElement> & {\n  count: number\n}\n\nexport const CommitFileDeletions = ({\n  count,\n  className,\n  children,\n  ...props\n}: CommitFileDeletionsProps) => {\n  if (count <= 0) {\n    return null\n  }\n\n  return (\n    <span\n      className={cn(\"text-red-600 dark:text-red-400\", className)}\n      {...props}\n    >\n      {children ?? (\n        <>\n          <MinusIcon className=\"inline-block size-3\" />\n          {count}\n        </>\n      )}\n    </span>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/avatar.tsx",
          "target": "@components/ai-elements/_ui/avatar.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar as AvatarPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Avatar({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n  return (\n    <AvatarPrimitive.Root\n      data-slot=\"avatar\"\n      className={cn(\n        \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarImage({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n  return (\n    <AvatarPrimitive.Image\n      data-slot=\"avatar-image\"\n      className={cn(\"aspect-square size-full\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction AvatarFallback({\n  className,\n  ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n  return (\n    <AvatarPrimitive.Fallback\n      data-slot=\"avatar-fallback\"\n      className={cn(\n        \"bg-muted flex size-full items-center justify-center rounded-full\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Avatar, AvatarImage, AvatarFallback }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-confirmation",
      "type": "registry:block",
      "title": "Ai Elements Confirmation",
      "description": "confirmation",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/confirmation.tsx",
          "target": "@components/ai-elements/confirmation.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Alert, AlertDescription } from \"@/components/ai-elements/_ui/alert\"\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport type { ToolUIPart } from \"ai\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport { createContext, useContext, useMemo } from \"react\"\n\ntype ToolUIPartApproval =\n  | {\n      id: string\n      approved?: never\n      reason?: never\n    }\n  | {\n      id: string\n      approved: boolean\n      reason?: string\n    }\n  | {\n      id: string\n      approved: true\n      reason?: string\n    }\n  | {\n      id: string\n      approved: false\n      reason?: string\n    }\n  | undefined\n\ninterface ConfirmationContextValue {\n  approval: ToolUIPartApproval\n  state: ToolUIPart[\"state\"]\n}\n\nconst ConfirmationContext = createContext<ConfirmationContextValue | null>(null)\n\nconst useConfirmation = () => {\n  const context = useContext(ConfirmationContext)\n\n  if (!context) {\n    throw new Error(\"Confirmation components must be used within Confirmation\")\n  }\n\n  return context\n}\n\nexport type ConfirmationProps = ComponentProps<typeof Alert> & {\n  approval?: ToolUIPartApproval\n  state: ToolUIPart[\"state\"]\n}\n\nexport const Confirmation = ({\n  className,\n  approval,\n  state,\n  ...props\n}: ConfirmationProps) => {\n  const contextValue = useMemo(() => ({ approval, state }), [approval, state])\n\n  if (!approval || state === \"input-streaming\" || state === \"input-available\") {\n    return null\n  }\n\n  return (\n    <ConfirmationContext.Provider value={contextValue}>\n      <Alert className={cn(\"flex flex-col gap-2\", className)} {...props} />\n    </ConfirmationContext.Provider>\n  )\n}\n\nexport type ConfirmationTitleProps = ComponentProps<typeof AlertDescription>\n\nexport const ConfirmationTitle = ({\n  className,\n  ...props\n}: ConfirmationTitleProps) => (\n  <AlertDescription className={cn(\"inline\", className)} {...props} />\n)\n\nexport interface ConfirmationRequestProps {\n  children?: ReactNode\n}\n\nexport const ConfirmationRequest = ({ children }: ConfirmationRequestProps) => {\n  const { state } = useConfirmation()\n\n  // Only show when approval is requested\n  if (state !== \"approval-requested\") {\n    return null\n  }\n\n  return children\n}\n\nexport interface ConfirmationAcceptedProps {\n  children?: ReactNode\n}\n\nexport const ConfirmationAccepted = ({\n  children,\n}: ConfirmationAcceptedProps) => {\n  const { approval, state } = useConfirmation()\n\n  // Only show when approved and in response states\n  if (\n    !approval?.approved ||\n    (state !== \"approval-responded\" &&\n      state !== \"output-denied\" &&\n      state !== \"output-available\")\n  ) {\n    return null\n  }\n\n  return children\n}\n\nexport interface ConfirmationRejectedProps {\n  children?: ReactNode\n}\n\nexport const ConfirmationRejected = ({\n  children,\n}: ConfirmationRejectedProps) => {\n  const { approval, state } = useConfirmation()\n\n  // Only show when rejected and in response states\n  if (\n    approval?.approved !== false ||\n    (state !== \"approval-responded\" &&\n      state !== \"output-denied\" &&\n      state !== \"output-available\")\n  ) {\n    return null\n  }\n\n  return children\n}\n\nexport type ConfirmationActionsProps = ComponentProps<\"div\">\n\nexport const ConfirmationActions = ({\n  className,\n  ...props\n}: ConfirmationActionsProps) => {\n  const { state } = useConfirmation()\n\n  // Only show when approval is requested\n  if (state !== \"approval-requested\") {\n    return null\n  }\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-end gap-2 self-end\", className)}\n      {...props}\n    />\n  )\n}\n\nexport type ConfirmationActionProps = ComponentProps<typeof Button>\n\nexport const ConfirmationAction = (props: ConfirmationActionProps) => (\n  <Button className=\"h-8 px-3 text-sm\" type=\"button\" {...props} />\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/alert.tsx",
          "target": "@components/ai-elements/_ui/alert.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst alertVariants = cva(\n  \"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-card text-card-foreground\",\n        destructive:\n          \"text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Alert({\n  className,\n  variant,\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>) {\n  return (\n    <div\n      data-slot=\"alert\"\n      role=\"alert\"\n      className={cn(alertVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"alert-title\"\n      className={cn(\n        \"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDescription({\n  className,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"alert-description\"\n      className={cn(\n        \"text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Alert, AlertTitle, AlertDescription }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-connection",
      "type": "registry:block",
      "title": "Ai Elements Connection",
      "description": "connection",
      "dependencies": [
        "@xyflow/react@12.10.0",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/connection.tsx",
          "target": "@components/ai-elements/connection.tsx",
          "type": "registry:component",
          "content": "import type { ConnectionLineComponent } from \"@xyflow/react\"\n\nconst HALF = 0.5\n\nexport const Connection: ConnectionLineComponent = ({\n  fromX,\n  fromY,\n  toX,\n  toY,\n}) => (\n  <g>\n    <path\n      className=\"animated\"\n      d={`M${fromX},${fromY} C ${fromX + (toX - fromX) * HALF},${fromY} ${fromX + (toX - fromX) * HALF},${toY} ${toX},${toY}`}\n      fill=\"none\"\n      stroke=\"var(--color-ring)\"\n      strokeWidth={1}\n    />\n    <circle\n      cx={toX}\n      cy={toY}\n      fill=\"#fff\"\n      r={3}\n      stroke=\"var(--color-ring)\"\n      strokeWidth={1}\n    />\n  </g>\n)\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-context",
      "type": "registry:block",
      "title": "Ai Elements Context",
      "description": "context",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tokenlens@1.3.1",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/context.tsx",
          "target": "@components/ai-elements/context.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  HoverCard,\n  HoverCardContent,\n  HoverCardTrigger,\n} from \"@/components/ai-elements/_ui/hover-card\"\nimport { Progress } from \"@/components/ai-elements/_ui/progress\"\nimport { cn } from \"@/lib/utils\"\nimport type { LanguageModelUsage } from \"ai\"\nimport type { ComponentProps } from \"react\"\nimport { createContext, useContext, useMemo } from \"react\"\nimport { getUsage } from \"tokenlens\"\n\nconst PERCENT_MAX = 100\nconst ICON_RADIUS = 10\nconst ICON_VIEWBOX = 24\nconst ICON_CENTER = 12\nconst ICON_STROKE_WIDTH = 2\n\ntype ModelId = string\n\ninterface ContextSchema {\n  usedTokens: number\n  maxTokens: number\n  usage?: LanguageModelUsage\n  modelId?: ModelId\n}\n\nconst ContextContext = createContext<ContextSchema | null>(null)\n\nconst useContextValue = () => {\n  const context = useContext(ContextContext)\n\n  if (!context) {\n    throw new Error(\"Context components must be used within Context\")\n  }\n\n  return context\n}\n\nexport type ContextProps = ComponentProps<typeof HoverCard> & ContextSchema\n\nexport const Context = ({\n  usedTokens,\n  maxTokens,\n  usage,\n  modelId,\n  ...props\n}: ContextProps) => {\n  const contextValue = useMemo(\n    () => ({ maxTokens, modelId, usage, usedTokens }),\n    [maxTokens, modelId, usage, usedTokens]\n  )\n\n  return (\n    <ContextContext.Provider value={contextValue}>\n      <HoverCard closeDelay={0} openDelay={0} {...props} />\n    </ContextContext.Provider>\n  )\n}\n\nconst ContextIcon = () => {\n  const { usedTokens, maxTokens } = useContextValue()\n  const circumference = 2 * Math.PI * ICON_RADIUS\n  const usedPercent = usedTokens / maxTokens\n  const dashOffset = circumference * (1 - usedPercent)\n\n  return (\n    <svg\n      aria-label=\"Model context usage\"\n      height=\"20\"\n      role=\"img\"\n      style={{ color: \"currentcolor\" }}\n      viewBox={`0 0 ${ICON_VIEWBOX} ${ICON_VIEWBOX}`}\n      width=\"20\"\n    >\n      <circle\n        cx={ICON_CENTER}\n        cy={ICON_CENTER}\n        fill=\"none\"\n        opacity=\"0.25\"\n        r={ICON_RADIUS}\n        stroke=\"currentColor\"\n        strokeWidth={ICON_STROKE_WIDTH}\n      />\n      <circle\n        cx={ICON_CENTER}\n        cy={ICON_CENTER}\n        fill=\"none\"\n        opacity=\"0.7\"\n        r={ICON_RADIUS}\n        stroke=\"currentColor\"\n        strokeDasharray={`${circumference} ${circumference}`}\n        strokeDashoffset={dashOffset}\n        strokeLinecap=\"round\"\n        strokeWidth={ICON_STROKE_WIDTH}\n        style={{ transform: \"rotate(-90deg)\", transformOrigin: \"center\" }}\n      />\n    </svg>\n  )\n}\n\nexport type ContextTriggerProps = ComponentProps<typeof Button>\n\nexport const ContextTrigger = ({ children, ...props }: ContextTriggerProps) => {\n  const { usedTokens, maxTokens } = useContextValue()\n  const usedPercent = usedTokens / maxTokens\n  const renderedPercent = new Intl.NumberFormat(\"en-US\", {\n    maximumFractionDigits: 1,\n    style: \"percent\",\n  }).format(usedPercent)\n\n  return (\n    <HoverCardTrigger asChild>\n      {children ?? (\n        <Button type=\"button\" variant=\"ghost\" {...props}>\n          <span className=\"text-muted-foreground font-medium\">\n            {renderedPercent}\n          </span>\n          <ContextIcon />\n        </Button>\n      )}\n    </HoverCardTrigger>\n  )\n}\n\nexport type ContextContentProps = ComponentProps<typeof HoverCardContent>\n\nexport const ContextContent = ({\n  className,\n  ...props\n}: ContextContentProps) => (\n  <HoverCardContent\n    className={cn(\"min-w-60 divide-y overflow-hidden p-0\", className)}\n    {...props}\n  />\n)\n\nexport type ContextContentHeaderProps = ComponentProps<\"div\">\n\nexport const ContextContentHeader = ({\n  children,\n  className,\n  ...props\n}: ContextContentHeaderProps) => {\n  const { usedTokens, maxTokens } = useContextValue()\n  const usedPercent = usedTokens / maxTokens\n  const displayPct = new Intl.NumberFormat(\"en-US\", {\n    maximumFractionDigits: 1,\n    style: \"percent\",\n  }).format(usedPercent)\n  const used = new Intl.NumberFormat(\"en-US\", {\n    notation: \"compact\",\n  }).format(usedTokens)\n  const total = new Intl.NumberFormat(\"en-US\", {\n    notation: \"compact\",\n  }).format(maxTokens)\n\n  return (\n    <div className={cn(\"w-full space-y-2 p-3\", className)} {...props}>\n      {children ?? (\n        <>\n          <div className=\"flex items-center justify-between gap-3 text-xs\">\n            <p>{displayPct}</p>\n            <p className=\"text-muted-foreground font-mono\">\n              {used} / {total}\n            </p>\n          </div>\n          <div className=\"space-y-2\">\n            <Progress className=\"bg-muted\" value={usedPercent * PERCENT_MAX} />\n          </div>\n        </>\n      )}\n    </div>\n  )\n}\n\nexport type ContextContentBodyProps = ComponentProps<\"div\">\n\nexport const ContextContentBody = ({\n  children,\n  className,\n  ...props\n}: ContextContentBodyProps) => (\n  <div className={cn(\"w-full p-3\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type ContextContentFooterProps = ComponentProps<\"div\">\n\nexport const ContextContentFooter = ({\n  children,\n  className,\n  ...props\n}: ContextContentFooterProps) => {\n  const { modelId, usage } = useContextValue()\n  const costUSD = modelId\n    ? getUsage({\n        modelId,\n        usage: {\n          input: usage?.inputTokens ?? 0,\n          output: usage?.outputTokens ?? 0,\n        },\n      }).costUSD?.totalUSD\n    : undefined\n  const totalCost = new Intl.NumberFormat(\"en-US\", {\n    currency: \"USD\",\n    style: \"currency\",\n  }).format(costUSD ?? 0)\n\n  return (\n    <div\n      className={cn(\n        \"bg-secondary flex w-full items-center justify-between gap-3 p-3 text-xs\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? (\n        <>\n          <span className=\"text-muted-foreground\">Total cost</span>\n          <span>{totalCost}</span>\n        </>\n      )}\n    </div>\n  )\n}\n\nconst TokensWithCost = ({\n  tokens,\n  costText,\n}: {\n  tokens?: number\n  costText?: string\n}) => (\n  <span>\n    {tokens === undefined\n      ? \"—\"\n      : new Intl.NumberFormat(\"en-US\", {\n          notation: \"compact\",\n        }).format(tokens)}\n    {costText ? (\n      <span className=\"text-muted-foreground ml-2\">• {costText}</span>\n    ) : null}\n  </span>\n)\n\nexport type ContextInputUsageProps = ComponentProps<\"div\">\n\nexport const ContextInputUsage = ({\n  className,\n  children,\n  ...props\n}: ContextInputUsageProps) => {\n  const { usage, modelId } = useContextValue()\n  const inputTokens = usage?.inputTokens ?? 0\n\n  if (children) {\n    return children\n  }\n\n  if (!inputTokens) {\n    return null\n  }\n\n  const inputCost = modelId\n    ? getUsage({\n        modelId,\n        usage: { input: inputTokens, output: 0 },\n      }).costUSD?.totalUSD\n    : undefined\n  const inputCostText = new Intl.NumberFormat(\"en-US\", {\n    currency: \"USD\",\n    style: \"currency\",\n  }).format(inputCost ?? 0)\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-between text-xs\", className)}\n      {...props}\n    >\n      <span className=\"text-muted-foreground\">Input</span>\n      <TokensWithCost costText={inputCostText} tokens={inputTokens} />\n    </div>\n  )\n}\n\nexport type ContextOutputUsageProps = ComponentProps<\"div\">\n\nexport const ContextOutputUsage = ({\n  className,\n  children,\n  ...props\n}: ContextOutputUsageProps) => {\n  const { usage, modelId } = useContextValue()\n  const outputTokens = usage?.outputTokens ?? 0\n\n  if (children) {\n    return children\n  }\n\n  if (!outputTokens) {\n    return null\n  }\n\n  const outputCost = modelId\n    ? getUsage({\n        modelId,\n        usage: { input: 0, output: outputTokens },\n      }).costUSD?.totalUSD\n    : undefined\n  const outputCostText = new Intl.NumberFormat(\"en-US\", {\n    currency: \"USD\",\n    style: \"currency\",\n  }).format(outputCost ?? 0)\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-between text-xs\", className)}\n      {...props}\n    >\n      <span className=\"text-muted-foreground\">Output</span>\n      <TokensWithCost costText={outputCostText} tokens={outputTokens} />\n    </div>\n  )\n}\n\nexport type ContextReasoningUsageProps = ComponentProps<\"div\">\n\nexport const ContextReasoningUsage = ({\n  className,\n  children,\n  ...props\n}: ContextReasoningUsageProps) => {\n  const { usage, modelId } = useContextValue()\n  const reasoningTokens = usage?.reasoningTokens ?? 0\n\n  if (children) {\n    return children\n  }\n\n  if (!reasoningTokens) {\n    return null\n  }\n\n  const reasoningCost = modelId\n    ? getUsage({\n        modelId,\n        usage: { reasoningTokens },\n      }).costUSD?.totalUSD\n    : undefined\n  const reasoningCostText = new Intl.NumberFormat(\"en-US\", {\n    currency: \"USD\",\n    style: \"currency\",\n  }).format(reasoningCost ?? 0)\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-between text-xs\", className)}\n      {...props}\n    >\n      <span className=\"text-muted-foreground\">Reasoning</span>\n      <TokensWithCost costText={reasoningCostText} tokens={reasoningTokens} />\n    </div>\n  )\n}\n\nexport type ContextCacheUsageProps = ComponentProps<\"div\">\n\nexport const ContextCacheUsage = ({\n  className,\n  children,\n  ...props\n}: ContextCacheUsageProps) => {\n  const { usage, modelId } = useContextValue()\n  const cacheTokens = usage?.cachedInputTokens ?? 0\n\n  if (children) {\n    return children\n  }\n\n  if (!cacheTokens) {\n    return null\n  }\n\n  const cacheCost = modelId\n    ? getUsage({\n        modelId,\n        usage: { cacheReads: cacheTokens, input: 0, output: 0 },\n      }).costUSD?.totalUSD\n    : undefined\n  const cacheCostText = new Intl.NumberFormat(\"en-US\", {\n    currency: \"USD\",\n    style: \"currency\",\n  }).format(cacheCost ?? 0)\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-between text-xs\", className)}\n      {...props}\n    >\n      <span className=\"text-muted-foreground\">Cache</span>\n      <TokensWithCost costText={cacheCostText} tokens={cacheTokens} />\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/hover-card.tsx",
          "target": "@components/ai-elements/_ui/hover-card.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { HoverCard as HoverCardPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction HoverCard({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n  return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />\n}\n\nfunction HoverCardTrigger({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n  return (\n    <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n  )\n}\n\nfunction HoverCardContent({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n  return (\n    <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n      <HoverCardPrimitive.Content\n        data-slot=\"hover-card-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n          className\n        )}\n        {...props}\n      />\n    </HoverCardPrimitive.Portal>\n  )\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\n"
        },
        {
          "path": "components/ai-elements/_ui/progress.tsx",
          "target": "@components/ai-elements/_ui/progress.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Progress as ProgressPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Progress({\n  className,\n  value,\n  ...props\n}: React.ComponentProps<typeof ProgressPrimitive.Root>) {\n  return (\n    <ProgressPrimitive.Root\n      data-slot=\"progress\"\n      className={cn(\n        \"bg-primary/20 relative h-2 w-full overflow-hidden rounded-full\",\n        className\n      )}\n      {...props}\n    >\n      <ProgressPrimitive.Indicator\n        data-slot=\"progress-indicator\"\n        className=\"bg-primary h-full w-full flex-1 transition-all\"\n        style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n      />\n    </ProgressPrimitive.Root>\n  )\n}\n\nexport { Progress }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-controls",
      "type": "registry:block",
      "title": "Ai Elements Controls",
      "description": "controls",
      "dependencies": [
        "@xyflow/react@12.10.0",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/controls.tsx",
          "target": "@components/ai-elements/controls.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Controls as ControlsPrimitive } from \"@xyflow/react\"\nimport type { ComponentProps } from \"react\"\n\nexport type ControlsProps = ComponentProps<typeof ControlsPrimitive>\n\nexport const Controls = ({ className, ...props }: ControlsProps) => (\n  <ControlsPrimitive\n    className={cn(\n      \"bg-card gap-px overflow-hidden rounded-md border p-1 shadow-none!\",\n      \"[&>button]:hover:bg-secondary! [&>button]:rounded-md [&>button]:border-none! [&>button]:bg-transparent!\",\n      className\n    )}\n    {...props}\n  />\n)\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-conversation",
      "type": "registry:block",
      "title": "Ai Elements Conversation",
      "description": "conversation",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6",
        "use-stick-to-bottom@^1.1.0"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/conversation.tsx",
          "target": "@components/ai-elements/conversation.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport type { UIMessage } from \"ai\"\nimport { ArrowDownIcon, DownloadIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport { useCallback } from \"react\"\nimport { StickToBottom, useStickToBottomContext } from \"use-stick-to-bottom\"\n\nexport type ConversationProps = ComponentProps<typeof StickToBottom>\n\nexport const Conversation = ({ className, ...props }: ConversationProps) => (\n  <StickToBottom\n    className={cn(\"relative flex-1 overflow-y-hidden\", className)}\n    initial=\"smooth\"\n    resize=\"smooth\"\n    role=\"log\"\n    {...props}\n  />\n)\n\nexport type ConversationContentProps = ComponentProps<\n  typeof StickToBottom.Content\n>\n\nexport const ConversationContent = ({\n  className,\n  ...props\n}: ConversationContentProps) => (\n  <StickToBottom.Content\n    className={cn(\"flex flex-col gap-8 p-4\", className)}\n    {...props}\n  />\n)\n\nexport type ConversationEmptyStateProps = ComponentProps<\"div\"> & {\n  title?: string\n  description?: string\n  icon?: React.ReactNode\n}\n\nexport const ConversationEmptyState = ({\n  className,\n  title = \"No messages yet\",\n  description = \"Start a conversation to see messages here\",\n  icon,\n  children,\n  ...props\n}: ConversationEmptyStateProps) => (\n  <div\n    className={cn(\n      \"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\",\n      className\n    )}\n    {...props}\n  >\n    {children ?? (\n      <>\n        {icon && <div className=\"text-muted-foreground\">{icon}</div>}\n        <div className=\"space-y-1\">\n          <h3 className=\"text-sm font-medium\">{title}</h3>\n          {description && (\n            <p className=\"text-muted-foreground text-sm\">{description}</p>\n          )}\n        </div>\n      </>\n    )}\n  </div>\n)\n\nexport type ConversationScrollButtonProps = ComponentProps<typeof Button>\n\nexport const ConversationScrollButton = ({\n  className,\n  ...props\n}: ConversationScrollButtonProps) => {\n  const { isAtBottom, scrollToBottom } = useStickToBottomContext()\n\n  const handleScrollToBottom = useCallback(() => {\n    scrollToBottom()\n  }, [scrollToBottom])\n\n  return (\n    !isAtBottom && (\n      <Button\n        className={cn(\n          \"dark:bg-background dark:hover:bg-muted absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full\",\n          className\n        )}\n        onClick={handleScrollToBottom}\n        size=\"icon\"\n        type=\"button\"\n        variant=\"outline\"\n        {...props}\n      >\n        <ArrowDownIcon className=\"size-4\" />\n      </Button>\n    )\n  )\n}\n\nconst getMessageText = (message: UIMessage): string =>\n  message.parts\n    .filter((part) => part.type === \"text\")\n    .map((part) => part.text)\n    .join(\"\")\n\nexport type ConversationDownloadProps = Omit<\n  ComponentProps<typeof Button>,\n  \"onClick\"\n> & {\n  messages: UIMessage[]\n  filename?: string\n  formatMessage?: (message: UIMessage, index: number) => string\n}\n\nconst defaultFormatMessage = (message: UIMessage): string => {\n  const roleLabel = message.role.charAt(0).toUpperCase() + message.role.slice(1)\n  return `**${roleLabel}:** ${getMessageText(message)}`\n}\n\nexport const messagesToMarkdown = (\n  messages: UIMessage[],\n  formatMessage: (\n    message: UIMessage,\n    index: number\n  ) => string = defaultFormatMessage\n): string => messages.map((msg, i) => formatMessage(msg, i)).join(\"\\n\\n\")\n\nexport const ConversationDownload = ({\n  messages,\n  filename = \"conversation.md\",\n  formatMessage = defaultFormatMessage,\n  className,\n  children,\n  ...props\n}: ConversationDownloadProps) => {\n  const handleDownload = useCallback(() => {\n    const markdown = messagesToMarkdown(messages, formatMessage)\n    const blob = new Blob([markdown], { type: \"text/markdown\" })\n    const url = URL.createObjectURL(blob)\n    const link = document.createElement(\"a\")\n    link.href = url\n    link.download = filename\n    document.body.append(link)\n    link.click()\n    link.remove()\n    URL.revokeObjectURL(url)\n  }, [messages, filename, formatMessage])\n\n  return (\n    <Button\n      className={cn(\n        \"dark:bg-background dark:hover:bg-muted absolute top-4 right-4 rounded-full\",\n        className\n      )}\n      onClick={handleDownload}\n      size=\"icon\"\n      type=\"button\"\n      variant=\"outline\"\n      {...props}\n    >\n      {children ?? <DownloadIcon className=\"size-4\" />}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-edge",
      "type": "registry:block",
      "title": "Ai Elements Edge",
      "description": "edge",
      "dependencies": [
        "@xyflow/react@12.10.0",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/edge.tsx",
          "target": "@components/ai-elements/edge.tsx",
          "type": "registry:component",
          "content": "import type { EdgeProps, InternalNode, Node } from \"@xyflow/react\"\nimport {\n  BaseEdge,\n  getBezierPath,\n  getSimpleBezierPath,\n  Position,\n  useInternalNode,\n} from \"@xyflow/react\"\n\nconst Temporary = ({\n  id,\n  sourceX,\n  sourceY,\n  targetX,\n  targetY,\n  sourcePosition,\n  targetPosition,\n}: EdgeProps) => {\n  const [edgePath] = getSimpleBezierPath({\n    sourcePosition,\n    sourceX,\n    sourceY,\n    targetPosition,\n    targetX,\n    targetY,\n  })\n\n  return (\n    <BaseEdge\n      className=\"stroke-ring stroke-1\"\n      id={id}\n      path={edgePath}\n      style={{\n        strokeDasharray: \"5, 5\",\n      }}\n    />\n  )\n}\n\nconst getHandleCoordsByPosition = (\n  node: InternalNode<Node>,\n  handlePosition: Position\n) => {\n  // Choose the handle type based on position - Left is for target, Right is for source\n  const handleType = handlePosition === Position.Left ? \"target\" : \"source\"\n\n  const handle = node.internals.handleBounds?.[handleType]?.find(\n    (h) => h.position === handlePosition\n  )\n\n  if (!handle) {\n    return [0, 0] as const\n  }\n\n  let offsetX = handle.width / 2\n  let offsetY = handle.height / 2\n\n  // this is a tiny detail to make the markerEnd of an edge visible.\n  // The handle position that gets calculated has the origin top-left, so depending which side we are using, we add a little offset\n  // when the handlePosition is Position.Right for example, we need to add an offset as big as the handle itself in order to get the correct position\n  switch (handlePosition) {\n    case Position.Left: {\n      offsetX = 0\n      break\n    }\n    case Position.Right: {\n      offsetX = handle.width\n      break\n    }\n    case Position.Top: {\n      offsetY = 0\n      break\n    }\n    case Position.Bottom: {\n      offsetY = handle.height\n      break\n    }\n    default: {\n      throw new Error(`Invalid handle position: ${handlePosition}`)\n    }\n  }\n\n  const x = node.internals.positionAbsolute.x + handle.x + offsetX\n  const y = node.internals.positionAbsolute.y + handle.y + offsetY\n\n  return [x, y] as const\n}\n\nconst getEdgeParams = (\n  source: InternalNode<Node>,\n  target: InternalNode<Node>\n) => {\n  const sourcePos = Position.Right\n  const [sx, sy] = getHandleCoordsByPosition(source, sourcePos)\n  const targetPos = Position.Left\n  const [tx, ty] = getHandleCoordsByPosition(target, targetPos)\n\n  return {\n    sourcePos,\n    sx,\n    sy,\n    targetPos,\n    tx,\n    ty,\n  }\n}\n\nconst Animated = ({ id, source, target, markerEnd, style }: EdgeProps) => {\n  const sourceNode = useInternalNode(source)\n  const targetNode = useInternalNode(target)\n\n  if (!(sourceNode && targetNode)) {\n    return null\n  }\n\n  const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams(\n    sourceNode,\n    targetNode\n  )\n\n  const [edgePath] = getBezierPath({\n    sourcePosition: sourcePos,\n    sourceX: sx,\n    sourceY: sy,\n    targetPosition: targetPos,\n    targetX: tx,\n    targetY: ty,\n  })\n\n  return (\n    <>\n      <BaseEdge id={id} markerEnd={markerEnd} path={edgePath} style={style} />\n      <circle fill=\"var(--primary)\" r=\"4\">\n        <animateMotion dur=\"2s\" path={edgePath} repeatCount=\"indefinite\" />\n      </circle>\n    </>\n  )\n}\n\nexport const Edge = {\n  Animated,\n  Temporary,\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-environment-variables",
      "type": "registry:block",
      "title": "Ai Elements Environment Variables",
      "description": "environment variables",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/environment-variables.tsx",
          "target": "@components/ai-elements/environment-variables.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { Switch } from \"@/components/ai-elements/_ui/switch\"\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, CopyIcon, EyeIcon, EyeOffIcon } from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\ninterface EnvironmentVariablesContextType {\n  showValues: boolean\n  setShowValues: (show: boolean) => void\n}\n\n// Default noop for context default value\n// oxlint-disable-next-line eslint(no-empty-function)\nconst noop = () => {}\n\nconst EnvironmentVariablesContext =\n  createContext<EnvironmentVariablesContextType>({\n    setShowValues: noop,\n    showValues: false,\n  })\n\nexport type EnvironmentVariablesProps = HTMLAttributes<HTMLDivElement> & {\n  showValues?: boolean\n  defaultShowValues?: boolean\n  onShowValuesChange?: (show: boolean) => void\n}\n\nexport const EnvironmentVariables = ({\n  showValues: controlledShowValues,\n  defaultShowValues = false,\n  onShowValuesChange,\n  className,\n  children,\n  ...props\n}: EnvironmentVariablesProps) => {\n  const [internalShowValues, setInternalShowValues] =\n    useState(defaultShowValues)\n  const showValues = controlledShowValues ?? internalShowValues\n\n  const setShowValues = useCallback(\n    (show: boolean) => {\n      setInternalShowValues(show)\n      onShowValuesChange?.(show)\n    },\n    [onShowValuesChange]\n  )\n\n  const contextValue = useMemo(\n    () => ({ setShowValues, showValues }),\n    [setShowValues, showValues]\n  )\n\n  return (\n    <EnvironmentVariablesContext.Provider value={contextValue}>\n      <div\n        className={cn(\"bg-background rounded-lg border\", className)}\n        {...props}\n      >\n        {children}\n      </div>\n    </EnvironmentVariablesContext.Provider>\n  )\n}\n\nexport type EnvironmentVariablesHeaderProps = HTMLAttributes<HTMLDivElement>\n\nexport const EnvironmentVariablesHeader = ({\n  className,\n  children,\n  ...props\n}: EnvironmentVariablesHeaderProps) => (\n  <div\n    className={cn(\n      \"flex items-center justify-between border-b px-4 py-3\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type EnvironmentVariablesTitleProps = HTMLAttributes<HTMLHeadingElement>\n\nexport const EnvironmentVariablesTitle = ({\n  className,\n  children,\n  ...props\n}: EnvironmentVariablesTitleProps) => (\n  <h3 className={cn(\"text-sm font-medium\", className)} {...props}>\n    {children ?? \"Environment Variables\"}\n  </h3>\n)\n\nexport type EnvironmentVariablesToggleProps = ComponentProps<typeof Switch>\n\nexport const EnvironmentVariablesToggle = ({\n  className,\n  ...props\n}: EnvironmentVariablesToggleProps) => {\n  const { showValues, setShowValues } = useContext(EnvironmentVariablesContext)\n\n  return (\n    <div className={cn(\"flex items-center gap-2\", className)}>\n      <span className=\"text-muted-foreground text-xs\">\n        {showValues ? <EyeIcon size={14} /> : <EyeOffIcon size={14} />}\n      </span>\n      <Switch\n        aria-label=\"Toggle value visibility\"\n        checked={showValues}\n        onCheckedChange={setShowValues}\n        {...props}\n      />\n    </div>\n  )\n}\n\nexport type EnvironmentVariablesContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const EnvironmentVariablesContent = ({\n  className,\n  children,\n  ...props\n}: EnvironmentVariablesContentProps) => (\n  <div className={cn(\"divide-y\", className)} {...props}>\n    {children}\n  </div>\n)\n\ninterface EnvironmentVariableContextType {\n  name: string\n  value: string\n}\n\nconst EnvironmentVariableContext =\n  createContext<EnvironmentVariableContextType>({\n    name: \"\",\n    value: \"\",\n  })\n\nexport type EnvironmentVariableGroupProps = HTMLAttributes<HTMLDivElement>\n\nexport const EnvironmentVariableGroup = ({\n  className,\n  children,\n  ...props\n}: EnvironmentVariableGroupProps) => (\n  <div className={cn(\"flex min-w-0 items-center gap-2\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type EnvironmentVariableNameProps = HTMLAttributes<HTMLSpanElement>\n\nexport const EnvironmentVariableName = ({\n  className,\n  children,\n  ...props\n}: EnvironmentVariableNameProps) => {\n  const { name } = useContext(EnvironmentVariableContext)\n\n  return (\n    <span className={cn(\"truncate font-mono text-sm\", className)} {...props}>\n      {children ?? name}\n    </span>\n  )\n}\n\nexport type EnvironmentVariableValueProps = HTMLAttributes<HTMLSpanElement>\n\nexport const EnvironmentVariableValue = ({\n  className,\n  children,\n  ...props\n}: EnvironmentVariableValueProps) => {\n  const { value } = useContext(EnvironmentVariableContext)\n  const { showValues } = useContext(EnvironmentVariablesContext)\n\n  const displayValue = showValues\n    ? value\n    : \"•\".repeat(Math.min(value.length, 20))\n\n  return (\n    <span\n      className={cn(\n        \"text-muted-foreground truncate font-mono text-sm\",\n        !showValues && \"select-none\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? displayValue}\n    </span>\n  )\n}\n\nexport type EnvironmentVariableProps = HTMLAttributes<HTMLDivElement> & {\n  name: string\n  value: string\n}\n\nexport const EnvironmentVariable = ({\n  name,\n  value,\n  className,\n  children,\n  ...props\n}: EnvironmentVariableProps) => {\n  const envVarContextValue = useMemo(() => ({ name, value }), [name, value])\n\n  return (\n    <EnvironmentVariableContext.Provider value={envVarContextValue}>\n      <div\n        className={cn(\n          \"flex min-w-0 items-center justify-between gap-4 px-4 py-3\",\n          className\n        )}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <div className=\"flex items-center gap-2\">\n              <EnvironmentVariableName />\n            </div>\n            <EnvironmentVariableValue />\n          </>\n        )}\n      </div>\n    </EnvironmentVariableContext.Provider>\n  )\n}\n\nexport type EnvironmentVariableCopyButtonProps = ComponentProps<\n  typeof Button\n> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n  copyFormat?: \"name\" | \"value\" | \"export\"\n}\n\nexport const EnvironmentVariableCopyButton = ({\n  onCopy,\n  onError,\n  timeout = 2000,\n  copyFormat = \"value\",\n  children,\n  className,\n  ...props\n}: EnvironmentVariableCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n  const { name, value } = useContext(EnvironmentVariableContext)\n\n  const getTextToCopy = useCallback((): string => {\n    const formatMap = {\n      export: () => `export ${name}=\"${value}\"`,\n      name: () => name,\n      value: () => value,\n    }\n    return formatMap[copyFormat]()\n  }, [name, value, copyFormat])\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      await navigator.clipboard.writeText(getTextToCopy())\n      setIsCopied(true)\n      onCopy?.()\n      timeoutRef.current = window.setTimeout(() => setIsCopied(false), timeout)\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [getTextToCopy, onCopy, onError, timeout])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <Button\n      className={cn(\"size-6 shrink-0\", className)}\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Icon size={12} />}\n    </Button>\n  )\n}\n\nexport type EnvironmentVariableRequiredProps = ComponentProps<typeof Badge>\n\nexport const EnvironmentVariableRequired = ({\n  className,\n  children,\n  ...props\n}: EnvironmentVariableRequiredProps) => (\n  <Badge className={cn(\"text-xs\", className)} variant=\"secondary\" {...props}>\n    {children ?? \"Required\"}\n  </Badge>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ai-elements/_ui/switch.tsx",
          "target": "@components/ai-elements/_ui/switch.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Switch as SwitchPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Switch({\n  className,\n  ...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root>) {\n  return (\n    <SwitchPrimitive.Root\n      data-slot=\"switch\"\n      className={cn(\n        \"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50\",\n        className\n      )}\n      {...props}\n    >\n      <SwitchPrimitive.Thumb\n        data-slot=\"switch-thumb\"\n        className={cn(\n          \"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0\"\n        )}\n      />\n    </SwitchPrimitive.Root>\n  )\n}\n\nexport { Switch }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-file-tree",
      "type": "registry:block",
      "title": "Ai Elements File Tree",
      "description": "file tree",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/file-tree.tsx",
          "target": "@components/ai-elements/file-tree.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  ChevronRightIcon,\n  FileIcon,\n  FolderIcon,\n  FolderOpenIcon,\n} from \"lucide-react\"\nimport type { HTMLAttributes, ReactNode } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useMemo,\n  useState,\n} from \"react\"\n\ninterface FileTreeContextType {\n  expandedPaths: Set<string>\n  togglePath: (path: string) => void\n  selectedPath?: string\n  onSelect?: (path: string) => void\n}\n\n// Default noop for context default value\n// oxlint-disable-next-line eslint(no-empty-function)\nconst noop = () => {}\n\nconst FileTreeContext = createContext<FileTreeContextType>({\n  // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)\n  expandedPaths: new Set(),\n  togglePath: noop,\n})\n\nexport type FileTreeProps = Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> & {\n  expanded?: Set<string>\n  defaultExpanded?: Set<string>\n  selectedPath?: string\n  onSelect?: (path: string) => void\n  onExpandedChange?: (expanded: Set<string>) => void\n}\n\nexport const FileTree = ({\n  expanded: controlledExpanded,\n  defaultExpanded = new Set(),\n  selectedPath,\n  onSelect,\n  onExpandedChange,\n  className,\n  children,\n  ...props\n}: FileTreeProps) => {\n  const [internalExpanded, setInternalExpanded] = useState(defaultExpanded)\n  const expandedPaths = controlledExpanded ?? internalExpanded\n\n  const togglePath = useCallback(\n    (path: string) => {\n      const newExpanded = new Set(expandedPaths)\n      if (newExpanded.has(path)) {\n        newExpanded.delete(path)\n      } else {\n        newExpanded.add(path)\n      }\n      setInternalExpanded(newExpanded)\n      onExpandedChange?.(newExpanded)\n    },\n    [expandedPaths, onExpandedChange]\n  )\n\n  const contextValue = useMemo(\n    () => ({ expandedPaths, onSelect, selectedPath, togglePath }),\n    [expandedPaths, onSelect, selectedPath, togglePath]\n  )\n\n  return (\n    <FileTreeContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"bg-background rounded-lg border font-mono text-sm\",\n          className\n        )}\n        role=\"tree\"\n        {...props}\n      >\n        <div className=\"p-2\">{children}</div>\n      </div>\n    </FileTreeContext.Provider>\n  )\n}\n\nexport type FileTreeIconProps = HTMLAttributes<HTMLSpanElement>\n\nexport const FileTreeIcon = ({\n  className,\n  children,\n  ...props\n}: FileTreeIconProps) => (\n  <span className={cn(\"shrink-0\", className)} {...props}>\n    {children}\n  </span>\n)\n\nexport type FileTreeNameProps = HTMLAttributes<HTMLSpanElement>\n\nexport const FileTreeName = ({\n  className,\n  children,\n  ...props\n}: FileTreeNameProps) => (\n  <span className={cn(\"truncate\", className)} {...props}>\n    {children}\n  </span>\n)\n\ninterface FileTreeFolderContextType {\n  path: string\n  name: string\n  isExpanded: boolean\n}\n\nconst FileTreeFolderContext = createContext<FileTreeFolderContextType>({\n  isExpanded: false,\n  name: \"\",\n  path: \"\",\n})\n\nexport type FileTreeFolderProps = HTMLAttributes<HTMLDivElement> & {\n  path: string\n  name: string\n}\n\nexport const FileTreeFolder = ({\n  path,\n  name,\n  className,\n  children,\n  ...props\n}: FileTreeFolderProps) => {\n  const { expandedPaths, togglePath, selectedPath, onSelect } =\n    useContext(FileTreeContext)\n  const isExpanded = expandedPaths.has(path)\n  const isSelected = selectedPath === path\n\n  const handleOpenChange = useCallback(() => {\n    togglePath(path)\n  }, [togglePath, path])\n\n  const handleSelect = useCallback(() => {\n    onSelect?.(path)\n  }, [onSelect, path])\n\n  const folderContextValue = useMemo(\n    () => ({ isExpanded, name, path }),\n    [isExpanded, name, path]\n  )\n\n  return (\n    <FileTreeFolderContext.Provider value={folderContextValue}>\n      <Collapsible onOpenChange={handleOpenChange} open={isExpanded}>\n        <div\n          aria-selected={isSelected}\n          className={cn(\"\", className)}\n          role=\"treeitem\"\n          tabIndex={0}\n          {...props}\n        >\n          <div\n            className={cn(\n              \"hover:bg-muted/50 flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors\",\n              isSelected && \"bg-muted\"\n            )}\n          >\n            <CollapsibleTrigger asChild>\n              <button\n                className=\"flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0\"\n                type=\"button\"\n              >\n                <ChevronRightIcon\n                  className={cn(\n                    \"text-muted-foreground size-4 shrink-0 transition-transform\",\n                    isExpanded && \"rotate-90\"\n                  )}\n                />\n              </button>\n            </CollapsibleTrigger>\n            <button\n              className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left\"\n              onClick={handleSelect}\n              type=\"button\"\n            >\n              <FileTreeIcon>\n                {isExpanded ? (\n                  <FolderOpenIcon className=\"size-4 text-blue-500\" />\n                ) : (\n                  <FolderIcon className=\"size-4 text-blue-500\" />\n                )}\n              </FileTreeIcon>\n              <FileTreeName>{name}</FileTreeName>\n            </button>\n          </div>\n          <CollapsibleContent>\n            <div className=\"ml-4 border-l pl-2\">{children}</div>\n          </CollapsibleContent>\n        </div>\n      </Collapsible>\n    </FileTreeFolderContext.Provider>\n  )\n}\n\ninterface FileTreeFileContextType {\n  path: string\n  name: string\n}\n\nconst FileTreeFileContext = createContext<FileTreeFileContextType>({\n  name: \"\",\n  path: \"\",\n})\n\nexport type FileTreeFileProps = HTMLAttributes<HTMLDivElement> & {\n  path: string\n  name: string\n  icon?: ReactNode\n}\n\nexport const FileTreeFile = ({\n  path,\n  name,\n  icon,\n  className,\n  children,\n  ...props\n}: FileTreeFileProps) => {\n  const { selectedPath, onSelect } = useContext(FileTreeContext)\n  const isSelected = selectedPath === path\n\n  const handleClick = useCallback(() => {\n    onSelect?.(path)\n  }, [onSelect, path])\n\n  const handleKeyDown = useCallback(\n    (e: React.KeyboardEvent) => {\n      if (e.key === \"Enter\" || e.key === \" \") {\n        onSelect?.(path)\n      }\n    },\n    [onSelect, path]\n  )\n\n  const fileContextValue = useMemo(() => ({ name, path }), [name, path])\n\n  return (\n    <FileTreeFileContext.Provider value={fileContextValue}>\n      <div\n        aria-selected={isSelected}\n        className={cn(\n          \"hover:bg-muted/50 flex cursor-pointer items-center gap-1 rounded px-2 py-1 transition-colors\",\n          isSelected && \"bg-muted\",\n          className\n        )}\n        onClick={handleClick}\n        onKeyDown={handleKeyDown}\n        role=\"treeitem\"\n        tabIndex={0}\n        {...props}\n      >\n        {children ?? (\n          <>\n            {/* Spacer for alignment */}\n            <span className=\"size-4 shrink-0\" />\n            <FileTreeIcon>\n              {icon ?? <FileIcon className=\"text-muted-foreground size-4\" />}\n            </FileTreeIcon>\n            <FileTreeName>{name}</FileTreeName>\n          </>\n        )}\n      </div>\n    </FileTreeFileContext.Provider>\n  )\n}\n\nexport type FileTreeActionsProps = HTMLAttributes<HTMLDivElement>\n\nconst stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation()\n\nexport const FileTreeActions = ({\n  className,\n  children,\n  ...props\n}: FileTreeActionsProps) => (\n  <div\n    className={cn(\"ml-auto flex items-center gap-1\", className)}\n    onClick={stopPropagation}\n    onKeyDown={stopPropagation}\n    role=\"group\"\n    {...props}\n  >\n    {children}\n  </div>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-image",
      "type": "registry:block",
      "title": "Ai Elements Image",
      "description": "image",
      "dependencies": [
        "ai@6.0.280",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/image.tsx",
          "target": "@components/ai-elements/image.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport type { Experimental_GeneratedImage } from \"ai\"\n\nexport type ImageProps = Experimental_GeneratedImage & {\n  className?: string\n  alt?: string\n}\n\nexport const Image = ({\n  base64,\n  uint8Array,\n  mediaType,\n  ...props\n}: ImageProps) => {\n  void uint8Array\n  return (\n    <img\n      {...props}\n      alt={props.alt}\n      className={cn(\n        \"h-auto max-w-full overflow-hidden rounded-md\",\n        props.className\n      )}\n      src={`data:${mediaType};base64,${base64}`}\n    />\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-inline-citation",
      "type": "registry:block",
      "title": "Ai Elements Inline Citation",
      "description": "inline citation",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "embla-carousel-react@8.6.0",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/inline-citation.tsx",
          "target": "@components/ai-elements/inline-citation.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport type { CarouselApi } from \"@/components/ai-elements/_ui/carousel\"\nimport {\n  Carousel,\n  CarouselContent,\n  CarouselItem,\n} from \"@/components/ai-elements/_ui/carousel\"\nimport {\n  HoverCard,\n  HoverCardContent,\n  HoverCardTrigger,\n} from \"@/components/ai-elements/_ui/hover-card\"\nimport { cn } from \"@/lib/utils\"\nimport { ArrowLeftIcon, ArrowRightIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useState,\n} from \"react\"\n\nexport type InlineCitationProps = ComponentProps<\"span\">\n\nexport const InlineCitation = ({\n  className,\n  ...props\n}: InlineCitationProps) => (\n  <span\n    className={cn(\"group inline items-center gap-1\", className)}\n    {...props}\n  />\n)\n\nexport type InlineCitationTextProps = ComponentProps<\"span\">\n\nexport const InlineCitationText = ({\n  className,\n  ...props\n}: InlineCitationTextProps) => (\n  <span\n    className={cn(\"group-hover:bg-accent transition-colors\", className)}\n    {...props}\n  />\n)\n\nexport type InlineCitationCardProps = ComponentProps<typeof HoverCard>\n\nexport const InlineCitationCard = (props: InlineCitationCardProps) => (\n  <HoverCard closeDelay={0} openDelay={0} {...props} />\n)\n\nexport type InlineCitationCardTriggerProps = ComponentProps<typeof Badge> & {\n  sources: string[]\n}\n\nexport const InlineCitationCardTrigger = ({\n  sources,\n  className,\n  ...props\n}: InlineCitationCardTriggerProps) => (\n  <HoverCardTrigger asChild>\n    <Badge\n      className={cn(\"ml-1 rounded-full\", className)}\n      variant=\"secondary\"\n      {...props}\n    >\n      {sources[0] ? (\n        <>\n          {new URL(sources[0]).hostname}{\" \"}\n          {sources.length > 1 && `+${sources.length - 1}`}\n        </>\n      ) : (\n        \"unknown\"\n      )}\n    </Badge>\n  </HoverCardTrigger>\n)\n\nexport type InlineCitationCardBodyProps = ComponentProps<\"div\">\n\nexport const InlineCitationCardBody = ({\n  className,\n  ...props\n}: InlineCitationCardBodyProps) => (\n  <HoverCardContent className={cn(\"relative w-80 p-0\", className)} {...props} />\n)\n\nconst CarouselApiContext = createContext<CarouselApi | undefined>(undefined)\n\nconst useCarouselApi = () => {\n  const context = useContext(CarouselApiContext)\n  return context\n}\n\nexport type InlineCitationCarouselProps = ComponentProps<typeof Carousel>\n\nexport const InlineCitationCarousel = ({\n  className,\n  children,\n  ...props\n}: InlineCitationCarouselProps) => {\n  const [api, setApi] = useState<CarouselApi>()\n\n  return (\n    <CarouselApiContext.Provider value={api}>\n      <Carousel className={cn(\"w-full\", className)} setApi={setApi} {...props}>\n        {children}\n      </Carousel>\n    </CarouselApiContext.Provider>\n  )\n}\n\nexport type InlineCitationCarouselContentProps = ComponentProps<\"div\">\n\nexport const InlineCitationCarouselContent = (\n  props: InlineCitationCarouselContentProps\n) => <CarouselContent {...props} />\n\nexport type InlineCitationCarouselItemProps = ComponentProps<\"div\">\n\nexport const InlineCitationCarouselItem = ({\n  className,\n  ...props\n}: InlineCitationCarouselItemProps) => (\n  <CarouselItem\n    className={cn(\"w-full space-y-2 p-4 pl-8\", className)}\n    {...props}\n  />\n)\n\nexport type InlineCitationCarouselHeaderProps = ComponentProps<\"div\">\n\nexport const InlineCitationCarouselHeader = ({\n  className,\n  ...props\n}: InlineCitationCarouselHeaderProps) => (\n  <div\n    className={cn(\n      \"bg-secondary flex items-center justify-between gap-2 rounded-t-md p-2\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type InlineCitationCarouselIndexProps = ComponentProps<\"div\">\n\nexport const InlineCitationCarouselIndex = ({\n  children,\n  className,\n  ...props\n}: InlineCitationCarouselIndexProps) => {\n  const api = useCarouselApi()\n  const [current, setCurrent] = useState(0)\n  const [count, setCount] = useState(0)\n\n  const syncState = useCallback(() => {\n    if (!api) {\n      return\n    }\n    setCount(api.scrollSnapList().length)\n    setCurrent(api.selectedScrollSnap() + 1)\n  }, [api])\n\n  useEffect(() => {\n    if (!api) {\n      return\n    }\n\n    syncState()\n\n    api.on(\"select\", syncState)\n\n    return () => {\n      api.off(\"select\", syncState)\n    }\n  }, [api, syncState])\n\n  return (\n    <div\n      className={cn(\n        \"text-muted-foreground flex flex-1 items-center justify-end px-3 py-1 text-xs\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? `${current}/${count}`}\n    </div>\n  )\n}\n\nexport type InlineCitationCarouselPrevProps = ComponentProps<\"button\">\n\nexport const InlineCitationCarouselPrev = ({\n  className,\n  ...props\n}: InlineCitationCarouselPrevProps) => {\n  const api = useCarouselApi()\n\n  const handleClick = useCallback(() => {\n    if (api) {\n      api.scrollPrev()\n    }\n  }, [api])\n\n  return (\n    <button\n      aria-label=\"Previous\"\n      className={cn(\"shrink-0\", className)}\n      onClick={handleClick}\n      type=\"button\"\n      {...props}\n    >\n      <ArrowLeftIcon className=\"text-muted-foreground size-4\" />\n    </button>\n  )\n}\n\nexport type InlineCitationCarouselNextProps = ComponentProps<\"button\">\n\nexport const InlineCitationCarouselNext = ({\n  className,\n  ...props\n}: InlineCitationCarouselNextProps) => {\n  const api = useCarouselApi()\n\n  const handleClick = useCallback(() => {\n    if (api) {\n      api.scrollNext()\n    }\n  }, [api])\n\n  return (\n    <button\n      aria-label=\"Next\"\n      className={cn(\"shrink-0\", className)}\n      onClick={handleClick}\n      type=\"button\"\n      {...props}\n    >\n      <ArrowRightIcon className=\"text-muted-foreground size-4\" />\n    </button>\n  )\n}\n\nexport type InlineCitationSourceProps = ComponentProps<\"div\"> & {\n  title?: string\n  url?: string\n  description?: string\n}\n\nexport const InlineCitationSource = ({\n  title,\n  url,\n  description,\n  className,\n  children,\n  ...props\n}: InlineCitationSourceProps) => (\n  <div className={cn(\"space-y-1\", className)} {...props}>\n    {title && (\n      <h4 className=\"truncate text-sm leading-tight font-medium\">{title}</h4>\n    )}\n    {url && (\n      <p className=\"text-muted-foreground truncate text-xs break-all\">{url}</p>\n    )}\n    {description && (\n      <p className=\"text-muted-foreground line-clamp-3 text-sm leading-relaxed\">\n        {description}\n      </p>\n    )}\n    {children}\n  </div>\n)\n\nexport type InlineCitationQuoteProps = ComponentProps<\"blockquote\">\n\nexport const InlineCitationQuote = ({\n  children,\n  className,\n  ...props\n}: InlineCitationQuoteProps) => (\n  <blockquote\n    className={cn(\n      \"border-muted text-muted-foreground border-l-2 pl-3 text-sm italic\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </blockquote>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/carousel.tsx",
          "target": "@components/ai-elements/_ui/carousel.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport useEmblaCarousel, {\n  type UseEmblaCarouselType,\n} from \"embla-carousel-react\"\nimport { ArrowLeft, ArrowRight } from \"lucide-react\"\nimport * as React from \"react\"\n\ntype CarouselApi = UseEmblaCarouselType[1]\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>\ntype CarouselOptions = UseCarouselParameters[0]\ntype CarouselPlugin = UseCarouselParameters[1]\n\ntype CarouselProps = {\n  opts?: CarouselOptions\n  plugins?: CarouselPlugin\n  orientation?: \"horizontal\" | \"vertical\"\n  setApi?: (api: CarouselApi) => void\n}\n\ntype CarouselContextProps = {\n  carouselRef: ReturnType<typeof useEmblaCarousel>[0]\n  api: ReturnType<typeof useEmblaCarousel>[1]\n  scrollPrev: () => void\n  scrollNext: () => void\n  canScrollPrev: boolean\n  canScrollNext: boolean\n} & CarouselProps\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null)\n\nfunction useCarousel() {\n  const context = React.useContext(CarouselContext)\n\n  if (!context) {\n    throw new Error(\"useCarousel must be used within a <Carousel />\")\n  }\n\n  return context\n}\n\nfunction Carousel({\n  orientation = \"horizontal\",\n  opts,\n  setApi,\n  plugins,\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\n  const [carouselRef, api] = useEmblaCarousel(\n    {\n      ...opts,\n      axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n    },\n    plugins\n  )\n  const [canScrollPrev, setCanScrollPrev] = React.useState(false)\n  const [canScrollNext, setCanScrollNext] = React.useState(false)\n\n  const onSelect = React.useCallback((api: CarouselApi) => {\n    if (!api) return\n    setCanScrollPrev(api.canScrollPrev())\n    setCanScrollNext(api.canScrollNext())\n  }, [])\n\n  const scrollPrev = React.useCallback(() => {\n    api?.scrollPrev()\n  }, [api])\n\n  const scrollNext = React.useCallback(() => {\n    api?.scrollNext()\n  }, [api])\n\n  const handleKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (event.key === \"ArrowLeft\") {\n        event.preventDefault()\n        scrollPrev()\n      } else if (event.key === \"ArrowRight\") {\n        event.preventDefault()\n        scrollNext()\n      }\n    },\n    [scrollPrev, scrollNext]\n  )\n\n  React.useEffect(() => {\n    if (!api || !setApi) return\n    setApi(api)\n  }, [api, setApi])\n\n  React.useEffect(() => {\n    if (!api) return\n    onSelect(api)\n    api.on(\"reInit\", onSelect)\n    api.on(\"select\", onSelect)\n\n    return () => {\n      api?.off(\"select\", onSelect)\n    }\n  }, [api, onSelect])\n\n  return (\n    <CarouselContext.Provider\n      value={{\n        carouselRef,\n        api: api,\n        opts,\n        orientation:\n          orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n        scrollPrev,\n        scrollNext,\n        canScrollPrev,\n        canScrollNext,\n      }}\n    >\n      <div\n        onKeyDownCapture={handleKeyDown}\n        className={cn(\"relative\", className)}\n        role=\"region\"\n        aria-roledescription=\"carousel\"\n        data-slot=\"carousel\"\n        {...props}\n      >\n        {children}\n      </div>\n    </CarouselContext.Provider>\n  )\n}\n\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  const { carouselRef, orientation } = useCarousel()\n\n  return (\n    <div\n      ref={carouselRef}\n      className=\"overflow-hidden\"\n      data-slot=\"carousel-content\"\n    >\n      <div\n        className={cn(\n          \"flex\",\n          orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  )\n}\n\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\n  const { orientation } = useCarousel()\n\n  return (\n    <div\n      role=\"group\"\n      aria-roledescription=\"slide\"\n      data-slot=\"carousel-item\"\n      className={cn(\n        \"min-w-0 shrink-0 grow-0 basis-full\",\n        orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CarouselPrevious({\n  className,\n  variant = \"outline\",\n  size = \"icon\",\n  ...props\n}: React.ComponentProps<typeof Button>) {\n  const { orientation, scrollPrev, canScrollPrev } = useCarousel()\n\n  return (\n    <Button\n      data-slot=\"carousel-previous\"\n      variant={variant}\n      size={size}\n      className={cn(\n        \"absolute size-8 rounded-full\",\n        orientation === \"horizontal\"\n          ? \"top-1/2 -left-12 -translate-y-1/2\"\n          : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n        className\n      )}\n      disabled={!canScrollPrev}\n      onClick={scrollPrev}\n      {...props}\n    >\n      <ArrowLeft />\n      <span className=\"sr-only\">Previous slide</span>\n    </Button>\n  )\n}\n\nfunction CarouselNext({\n  className,\n  variant = \"outline\",\n  size = \"icon\",\n  ...props\n}: React.ComponentProps<typeof Button>) {\n  const { orientation, scrollNext, canScrollNext } = useCarousel()\n\n  return (\n    <Button\n      data-slot=\"carousel-next\"\n      variant={variant}\n      size={size}\n      className={cn(\n        \"absolute size-8 rounded-full\",\n        orientation === \"horizontal\"\n          ? \"top-1/2 -right-12 -translate-y-1/2\"\n          : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n        className\n      )}\n      disabled={!canScrollNext}\n      onClick={scrollNext}\n      {...props}\n    >\n      <ArrowRight />\n      <span className=\"sr-only\">Next slide</span>\n    </Button>\n  )\n}\n\nexport {\n  type CarouselApi,\n  Carousel,\n  CarouselContent,\n  CarouselItem,\n  CarouselPrevious,\n  CarouselNext,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ai-elements/_ui/hover-card.tsx",
          "target": "@components/ai-elements/_ui/hover-card.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { HoverCard as HoverCardPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction HoverCard({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n  return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />\n}\n\nfunction HoverCardTrigger({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n  return (\n    <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n  )\n}\n\nfunction HoverCardContent({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n  return (\n    <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n      <HoverCardPrimitive.Content\n        data-slot=\"hover-card-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n          className\n        )}\n        {...props}\n      />\n    </HoverCardPrimitive.Portal>\n  )\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-jsx-preview",
      "type": "registry:block",
      "title": "Ai Elements Jsx Preview",
      "description": "jsx preview",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "react-jsx-parser@^2.4.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/jsx-preview.tsx",
          "target": "@components/ai-elements/jsx-preview.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { AlertCircle } from \"lucide-react\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport {\n  createContext,\n  memo,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport type { TProps as JsxParserProps } from \"react-jsx-parser\"\nimport JsxParser from \"react-jsx-parser\"\n\ninterface JSXPreviewContextValue {\n  jsx: string\n  processedJsx: string\n  isStreaming: boolean\n  error: Error | null\n  setError: (error: Error | null) => void\n  setLastGoodJsx: (jsx: string) => void\n  components: JsxParserProps[\"components\"]\n  bindings: JsxParserProps[\"bindings\"]\n  onErrorProp?: (error: Error) => void\n}\n\nconst JSXPreviewContext = createContext<JSXPreviewContextValue | null>(null)\n\nconst TAG_REGEX = /<\\/?([a-zA-Z][a-zA-Z0-9]*)\\s*([^>]*?)(\\/)?>/\n\nexport const useJSXPreview = () => {\n  const context = useContext(JSXPreviewContext)\n  if (!context) {\n    throw new Error(\"JSXPreview components must be used within JSXPreview\")\n  }\n  return context\n}\n\nconst matchJsxTag = (code: string) => {\n  if (code.trim() === \"\") {\n    return null\n  }\n\n  const match = code.match(TAG_REGEX)\n\n  if (!match || match.index === undefined) {\n    return null\n  }\n\n  const [fullMatch, tagName, attributes, selfClosing] = match\n\n  let type: \"self-closing\" | \"closing\" | \"opening\"\n  if (selfClosing) {\n    type = \"self-closing\"\n  } else if (fullMatch.startsWith(\"</\")) {\n    type = \"closing\"\n  } else {\n    type = \"opening\"\n  }\n\n  return {\n    attributes: attributes.trim(),\n    endIndex: match.index + fullMatch.length,\n    startIndex: match.index,\n    tag: fullMatch,\n    tagName,\n    type,\n  }\n}\n\nconst stripIncompleteTag = (text: string) => {\n  // Find the last '<' that isn't part of a complete tag\n  const lastOpen = text.lastIndexOf(\"<\")\n  if (lastOpen === -1) {\n    return text\n  }\n\n  const afterOpen = text.slice(lastOpen)\n  // If there's no closing '>' after the last '<', it's an incomplete tag\n  if (!afterOpen.includes(\">\")) {\n    return text.slice(0, lastOpen)\n  }\n\n  return text\n}\n\nconst completeJsxTag = (code: string) => {\n  const stack: string[] = []\n  let result = \"\"\n  let currentPosition = 0\n\n  while (currentPosition < code.length) {\n    const match = matchJsxTag(code.slice(currentPosition))\n    if (!match) {\n      // No more tags found, strip any trailing incomplete tag\n      result += stripIncompleteTag(code.slice(currentPosition))\n      break\n    }\n    const { tagName, type, endIndex } = match\n\n    // Include any text content before this tag\n    result += code.slice(currentPosition, currentPosition + endIndex)\n\n    if (type === \"opening\") {\n      stack.push(tagName)\n    } else if (type === \"closing\") {\n      stack.pop()\n    }\n\n    currentPosition += endIndex\n  }\n\n  return (\n    result +\n    stack\n      .toReversed()\n      .map((tag) => `</${tag}>`)\n      .join(\"\")\n  )\n}\n\nexport type JSXPreviewProps = Omit<ComponentProps<\"div\">, \"onError\"> & {\n  jsx: string\n  isStreaming?: boolean\n  components?: JsxParserProps[\"components\"]\n  bindings?: JsxParserProps[\"bindings\"]\n  onError?: (error: Error) => void\n}\n\nexport const JSXPreview = memo(\n  ({\n    jsx,\n    isStreaming = false,\n    components,\n    bindings,\n    onError,\n    className,\n    children,\n    ...props\n  }: JSXPreviewProps) => {\n    const [prevJsx, setPrevJsx] = useState(jsx)\n    const [error, setError] = useState<Error | null>(null)\n    const [, setLastGoodJsx] = useState(\"\")\n\n    // Clear error when jsx changes (derived state pattern)\n    if (jsx !== prevJsx) {\n      setPrevJsx(jsx)\n      setError(null)\n    }\n\n    const processedJsx = useMemo(\n      () => (isStreaming ? completeJsxTag(jsx) : jsx),\n      [jsx, isStreaming]\n    )\n\n    const contextValue = useMemo(\n      () => ({\n        bindings,\n        components,\n        error,\n        isStreaming,\n        jsx,\n        onErrorProp: onError,\n        processedJsx,\n        setError,\n        setLastGoodJsx,\n      }),\n      [\n        bindings,\n        components,\n        error,\n        isStreaming,\n        jsx,\n        onError,\n        processedJsx,\n        setError,\n      ]\n    )\n\n    return (\n      <JSXPreviewContext.Provider value={contextValue}>\n        <div className={cn(\"relative\", className)} {...props}>\n          {children}\n        </div>\n      </JSXPreviewContext.Provider>\n    )\n  }\n)\n\nJSXPreview.displayName = \"JSXPreview\"\n\nexport type JSXPreviewContentProps = Omit<ComponentProps<\"div\">, \"children\">\n\nexport const JSXPreviewContent = memo(\n  ({ className, ...props }: JSXPreviewContentProps) => {\n    const {\n      processedJsx,\n      isStreaming,\n      components,\n      bindings,\n      setError,\n      setLastGoodJsx,\n      onErrorProp,\n    } = useJSXPreview()\n    const errorReportedRef = useRef<string | null>(null)\n    const lastGoodJsxRef = useRef(\"\")\n    const [hadError, setHadError] = useState(false)\n\n    // Reset error tracking when jsx changes\n    useEffect(() => {\n      errorReportedRef.current = null\n      setHadError(false)\n    }, [processedJsx])\n\n    const handleError = useCallback(\n      (err: Error) => {\n        // Prevent duplicate error reports for the same jsx\n        if (errorReportedRef.current === processedJsx) {\n          return\n        }\n        errorReportedRef.current = processedJsx\n\n        // During streaming, suppress errors and fall back to last good JSX\n        if (isStreaming) {\n          setHadError(true)\n          return\n        }\n\n        setError(err)\n        onErrorProp?.(err)\n      },\n      [processedJsx, isStreaming, onErrorProp, setError]\n    )\n\n    // Track the last JSX that rendered without error\n    useEffect(() => {\n      if (!errorReportedRef.current) {\n        lastGoodJsxRef.current = processedJsx\n        setLastGoodJsx(processedJsx)\n      }\n    }, [processedJsx, setLastGoodJsx])\n\n    // During streaming, if the current JSX errored, re-render with last good version\n    const displayJsx =\n      isStreaming && hadError ? lastGoodJsxRef.current : processedJsx\n\n    return (\n      <div className={cn(\"jsx-preview-content\", className)} {...props}>\n        <JsxParser\n          bindings={bindings}\n          components={components}\n          jsx={displayJsx}\n          onError={handleError}\n          renderInWrapper={false}\n        />\n      </div>\n    )\n  }\n)\n\nJSXPreviewContent.displayName = \"JSXPreviewContent\"\n\nexport type JSXPreviewErrorProps = ComponentProps<\"div\"> & {\n  children?: ReactNode | ((error: Error) => ReactNode)\n}\n\nconst renderChildren = (\n  children: ReactNode | ((error: Error) => ReactNode),\n  error: Error\n): ReactNode => {\n  if (typeof children === \"function\") {\n    return children(error)\n  }\n  return children\n}\n\nexport const JSXPreviewError = memo(\n  ({ className, children, ...props }: JSXPreviewErrorProps) => {\n    const { error } = useJSXPreview()\n\n    if (!error) {\n      return null\n    }\n\n    return (\n      <div\n        className={cn(\n          \"border-destructive/50 bg-destructive/10 text-destructive flex items-center gap-2 rounded-md border p-3 text-sm\",\n          className\n        )}\n        {...props}\n      >\n        {children ? (\n          renderChildren(children, error)\n        ) : (\n          <>\n            <AlertCircle className=\"size-4 shrink-0\" />\n            <span>{error.message}</span>\n          </>\n        )}\n      </div>\n    )\n  }\n)\n\nJSXPreviewError.displayName = \"JSXPreviewError\"\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-message",
      "type": "registry:block",
      "title": "Ai Elements Message",
      "description": "message",
      "dependencies": [
        "@streamdown/cjk@1.0.2",
        "@streamdown/code@1.1.0",
        "@streamdown/math@1.0.2",
        "@streamdown/mermaid@1.0.2",
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "katex@0.16.28",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "streamdown@2.4.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/message.tsx",
          "target": "@components/ai-elements/message.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  ButtonGroup,\n  ButtonGroupText,\n} from \"@/components/ai-elements/_ui/button-group\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ai-elements/_ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport { cjk } from \"@streamdown/cjk\"\nimport { code } from \"@streamdown/code\"\nimport { math } from \"@streamdown/math\"\nimport { mermaid } from \"@streamdown/mermaid\"\nimport type { UIMessage } from \"ai\"\nimport { ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes, ReactElement } from \"react\"\nimport {\n  createContext,\n  memo,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useState,\n} from \"react\"\nimport { Streamdown } from \"streamdown\"\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n  from: UIMessage[\"role\"]\n}\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n  <div\n    className={cn(\n      \"group flex w-full max-w-[95%] flex-col gap-2\",\n      from === \"user\" ? \"is-user ml-auto justify-end\" : \"is-assistant\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const MessageContent = ({\n  children,\n  className,\n  ...props\n}: MessageContentProps) => (\n  <div\n    className={cn(\n      \"is-user:dark flex w-fit max-w-full min-w-0 flex-col gap-2 overflow-hidden text-sm\",\n      \"group-[.is-user]:bg-secondary group-[.is-user]:text-foreground group-[.is-user]:ml-auto group-[.is-user]:rounded-lg group-[.is-user]:px-4 group-[.is-user]:py-3\",\n      \"group-[.is-assistant]:text-foreground\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type MessageActionsProps = ComponentProps<\"div\">\n\nexport const MessageActions = ({\n  className,\n  children,\n  ...props\n}: MessageActionsProps) => (\n  <div className={cn(\"flex items-center gap-1\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type MessageActionProps = ComponentProps<typeof Button> & {\n  tooltip?: string\n  label?: string\n}\n\nexport const MessageAction = ({\n  tooltip,\n  children,\n  label,\n  variant = \"ghost\",\n  size = \"icon-sm\",\n  ...props\n}: MessageActionProps) => {\n  const button = (\n    <Button size={size} type=\"button\" variant={variant} {...props}>\n      {children}\n      <span className=\"sr-only\">{label || tooltip}</span>\n    </Button>\n  )\n\n  if (tooltip) {\n    return (\n      <TooltipProvider>\n        <Tooltip>\n          <TooltipTrigger asChild>{button}</TooltipTrigger>\n          <TooltipContent>\n            <p>{tooltip}</p>\n          </TooltipContent>\n        </Tooltip>\n      </TooltipProvider>\n    )\n  }\n\n  return button\n}\n\ninterface MessageBranchContextType {\n  currentBranch: number\n  totalBranches: number\n  goToPrevious: () => void\n  goToNext: () => void\n  branches: ReactElement[]\n  setBranches: (branches: ReactElement[]) => void\n}\n\nconst MessageBranchContext = createContext<MessageBranchContextType | null>(\n  null\n)\n\nconst useMessageBranch = () => {\n  const context = useContext(MessageBranchContext)\n\n  if (!context) {\n    throw new Error(\n      \"MessageBranch components must be used within MessageBranch\"\n    )\n  }\n\n  return context\n}\n\nexport type MessageBranchProps = HTMLAttributes<HTMLDivElement> & {\n  defaultBranch?: number\n  onBranchChange?: (branchIndex: number) => void\n}\n\nexport const MessageBranch = ({\n  defaultBranch = 0,\n  onBranchChange,\n  className,\n  ...props\n}: MessageBranchProps) => {\n  const [currentBranch, setCurrentBranch] = useState(defaultBranch)\n  const [branches, setBranches] = useState<ReactElement[]>([])\n\n  const handleBranchChange = useCallback(\n    (newBranch: number) => {\n      setCurrentBranch(newBranch)\n      onBranchChange?.(newBranch)\n    },\n    [onBranchChange]\n  )\n\n  const goToPrevious = useCallback(() => {\n    const newBranch =\n      currentBranch > 0 ? currentBranch - 1 : branches.length - 1\n    handleBranchChange(newBranch)\n  }, [currentBranch, branches.length, handleBranchChange])\n\n  const goToNext = useCallback(() => {\n    const newBranch =\n      currentBranch < branches.length - 1 ? currentBranch + 1 : 0\n    handleBranchChange(newBranch)\n  }, [currentBranch, branches.length, handleBranchChange])\n\n  const contextValue = useMemo<MessageBranchContextType>(\n    () => ({\n      branches,\n      currentBranch,\n      goToNext,\n      goToPrevious,\n      setBranches,\n      totalBranches: branches.length,\n    }),\n    [branches, currentBranch, goToNext, goToPrevious]\n  )\n\n  return (\n    <MessageBranchContext.Provider value={contextValue}>\n      <div\n        className={cn(\"grid w-full gap-2 [&>div]:pb-0\", className)}\n        {...props}\n      />\n    </MessageBranchContext.Provider>\n  )\n}\n\nexport type MessageBranchContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const MessageBranchContent = ({\n  children,\n  ...props\n}: MessageBranchContentProps) => {\n  const { currentBranch, setBranches, branches } = useMessageBranch()\n  const childrenArray = useMemo(\n    () => (Array.isArray(children) ? children : [children]),\n    [children]\n  )\n\n  // Use useEffect to update branches when they change\n  useEffect(() => {\n    if (branches.length !== childrenArray.length) {\n      setBranches(childrenArray)\n    }\n  }, [childrenArray, branches, setBranches])\n\n  return childrenArray.map((branch, index) => (\n    <div\n      className={cn(\n        \"grid gap-2 overflow-hidden [&>div]:pb-0\",\n        index === currentBranch ? \"block\" : \"hidden\"\n      )}\n      key={branch.key}\n      {...props}\n    >\n      {branch}\n    </div>\n  ))\n}\n\nexport type MessageBranchSelectorProps = ComponentProps<typeof ButtonGroup>\n\nexport const MessageBranchSelector = ({\n  className,\n  ...props\n}: MessageBranchSelectorProps) => {\n  const { totalBranches } = useMessageBranch()\n\n  // Don't render if there's only one branch\n  if (totalBranches <= 1) {\n    return null\n  }\n\n  return (\n    <ButtonGroup\n      className={cn(\n        \"[&>*:not(:first-child)]:rounded-l-md [&>*:not(:last-child)]:rounded-r-md\",\n        className\n      )}\n      orientation=\"horizontal\"\n      {...props}\n    />\n  )\n}\n\nexport type MessageBranchPreviousProps = ComponentProps<typeof Button>\n\nexport const MessageBranchPrevious = ({\n  children,\n  ...props\n}: MessageBranchPreviousProps) => {\n  const { goToPrevious, totalBranches } = useMessageBranch()\n\n  return (\n    <Button\n      aria-label=\"Previous branch\"\n      disabled={totalBranches <= 1}\n      onClick={goToPrevious}\n      size=\"icon-sm\"\n      type=\"button\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <ChevronLeftIcon size={14} />}\n    </Button>\n  )\n}\n\nexport type MessageBranchNextProps = ComponentProps<typeof Button>\n\nexport const MessageBranchNext = ({\n  children,\n  ...props\n}: MessageBranchNextProps) => {\n  const { goToNext, totalBranches } = useMessageBranch()\n\n  return (\n    <Button\n      aria-label=\"Next branch\"\n      disabled={totalBranches <= 1}\n      onClick={goToNext}\n      size=\"icon-sm\"\n      type=\"button\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <ChevronRightIcon size={14} />}\n    </Button>\n  )\n}\n\nexport type MessageBranchPageProps = HTMLAttributes<HTMLSpanElement>\n\nexport const MessageBranchPage = ({\n  className,\n  ...props\n}: MessageBranchPageProps) => {\n  const { currentBranch, totalBranches } = useMessageBranch()\n\n  return (\n    <ButtonGroupText\n      className={cn(\n        \"text-muted-foreground border-none bg-transparent shadow-none\",\n        className\n      )}\n      {...props}\n    >\n      {currentBranch + 1} of {totalBranches}\n    </ButtonGroupText>\n  )\n}\n\nexport type MessageResponseProps = ComponentProps<typeof Streamdown>\n\nconst streamdownPlugins = { cjk, code, math, mermaid }\n\nexport const MessageResponse = memo(\n  ({ className, ...props }: MessageResponseProps) => (\n    <Streamdown\n      className={cn(\n        \"size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0\",\n        className\n      )}\n      plugins={streamdownPlugins}\n      {...props}\n    />\n  ),\n  (prevProps, nextProps) =>\n    prevProps.children === nextProps.children &&\n    nextProps.isAnimating === prevProps.isAnimating\n)\n\nMessageResponse.displayName = \"MessageResponse\"\n\nexport type MessageToolbarProps = ComponentProps<\"div\">\n\nexport const MessageToolbar = ({\n  className,\n  children,\n  ...props\n}: MessageToolbarProps) => (\n  <div\n    className={cn(\n      \"mt-4 flex w-full items-center justify-between gap-4\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button-group.tsx",
          "target": "@components/ai-elements/_ui/button-group.tsx",
          "type": "registry:component",
          "content": "import { Separator } from \"@/components/ai-elements/_ui/separator\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\n\nconst buttonGroupVariants = cva(\n  \"flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2\",\n  {\n    variants: {\n      orientation: {\n        horizontal:\n          \"[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none\",\n        vertical:\n          \"flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none\",\n      },\n    },\n    defaultVariants: {\n      orientation: \"horizontal\",\n    },\n  }\n)\n\nfunction ButtonGroup({\n  className,\n  orientation,\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof buttonGroupVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"button-group\"\n      data-orientation={orientation}\n      className={cn(buttonGroupVariants({ orientation }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction ButtonGroupText({\n  className,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  asChild?: boolean\n}) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"div\"\n\n  return (\n    <Comp\n      className={cn(\n        \"bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ButtonGroupSeparator({\n  className,\n  orientation = \"vertical\",\n  ...props\n}: React.ComponentProps<typeof Separator>) {\n  return (\n    <Separator\n      data-slot=\"button-group-separator\"\n      orientation={orientation}\n      className={cn(\n        \"bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  ButtonGroup,\n  ButtonGroupSeparator,\n  ButtonGroupText,\n  buttonGroupVariants,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/separator.tsx",
          "target": "@components/ai-elements/_ui/separator.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Separator as SeparatorPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Separator({\n  className,\n  orientation = \"horizontal\",\n  decorative = true,\n  ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n  return (\n    <SeparatorPrimitive.Root\n      data-slot=\"separator\"\n      decorative={decorative}\n      orientation={orientation}\n      className={cn(\n        \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Separator }\n"
        },
        {
          "path": "components/ai-elements/_ui/tooltip.tsx",
          "target": "@components/ai-elements/_ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 0,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/markdown.css",
          "target": "@components/ai-elements/markdown.css",
          "type": "registry:file",
          "content": "@import \"streamdown/styles.css\";\n@import \"katex/dist/katex.min.css\";\n\n@source \"../../node_modules/streamdown/dist\";\n@source \"../../node_modules/@streamdown/code/dist\";\n@source \"../../node_modules/@streamdown/cjk/dist\";\n@source \"../../node_modules/@streamdown/math/dist\";\n@source \"../../node_modules/@streamdown/mermaid/dist\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-mic-selector",
      "type": "registry:block",
      "title": "Ai Elements Mic Selector",
      "description": "mic selector",
      "dependencies": [
        "@radix-ui/react-use-controllable-state@1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "cmdk@1.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/mic-selector.tsx",
          "target": "@components/ai-elements/mic-selector.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Command,\n  CommandEmpty,\n  CommandInput,\n  CommandItem,\n  CommandList,\n} from \"@/components/ai-elements/_ui/command\"\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from \"@/components/ai-elements/_ui/popover\"\nimport { cn } from \"@/lib/utils\"\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\"\nimport { ChevronsUpDownIcon } from \"lucide-react\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\nconst deviceIdRegex = /\\(([\\da-fA-F]{4}:[\\da-fA-F]{4})\\)$/\n\ninterface MicSelectorContextType {\n  data: MediaDeviceInfo[]\n  value: string | undefined\n  onValueChange?: (value: string) => void\n  open: boolean\n  onOpenChange?: (open: boolean) => void\n  width: number\n  setWidth?: (width: number) => void\n}\n\nconst MicSelectorContext = createContext<MicSelectorContextType>({\n  data: [],\n  onOpenChange: undefined,\n  onValueChange: undefined,\n  open: false,\n  setWidth: undefined,\n  value: undefined,\n  width: 200,\n})\n\nexport const useAudioDevices = () => {\n  const [devices, setDevices] = useState<MediaDeviceInfo[]>([])\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState<string | null>(null)\n  const [hasPermission, setHasPermission] = useState(false)\n\n  const loadDevicesWithoutPermission = useCallback(async () => {\n    try {\n      setLoading(true)\n      setError(null)\n\n      const deviceList = await navigator.mediaDevices.enumerateDevices()\n      const audioInputs = deviceList.filter(\n        (device) => device.kind === \"audioinput\"\n      )\n\n      setDevices(audioInputs)\n    } catch (caughtError) {\n      const message =\n        caughtError instanceof Error\n          ? caughtError.message\n          : \"Failed to get audio devices\"\n\n      setError(message)\n      console.error(\"Error getting audio devices:\", message)\n    } finally {\n      setLoading(false)\n    }\n  }, [])\n\n  const loadDevicesWithPermission = useCallback(async () => {\n    if (loading) {\n      return\n    }\n\n    try {\n      setLoading(true)\n      setError(null)\n\n      const tempStream = await navigator.mediaDevices.getUserMedia({\n        audio: true,\n      })\n\n      for (const track of tempStream.getTracks()) {\n        track.stop()\n      }\n\n      const deviceList = await navigator.mediaDevices.enumerateDevices()\n      const audioInputs = deviceList.filter(\n        (device) => device.kind === \"audioinput\"\n      )\n\n      setDevices(audioInputs)\n      setHasPermission(true)\n    } catch (caughtError) {\n      const message =\n        caughtError instanceof Error\n          ? caughtError.message\n          : \"Failed to get audio devices\"\n\n      setError(message)\n      console.error(\"Error getting audio devices:\", message)\n    } finally {\n      setLoading(false)\n    }\n  }, [loading])\n\n  useEffect(() => {\n    loadDevicesWithoutPermission()\n  }, [loadDevicesWithoutPermission])\n\n  useEffect(() => {\n    const handleDeviceChange = () => {\n      if (hasPermission) {\n        loadDevicesWithPermission()\n      } else {\n        loadDevicesWithoutPermission()\n      }\n    }\n\n    navigator.mediaDevices.addEventListener(\"devicechange\", handleDeviceChange)\n\n    return () => {\n      navigator.mediaDevices.removeEventListener(\n        \"devicechange\",\n        handleDeviceChange\n      )\n    }\n  }, [hasPermission, loadDevicesWithPermission, loadDevicesWithoutPermission])\n\n  return {\n    devices,\n    error,\n    hasPermission,\n    loadDevices: loadDevicesWithPermission,\n    loading,\n  }\n}\n\nexport type MicSelectorProps = ComponentProps<typeof Popover> & {\n  defaultValue?: string\n  value?: string | undefined\n  onValueChange?: (value: string | undefined) => void\n  open?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nexport const MicSelector = ({\n  defaultValue,\n  value: controlledValue,\n  onValueChange: controlledOnValueChange,\n  defaultOpen = false,\n  open: controlledOpen,\n  onOpenChange: controlledOnOpenChange,\n  ...props\n}: MicSelectorProps) => {\n  const [value, onValueChange] = useControllableState<string | undefined>({\n    defaultProp: defaultValue,\n    onChange: controlledOnValueChange,\n    prop: controlledValue,\n  })\n  const [open, onOpenChange] = useControllableState({\n    defaultProp: defaultOpen,\n    onChange: controlledOnOpenChange,\n    prop: controlledOpen,\n  })\n  const [width, setWidth] = useState(200)\n  const { devices, loading, hasPermission, loadDevices } = useAudioDevices()\n\n  useEffect(() => {\n    if (open && !hasPermission && !loading) {\n      loadDevices()\n    }\n  }, [open, hasPermission, loading, loadDevices])\n\n  const contextValue = useMemo(\n    () => ({\n      data: devices,\n      onOpenChange,\n      onValueChange,\n      open,\n      setWidth,\n      value,\n      width,\n    }),\n    [devices, onOpenChange, onValueChange, open, setWidth, value, width]\n  )\n\n  return (\n    <MicSelectorContext.Provider value={contextValue}>\n      <Popover {...props} onOpenChange={onOpenChange} open={open} />\n    </MicSelectorContext.Provider>\n  )\n}\n\nexport type MicSelectorTriggerProps = ComponentProps<typeof Button>\n\nexport const MicSelectorTrigger = ({\n  children,\n  ...props\n}: MicSelectorTriggerProps) => {\n  const { setWidth } = useContext(MicSelectorContext)\n  const ref = useRef<HTMLButtonElement>(null)\n\n  useEffect(() => {\n    // Create a ResizeObserver to detect width changes\n    const resizeObserver = new ResizeObserver((entries) => {\n      for (const entry of entries) {\n        const newWidth = (entry.target as HTMLElement).offsetWidth\n        if (newWidth) {\n          setWidth?.(newWidth)\n        }\n      }\n    })\n\n    if (ref.current) {\n      resizeObserver.observe(ref.current)\n    }\n\n    // Clean up the observer when component unmounts\n    return () => {\n      resizeObserver.disconnect()\n    }\n  }, [setWidth])\n\n  return (\n    <PopoverTrigger asChild>\n      <Button variant=\"outline\" {...props} ref={ref}>\n        {children}\n        <ChevronsUpDownIcon\n          className=\"text-muted-foreground shrink-0\"\n          size={16}\n        />\n      </Button>\n    </PopoverTrigger>\n  )\n}\n\nexport type MicSelectorContentProps = ComponentProps<typeof Command> & {\n  popoverOptions?: ComponentProps<typeof PopoverContent>\n}\n\nexport const MicSelectorContent = ({\n  className,\n  popoverOptions,\n  ...props\n}: MicSelectorContentProps) => {\n  const { width, onValueChange, value } = useContext(MicSelectorContext)\n\n  return (\n    <PopoverContent\n      className={cn(\"p-0\", className)}\n      style={{ width }}\n      {...popoverOptions}\n    >\n      <Command onValueChange={onValueChange} value={value} {...props} />\n    </PopoverContent>\n  )\n}\n\nexport type MicSelectorInputProps = ComponentProps<typeof CommandInput> & {\n  value?: string\n  defaultValue?: string\n  onValueChange?: (value: string) => void\n}\n\nexport const MicSelectorInput = ({ ...props }: MicSelectorInputProps) => (\n  <CommandInput placeholder=\"Search microphones...\" {...props} />\n)\n\nexport type MicSelectorListProps = Omit<\n  ComponentProps<typeof CommandList>,\n  \"children\"\n> & {\n  children: (devices: MediaDeviceInfo[]) => ReactNode\n}\n\nexport const MicSelectorList = ({\n  children,\n  ...props\n}: MicSelectorListProps) => {\n  const { data } = useContext(MicSelectorContext)\n\n  return <CommandList {...props}>{children(data)}</CommandList>\n}\n\nexport type MicSelectorEmptyProps = ComponentProps<typeof CommandEmpty>\n\nexport const MicSelectorEmpty = ({\n  children = \"No microphone found.\",\n  ...props\n}: MicSelectorEmptyProps) => <CommandEmpty {...props}>{children}</CommandEmpty>\n\nexport type MicSelectorItemProps = ComponentProps<typeof CommandItem>\n\nexport const MicSelectorItem = (props: MicSelectorItemProps) => {\n  const { onValueChange, onOpenChange } = useContext(MicSelectorContext)\n\n  const handleSelect = useCallback(\n    (currentValue: string) => {\n      onValueChange?.(currentValue)\n      onOpenChange?.(false)\n    },\n    [onValueChange, onOpenChange]\n  )\n\n  return <CommandItem onSelect={handleSelect} {...props} />\n}\n\nexport type MicSelectorLabelProps = ComponentProps<\"span\"> & {\n  device: MediaDeviceInfo\n}\n\nexport const MicSelectorLabel = ({\n  device,\n  className,\n  ...props\n}: MicSelectorLabelProps) => {\n  const matches = device.label.match(deviceIdRegex)\n\n  if (!matches) {\n    return (\n      <span className={className} {...props}>\n        {device.label}\n      </span>\n    )\n  }\n\n  const [, deviceId] = matches\n  const name = device.label.replace(deviceIdRegex, \"\")\n\n  return (\n    <span className={className} {...props}>\n      <span>{name}</span>\n      <span className=\"text-muted-foreground\"> ({deviceId})</span>\n    </span>\n  )\n}\n\nexport type MicSelectorValueProps = ComponentProps<\"span\">\n\nexport const MicSelectorValue = ({\n  className,\n  ...props\n}: MicSelectorValueProps) => {\n  const { data, value } = useContext(MicSelectorContext)\n  const currentDevice = data.find((d) => d.deviceId === value)\n\n  if (!currentDevice) {\n    return (\n      <span className={cn(\"flex-1 text-left\", className)} {...props}>\n        Select microphone...\n      </span>\n    )\n  }\n\n  return (\n    <MicSelectorLabel\n      className={cn(\"flex-1 text-left\", className)}\n      device={currentDevice}\n      {...props}\n    />\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/command.tsx",
          "target": "@components/ai-elements/_ui/command.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ai-elements/_ui/dialog\"\nimport { cn } from \"@/lib/utils\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction Command({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\n        \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandDialog({\n  title = \"Command Palette\",\n  description = \"Search for a command to run...\",\n  children,\n  className,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string\n  description?: string\n  className?: string\n  showCloseButton?: boolean\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent\n        className={cn(\"overflow-hidden p-0\", className)}\n        showCloseButton={showCloseButton}\n      >\n        <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction CommandInput({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div\n      data-slot=\"command-input-wrapper\"\n      className=\"flex h-9 items-center gap-2 border-b px-3\"\n    >\n      <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n      <CommandPrimitive.Input\n        data-slot=\"command-input\"\n        className={cn(\n          \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  )\n}\n\nfunction CommandList({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(\n        \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandEmpty({\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return (\n    <CommandPrimitive.Empty\n      data-slot=\"command-empty\"\n      className=\"py-6 text-center text-sm\"\n      {...props}\n    />\n  )\n}\n\nfunction CommandGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(\"bg-border -mx-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandItem({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"command-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandInput,\n  CommandList,\n  CommandEmpty,\n  CommandGroup,\n  CommandItem,\n  CommandShortcut,\n  CommandSeparator,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/dialog.tsx",
          "target": "@components/ai-elements/_ui/dialog.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as DialogPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Dialog({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n  showCloseButton?: boolean\n}) {\n  return (\n    <DialogPortal data-slot=\"dialog-portal\">\n      <DialogOverlay />\n      <DialogPrimitive.Content\n        data-slot=\"dialog-content\"\n        className={cn(\n          \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <DialogPrimitive.Close\n            data-slot=\"dialog-close\"\n            className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n          >\n            <XIcon />\n            <span className=\"sr-only\">Close</span>\n          </DialogPrimitive.Close>\n        )}\n      </DialogPrimitive.Content>\n    </DialogPortal>\n  )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"text-lg leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/popover.tsx",
          "target": "@components/ai-elements/_ui/popover.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Popover as PopoverPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Popover({\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n  return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n  return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n  return (\n    <PopoverPrimitive.Portal>\n      <PopoverPrimitive.Content\n        data-slot=\"popover-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n          className\n        )}\n        {...props}\n      />\n    </PopoverPrimitive.Portal>\n  )\n}\n\nfunction PopoverAnchor({\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n  return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-model-selector",
      "type": "registry:block",
      "title": "Ai Elements Model Selector",
      "description": "model selector",
      "dependencies": [
        "clsx@^2.1.1",
        "cmdk@1.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/model-selector.tsx",
          "target": "@components/ai-elements/model-selector.tsx",
          "type": "registry:component",
          "content": "import {\n  Command,\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n} from \"@/components/ai-elements/_ui/command\"\nimport {\n  Dialog,\n  DialogContent,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ai-elements/_ui/dialog\"\nimport { cn } from \"@/lib/utils\"\nimport type { ComponentProps, ReactNode } from \"react\"\n\nexport type ModelSelectorProps = ComponentProps<typeof Dialog>\n\nexport const ModelSelector = (props: ModelSelectorProps) => (\n  <Dialog {...props} />\n)\n\nexport type ModelSelectorTriggerProps = ComponentProps<typeof DialogTrigger>\n\nexport const ModelSelectorTrigger = (props: ModelSelectorTriggerProps) => (\n  <DialogTrigger {...props} />\n)\n\nexport type ModelSelectorContentProps = ComponentProps<typeof DialogContent> & {\n  title?: ReactNode\n}\n\nexport const ModelSelectorContent = ({\n  className,\n  children,\n  title = \"Model Selector\",\n  ...props\n}: ModelSelectorContentProps) => (\n  <DialogContent\n    aria-describedby={undefined}\n    className={cn(\n      \"outline-border! border-none! p-0 outline! outline-solid!\",\n      className\n    )}\n    {...props}\n  >\n    <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n    <Command className=\"**:data-[slot=command-input-wrapper]:h-auto\">\n      {children}\n    </Command>\n  </DialogContent>\n)\n\nexport type ModelSelectorDialogProps = ComponentProps<typeof CommandDialog>\n\nexport const ModelSelectorDialog = (props: ModelSelectorDialogProps) => (\n  <CommandDialog {...props} />\n)\n\nexport type ModelSelectorInputProps = ComponentProps<typeof CommandInput>\n\nexport const ModelSelectorInput = ({\n  className,\n  ...props\n}: ModelSelectorInputProps) => (\n  <CommandInput className={cn(\"h-auto py-3.5\", className)} {...props} />\n)\n\nexport type ModelSelectorListProps = ComponentProps<typeof CommandList>\n\nexport const ModelSelectorList = (props: ModelSelectorListProps) => (\n  <CommandList {...props} />\n)\n\nexport type ModelSelectorEmptyProps = ComponentProps<typeof CommandEmpty>\n\nexport const ModelSelectorEmpty = (props: ModelSelectorEmptyProps) => (\n  <CommandEmpty {...props} />\n)\n\nexport type ModelSelectorGroupProps = ComponentProps<typeof CommandGroup>\n\nexport const ModelSelectorGroup = (props: ModelSelectorGroupProps) => (\n  <CommandGroup {...props} />\n)\n\nexport type ModelSelectorItemProps = ComponentProps<typeof CommandItem>\n\nexport const ModelSelectorItem = (props: ModelSelectorItemProps) => (\n  <CommandItem {...props} />\n)\n\nexport type ModelSelectorShortcutProps = ComponentProps<typeof CommandShortcut>\n\nexport const ModelSelectorShortcut = (props: ModelSelectorShortcutProps) => (\n  <CommandShortcut {...props} />\n)\n\nexport type ModelSelectorSeparatorProps = ComponentProps<\n  typeof CommandSeparator\n>\n\nexport const ModelSelectorSeparator = (props: ModelSelectorSeparatorProps) => (\n  <CommandSeparator {...props} />\n)\n\nexport type ModelSelectorLogoProps = Omit<\n  ComponentProps<\"img\">,\n  \"src\" | \"alt\"\n> & {\n  provider:\n    | \"moonshotai-cn\"\n    | \"lucidquery\"\n    | \"moonshotai\"\n    | \"zai-coding-plan\"\n    | \"alibaba\"\n    | \"xai\"\n    | \"vultr\"\n    | \"nvidia\"\n    | \"upstage\"\n    | \"groq\"\n    | \"github-copilot\"\n    | \"mistral\"\n    | \"vercel\"\n    | \"nebius\"\n    | \"deepseek\"\n    | \"alibaba-cn\"\n    | \"google-vertex-anthropic\"\n    | \"venice\"\n    | \"chutes\"\n    | \"cortecs\"\n    | \"github-models\"\n    | \"togetherai\"\n    | \"azure\"\n    | \"baseten\"\n    | \"huggingface\"\n    | \"opencode\"\n    | \"fastrouter\"\n    | \"google\"\n    | \"google-vertex\"\n    | \"cloudflare-workers-ai\"\n    | \"inception\"\n    | \"wandb\"\n    | \"openai\"\n    | \"zhipuai-coding-plan\"\n    | \"perplexity\"\n    | \"openrouter\"\n    | \"zenmux\"\n    | \"v0\"\n    | \"iflowcn\"\n    | \"synthetic\"\n    | \"deepinfra\"\n    | \"zhipuai\"\n    | \"submodel\"\n    | \"zai\"\n    | \"inference\"\n    | \"requesty\"\n    | \"morph\"\n    | \"lmstudio\"\n    | \"anthropic\"\n    | \"aihubmix\"\n    | \"fireworks-ai\"\n    | \"modelscope\"\n    | \"llama\"\n    | \"scaleway\"\n    | \"amazon-bedrock\"\n    | \"cerebras\"\n    // oxlint-disable-next-line typescript-eslint(ban-types) -- intentional pattern for autocomplete-friendly string union\n    | (string & {})\n}\n\nexport const ModelSelectorLogo = ({\n  provider,\n  className,\n  ...props\n}: ModelSelectorLogoProps) => (\n  <img\n    {...props}\n    alt={`${provider} logo`}\n    className={cn(\"size-3 dark:invert\", className)}\n    height={12}\n    src={`https://models.dev/logos/${provider}.svg`}\n    width={12}\n  />\n)\n\nexport type ModelSelectorLogoGroupProps = ComponentProps<\"div\">\n\nexport const ModelSelectorLogoGroup = ({\n  className,\n  ...props\n}: ModelSelectorLogoGroupProps) => (\n  <div\n    className={cn(\n      \"[&>img]:bg-background dark:[&>img]:bg-foreground flex shrink-0 items-center -space-x-1 [&>img]:rounded-full [&>img]:p-px [&>img]:ring-1\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type ModelSelectorNameProps = ComponentProps<\"span\">\n\nexport const ModelSelectorName = ({\n  className,\n  ...props\n}: ModelSelectorNameProps) => (\n  <span className={cn(\"flex-1 truncate text-left\", className)} {...props} />\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/command.tsx",
          "target": "@components/ai-elements/_ui/command.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ai-elements/_ui/dialog\"\nimport { cn } from \"@/lib/utils\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction Command({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\n        \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandDialog({\n  title = \"Command Palette\",\n  description = \"Search for a command to run...\",\n  children,\n  className,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string\n  description?: string\n  className?: string\n  showCloseButton?: boolean\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent\n        className={cn(\"overflow-hidden p-0\", className)}\n        showCloseButton={showCloseButton}\n      >\n        <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction CommandInput({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div\n      data-slot=\"command-input-wrapper\"\n      className=\"flex h-9 items-center gap-2 border-b px-3\"\n    >\n      <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n      <CommandPrimitive.Input\n        data-slot=\"command-input\"\n        className={cn(\n          \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  )\n}\n\nfunction CommandList({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(\n        \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandEmpty({\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return (\n    <CommandPrimitive.Empty\n      data-slot=\"command-empty\"\n      className=\"py-6 text-center text-sm\"\n      {...props}\n    />\n  )\n}\n\nfunction CommandGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(\"bg-border -mx-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandItem({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"command-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandInput,\n  CommandList,\n  CommandEmpty,\n  CommandGroup,\n  CommandItem,\n  CommandShortcut,\n  CommandSeparator,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/dialog.tsx",
          "target": "@components/ai-elements/_ui/dialog.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as DialogPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Dialog({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n  showCloseButton?: boolean\n}) {\n  return (\n    <DialogPortal data-slot=\"dialog-portal\">\n      <DialogOverlay />\n      <DialogPrimitive.Content\n        data-slot=\"dialog-content\"\n        className={cn(\n          \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <DialogPrimitive.Close\n            data-slot=\"dialog-close\"\n            className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n          >\n            <XIcon />\n            <span className=\"sr-only\">Close</span>\n          </DialogPrimitive.Close>\n        )}\n      </DialogPrimitive.Content>\n    </DialogPortal>\n  )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"text-lg leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-node",
      "type": "registry:block",
      "title": "Ai Elements Node",
      "description": "node",
      "dependencies": [
        "@xyflow/react@12.10.0",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/node.tsx",
          "target": "@components/ai-elements/node.tsx",
          "type": "registry:component",
          "content": "import {\n  Card,\n  CardAction,\n  CardContent,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ai-elements/_ui/card\"\nimport { cn } from \"@/lib/utils\"\nimport { Handle, Position } from \"@xyflow/react\"\nimport type { ComponentProps } from \"react\"\n\nexport type NodeProps = ComponentProps<typeof Card> & {\n  handles: {\n    target: boolean\n    source: boolean\n  }\n}\n\nexport const Node = ({ handles, className, ...props }: NodeProps) => (\n  <Card\n    className={cn(\n      \"node-container relative size-full h-auto w-sm gap-0 rounded-md p-0\",\n      className\n    )}\n    {...props}\n  >\n    {handles.target && <Handle position={Position.Left} type=\"target\" />}\n    {handles.source && <Handle position={Position.Right} type=\"source\" />}\n    {props.children}\n  </Card>\n)\n\nexport type NodeHeaderProps = ComponentProps<typeof CardHeader>\n\nexport const NodeHeader = ({ className, ...props }: NodeHeaderProps) => (\n  <CardHeader\n    className={cn(\"bg-secondary gap-0.5 rounded-t-md border-b p-3!\", className)}\n    {...props}\n  />\n)\n\nexport type NodeTitleProps = ComponentProps<typeof CardTitle>\n\nexport const NodeTitle = (props: NodeTitleProps) => <CardTitle {...props} />\n\nexport type NodeDescriptionProps = ComponentProps<typeof CardDescription>\n\nexport const NodeDescription = (props: NodeDescriptionProps) => (\n  <CardDescription {...props} />\n)\n\nexport type NodeActionProps = ComponentProps<typeof CardAction>\n\nexport const NodeAction = (props: NodeActionProps) => <CardAction {...props} />\n\nexport type NodeContentProps = ComponentProps<typeof CardContent>\n\nexport const NodeContent = ({ className, ...props }: NodeContentProps) => (\n  <CardContent className={cn(\"p-3\", className)} {...props} />\n)\n\nexport type NodeFooterProps = ComponentProps<typeof CardFooter>\n\nexport const NodeFooter = ({ className, ...props }: NodeFooterProps) => (\n  <CardFooter\n    className={cn(\"bg-secondary rounded-b-md border-t p-3!\", className)}\n    {...props}\n  />\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/card.tsx",
          "target": "@components/ai-elements/_ui/card.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card\"\n      className={cn(\n        \"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-header\"\n      className={cn(\n        \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-title\"\n      className={cn(\"leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-action\"\n      className={cn(\n        \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-content\"\n      className={cn(\"px-6\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-footer\"\n      className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Card,\n  CardHeader,\n  CardFooter,\n  CardTitle,\n  CardAction,\n  CardDescription,\n  CardContent,\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-open-in-chat",
      "type": "registry:block",
      "title": "Ai Elements Open In Chat",
      "description": "open in chat",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/open-in-chat.tsx",
          "target": "@components/ai-elements/open-in-chat.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/components/ai-elements/_ui/dropdown-menu\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  ChevronDownIcon,\n  ExternalLinkIcon,\n  MessageCircleIcon,\n} from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport { createContext, useContext, useMemo } from \"react\"\n\nconst providers = {\n  chatgpt: {\n    createUrl: (prompt: string) =>\n      `https://chatgpt.com/?${new URLSearchParams({\n        hints: \"search\",\n        prompt,\n      })}`,\n    icon: (\n      <svg\n        fill=\"currentColor\"\n        role=\"img\"\n        viewBox=\"0 0 24 24\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <title>OpenAI</title>\n        <path d=\"M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z\" />\n      </svg>\n    ),\n    title: \"Open in ChatGPT\",\n  },\n  claude: {\n    createUrl: (q: string) =>\n      `https://claude.ai/new?${new URLSearchParams({\n        q,\n      })}`,\n    icon: (\n      <svg\n        fill=\"currentColor\"\n        role=\"img\"\n        viewBox=\"0 0 12 12\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <title>Claude</title>\n        <path\n          clipRule=\"evenodd\"\n          d=\"M2.3545 7.9775L4.7145 6.654L4.7545 6.539L4.7145 6.475H4.6L4.205 6.451L2.856 6.4145L1.6865 6.366L0.5535 6.305L0.268 6.2445L0 5.892L0.0275 5.716L0.2675 5.5555L0.6105 5.5855L1.3705 5.637L2.5095 5.716L3.3355 5.7645L4.56 5.892H4.7545L4.782 5.8135L4.715 5.7645L4.6635 5.716L3.4845 4.918L2.2085 4.074L1.5405 3.588L1.1785 3.3425L0.9965 3.1115L0.9175 2.6075L1.2455 2.2465L1.686 2.2765L1.7985 2.307L2.245 2.65L3.199 3.388L4.4445 4.3045L4.627 4.4565L4.6995 4.405L4.709 4.3685L4.627 4.2315L3.9495 3.0085L3.2265 1.7635L2.9045 1.2475L2.8195 0.938C2.78711 0.819128 2.76965 0.696687 2.7675 0.5735L3.1415 0.067L3.348 0L3.846 0.067L4.056 0.249L4.366 0.956L4.867 2.0705L5.6445 3.5855L5.8725 4.0345L5.994 4.4505L6.0395 4.578H6.1185V4.505L6.1825 3.652L6.301 2.6045L6.416 1.257L6.456 0.877L6.644 0.422L7.0175 0.176L7.3095 0.316L7.5495 0.6585L7.516 0.8805L7.373 1.806L7.0935 3.2575L6.9115 4.2285H7.0175L7.139 4.1075L7.6315 3.4545L8.4575 2.4225L8.8225 2.0125L9.2475 1.5605L9.521 1.345H10.0375L10.4175 1.9095L10.2475 2.4925L9.7155 3.166L9.275 3.737L8.643 4.587L8.248 5.267L8.2845 5.322L8.3785 5.312L9.8065 5.009L10.578 4.869L11.4985 4.7115L11.915 4.9055L11.9605 5.103L11.7965 5.5065L10.812 5.7495L9.6575 5.9805L7.938 6.387L7.917 6.402L7.9415 6.4325L8.716 6.5055L9.047 6.5235H9.858L11.368 6.636L11.763 6.897L12 7.216L11.9605 7.4585L11.353 7.7685L10.533 7.574L8.6185 7.119L7.9625 6.9545H7.8715V7.0095L8.418 7.5435L9.421 8.4485L10.6755 9.6135L10.739 9.9025L10.578 10.13L10.408 10.1055L9.3055 9.277L8.88 8.9035L7.917 8.0935H7.853V8.1785L8.075 8.503L9.2475 10.2635L9.3085 10.8035L9.2235 10.98L8.9195 11.0865L8.5855 11.0255L7.8985 10.063L7.191 8.9795L6.6195 8.008L6.5495 8.048L6.2125 11.675L6.0545 11.86L5.69 12L5.3865 11.7695L5.2255 11.396L5.3865 10.658L5.581 9.696L5.7385 8.931L5.8815 7.981L5.9665 7.665L5.9605 7.644L5.8905 7.653L5.1735 8.6365L4.0835 10.109L3.2205 11.0315L3.0135 11.1135L2.655 10.9285L2.6885 10.5975L2.889 10.303L4.083 8.785L4.803 7.844L5.268 7.301L5.265 7.222H5.2375L2.066 9.28L1.501 9.353L1.2575 9.125L1.288 8.752L1.4035 8.6305L2.3575 7.9745L2.3545 7.9775Z\"\n          fillRule=\"evenodd\"\n        />\n      </svg>\n    ),\n    title: \"Open in Claude\",\n  },\n  cursor: {\n    createUrl: (text: string) => {\n      const url = new URL(\"https://cursor.com/link/prompt\")\n      url.searchParams.set(\"text\", text)\n      return url.toString()\n    },\n    icon: (\n      <svg\n        version=\"1.1\"\n        viewBox=\"0 0 466.73 532.09\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <title>Cursor</title>\n        <path\n          d=\"M457.43,125.94L244.42,2.96c-6.84-3.95-15.28-3.95-22.12,0L9.3,125.94c-5.75,3.32-9.3,9.46-9.3,16.11v247.99c0,6.65,3.55,12.79,9.3,16.11l213.01,122.98c6.84,3.95,15.28,3.95,22.12,0l213.01-122.98c5.75-3.32,9.3-9.46,9.3-16.11v-247.99c0-6.65-3.55-12.79-9.3-16.11h-.01ZM444.05,151.99l-205.63,356.16c-1.39,2.4-5.06,1.42-5.06-1.36v-233.21c0-4.66-2.49-8.97-6.53-11.31L24.87,145.67c-2.4-1.39-1.42-5.06,1.36-5.06h411.26c5.84,0,9.49,6.33,6.57,11.39h-.01Z\"\n          fill=\"currentColor\"\n        />\n      </svg>\n    ),\n    title: \"Open in Cursor\",\n  },\n  github: {\n    createUrl: (url: string) => url,\n    icon: (\n      <svg fill=\"currentColor\" role=\"img\" viewBox=\"0 0 24 24\">\n        <title>GitHub</title>\n        <path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\" />\n      </svg>\n    ),\n    title: \"Open in GitHub\",\n  },\n  scira: {\n    createUrl: (q: string) =>\n      `https://scira.ai/?${new URLSearchParams({\n        q,\n      })}`,\n    icon: (\n      <svg\n        fill=\"none\"\n        height=\"934\"\n        viewBox=\"0 0 910 934\"\n        width=\"910\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <title>Scira AI</title>\n        <path\n          d=\"M647.664 197.775C569.13 189.049 525.5 145.419 516.774 66.8849C508.048 145.419 464.418 189.049 385.884 197.775C464.418 206.501 508.048 250.131 516.774 328.665C525.5 250.131 569.13 206.501 647.664 197.775Z\"\n          fill=\"currentColor\"\n          stroke=\"currentColor\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"8\"\n        />\n        <path\n          d=\"M516.774 304.217C510.299 275.491 498.208 252.087 480.335 234.214C462.462 216.341 439.058 204.251 410.333 197.775C439.059 191.3 462.462 179.209 480.335 161.336C498.208 143.463 510.299 120.06 516.774 91.334C523.25 120.059 535.34 143.463 553.213 161.336C571.086 179.209 594.49 191.3 623.216 197.775C594.49 204.251 571.086 216.341 553.213 234.214C535.34 252.087 523.25 275.491 516.774 304.217Z\"\n          fill=\"currentColor\"\n          stroke=\"currentColor\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"8\"\n        />\n        <path\n          d=\"M857.5 508.116C763.259 497.644 710.903 445.288 700.432 351.047C689.961 445.288 637.605 497.644 543.364 508.116C637.605 518.587 689.961 570.943 700.432 665.184C710.903 570.943 763.259 518.587 857.5 508.116Z\"\n          stroke=\"currentColor\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"20\"\n        />\n        <path\n          d=\"M700.432 615.957C691.848 589.05 678.575 566.357 660.383 548.165C642.191 529.973 619.499 516.7 592.593 508.116C619.499 499.533 642.191 486.258 660.383 468.066C678.575 449.874 691.848 427.181 700.432 400.274C709.015 427.181 722.289 449.874 740.481 468.066C758.673 486.258 781.365 499.533 808.271 508.116C781.365 516.7 758.673 529.973 740.481 548.165C722.289 566.357 709.015 589.05 700.432 615.957Z\"\n          stroke=\"currentColor\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"20\"\n        />\n        <path\n          d=\"M889.949 121.237C831.049 114.692 798.326 81.9698 791.782 23.0692C785.237 81.9698 752.515 114.692 693.614 121.237C752.515 127.781 785.237 160.504 791.782 219.404C798.326 160.504 831.049 127.781 889.949 121.237Z\"\n          fill=\"currentColor\"\n          stroke=\"currentColor\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"8\"\n        />\n        <path\n          d=\"M791.782 196.795C786.697 176.937 777.869 160.567 765.16 147.858C752.452 135.15 736.082 126.322 716.226 121.237C736.082 116.152 752.452 107.324 765.16 94.6152C777.869 81.9065 786.697 65.5368 791.782 45.6797C796.867 65.5367 805.695 81.9066 818.403 94.6152C831.112 107.324 847.481 116.152 867.338 121.237C847.481 126.322 831.112 135.15 818.403 147.858C805.694 160.567 796.867 176.937 791.782 196.795Z\"\n          fill=\"currentColor\"\n          stroke=\"currentColor\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"8\"\n        />\n        <path\n          d=\"M760.632 764.337C720.719 814.616 669.835 855.1 611.872 882.692C553.91 910.285 490.404 924.255 426.213 923.533C362.022 922.812 298.846 907.419 241.518 878.531C184.19 849.643 134.228 808.026 95.4548 756.863C56.6815 705.7 30.1238 646.346 17.8129 583.343C5.50207 520.339 7.76433 455.354 24.4266 393.359C41.089 331.364 71.7099 274.001 113.947 225.658C156.184 177.315 208.919 139.273 268.117 114.442\"\n          stroke=\"currentColor\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          strokeWidth=\"30\"\n        />\n      </svg>\n    ),\n    title: \"Open in Scira\",\n  },\n  t3: {\n    createUrl: (q: string) =>\n      `https://t3.chat/new?${new URLSearchParams({\n        q,\n      })}`,\n    icon: <MessageCircleIcon />,\n    title: \"Open in T3 Chat\",\n  },\n  v0: {\n    createUrl: (q: string) =>\n      `https://v0.app?${new URLSearchParams({\n        q,\n      })}`,\n    icon: (\n      <svg\n        fill=\"currentColor\"\n        viewBox=\"0 0 147 70\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <title>v0</title>\n        <path d=\"M56 50.2031V14H70V60.1562C70 65.5928 65.5928 70 60.1562 70C57.5605 70 54.9982 68.9992 53.1562 67.1573L0 14H19.7969L56 50.2031Z\" />\n        <path d=\"M147 56H133V23.9531L100.953 56H133V70H96.6875C85.8144 70 77 61.1856 77 50.3125V14H91V46.1562L123.156 14H91V0H127.312C138.186 0 147 8.81439 147 19.6875V56Z\" />\n      </svg>\n    ),\n    title: \"Open in v0\",\n  },\n}\n\nconst OpenInContext = createContext<{ query: string } | undefined>(undefined)\n\nconst useOpenInContext = () => {\n  const context = useContext(OpenInContext)\n  if (!context) {\n    throw new Error(\"OpenIn components must be used within an OpenIn provider\")\n  }\n  return context\n}\n\nexport type OpenInProps = ComponentProps<typeof DropdownMenu> & {\n  query: string\n}\n\nexport const OpenIn = ({ query, ...props }: OpenInProps) => {\n  const contextValue = useMemo(() => ({ query }), [query])\n\n  return (\n    <OpenInContext.Provider value={contextValue}>\n      <DropdownMenu {...props} />\n    </OpenInContext.Provider>\n  )\n}\n\nexport type OpenInContentProps = ComponentProps<typeof DropdownMenuContent>\n\nexport const OpenInContent = ({ className, ...props }: OpenInContentProps) => (\n  <DropdownMenuContent\n    align=\"start\"\n    className={cn(\"w-[240px]\", className)}\n    {...props}\n  />\n)\n\nexport type OpenInItemProps = ComponentProps<typeof DropdownMenuItem>\n\nexport const OpenInItem = (props: OpenInItemProps) => (\n  <DropdownMenuItem {...props} />\n)\n\nexport type OpenInLabelProps = ComponentProps<typeof DropdownMenuLabel>\n\nexport const OpenInLabel = (props: OpenInLabelProps) => (\n  <DropdownMenuLabel {...props} />\n)\n\nexport type OpenInSeparatorProps = ComponentProps<typeof DropdownMenuSeparator>\n\nexport const OpenInSeparator = (props: OpenInSeparatorProps) => (\n  <DropdownMenuSeparator {...props} />\n)\n\nexport type OpenInTriggerProps = ComponentProps<typeof DropdownMenuTrigger>\n\nexport const OpenInTrigger = ({ children, ...props }: OpenInTriggerProps) => (\n  <DropdownMenuTrigger {...props} asChild>\n    {children ?? (\n      <Button type=\"button\" variant=\"outline\">\n        Open in chat\n        <ChevronDownIcon className=\"size-4\" />\n      </Button>\n    )}\n  </DropdownMenuTrigger>\n)\n\nexport type OpenInChatGPTProps = ComponentProps<typeof DropdownMenuItem>\n\nexport const OpenInChatGPT = (props: OpenInChatGPTProps) => {\n  const { query } = useOpenInContext()\n  return (\n    <DropdownMenuItem asChild {...props}>\n      <a\n        className=\"flex items-center gap-2\"\n        href={providers.chatgpt.createUrl(query)}\n        rel=\"noopener\"\n        target=\"_blank\"\n      >\n        <span className=\"shrink-0\">{providers.chatgpt.icon}</span>\n        <span className=\"flex-1\">{providers.chatgpt.title}</span>\n        <ExternalLinkIcon className=\"size-4 shrink-0\" />\n      </a>\n    </DropdownMenuItem>\n  )\n}\n\nexport type OpenInClaudeProps = ComponentProps<typeof DropdownMenuItem>\n\nexport const OpenInClaude = (props: OpenInClaudeProps) => {\n  const { query } = useOpenInContext()\n  return (\n    <DropdownMenuItem asChild {...props}>\n      <a\n        className=\"flex items-center gap-2\"\n        href={providers.claude.createUrl(query)}\n        rel=\"noopener\"\n        target=\"_blank\"\n      >\n        <span className=\"shrink-0\">{providers.claude.icon}</span>\n        <span className=\"flex-1\">{providers.claude.title}</span>\n        <ExternalLinkIcon className=\"size-4 shrink-0\" />\n      </a>\n    </DropdownMenuItem>\n  )\n}\n\nexport type OpenInT3Props = ComponentProps<typeof DropdownMenuItem>\n\nexport const OpenInT3 = (props: OpenInT3Props) => {\n  const { query } = useOpenInContext()\n  return (\n    <DropdownMenuItem asChild {...props}>\n      <a\n        className=\"flex items-center gap-2\"\n        href={providers.t3.createUrl(query)}\n        rel=\"noopener\"\n        target=\"_blank\"\n      >\n        <span className=\"shrink-0\">{providers.t3.icon}</span>\n        <span className=\"flex-1\">{providers.t3.title}</span>\n        <ExternalLinkIcon className=\"size-4 shrink-0\" />\n      </a>\n    </DropdownMenuItem>\n  )\n}\n\nexport type OpenInSciraProps = ComponentProps<typeof DropdownMenuItem>\n\nexport const OpenInScira = (props: OpenInSciraProps) => {\n  const { query } = useOpenInContext()\n  return (\n    <DropdownMenuItem asChild {...props}>\n      <a\n        className=\"flex items-center gap-2\"\n        href={providers.scira.createUrl(query)}\n        rel=\"noopener\"\n        target=\"_blank\"\n      >\n        <span className=\"shrink-0\">{providers.scira.icon}</span>\n        <span className=\"flex-1\">{providers.scira.title}</span>\n        <ExternalLinkIcon className=\"size-4 shrink-0\" />\n      </a>\n    </DropdownMenuItem>\n  )\n}\n\nexport type OpenInv0Props = ComponentProps<typeof DropdownMenuItem>\n\nexport const OpenInv0 = (props: OpenInv0Props) => {\n  const { query } = useOpenInContext()\n  return (\n    <DropdownMenuItem asChild {...props}>\n      <a\n        className=\"flex items-center gap-2\"\n        href={providers.v0.createUrl(query)}\n        rel=\"noopener\"\n        target=\"_blank\"\n      >\n        <span className=\"shrink-0\">{providers.v0.icon}</span>\n        <span className=\"flex-1\">{providers.v0.title}</span>\n        <ExternalLinkIcon className=\"size-4 shrink-0\" />\n      </a>\n    </DropdownMenuItem>\n  )\n}\n\nexport type OpenInCursorProps = ComponentProps<typeof DropdownMenuItem>\n\nexport const OpenInCursor = (props: OpenInCursorProps) => {\n  const { query } = useOpenInContext()\n  return (\n    <DropdownMenuItem asChild {...props}>\n      <a\n        className=\"flex items-center gap-2\"\n        href={providers.cursor.createUrl(query)}\n        rel=\"noopener\"\n        target=\"_blank\"\n      >\n        <span className=\"shrink-0\">{providers.cursor.icon}</span>\n        <span className=\"flex-1\">{providers.cursor.title}</span>\n        <ExternalLinkIcon className=\"size-4 shrink-0\" />\n      </a>\n    </DropdownMenuItem>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/dropdown-menu.tsx",
          "target": "@components/ai-elements/_ui/dropdown-menu.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction DropdownMenu({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  return (\n    <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n  )\n}\n\nfunction DropdownMenuTrigger({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return (\n    <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return (\n    <DropdownMenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CircleIcon className=\"size-2 fill-current\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPrimitive.SubContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-package-info",
      "type": "registry:block",
      "title": "Ai Elements Package Info",
      "description": "package info",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/package-info.tsx",
          "target": "@components/ai-elements/package-info.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport { cn } from \"@/lib/utils\"\nimport { ArrowRightIcon, MinusIcon, PackageIcon, PlusIcon } from \"lucide-react\"\nimport type { HTMLAttributes } from \"react\"\nimport { createContext, useContext, useMemo } from \"react\"\n\ntype ChangeType = \"major\" | \"minor\" | \"patch\" | \"added\" | \"removed\"\n\ninterface PackageInfoContextType {\n  name: string\n  currentVersion?: string\n  newVersion?: string\n  changeType?: ChangeType\n}\n\nconst PackageInfoContext = createContext<PackageInfoContextType>({\n  name: \"\",\n})\n\nexport type PackageInfoHeaderProps = HTMLAttributes<HTMLDivElement>\n\nexport const PackageInfoHeader = ({\n  className,\n  children,\n  ...props\n}: PackageInfoHeaderProps) => (\n  <div\n    className={cn(\"flex items-center justify-between gap-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type PackageInfoNameProps = HTMLAttributes<HTMLDivElement>\n\nexport const PackageInfoName = ({\n  className,\n  children,\n  ...props\n}: PackageInfoNameProps) => {\n  const { name } = useContext(PackageInfoContext)\n\n  return (\n    <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n      <PackageIcon className=\"text-muted-foreground size-4\" />\n      <span className=\"font-mono text-sm font-medium\">{children ?? name}</span>\n    </div>\n  )\n}\n\nconst changeTypeStyles: Record<ChangeType, string> = {\n  added: \"bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400\",\n  major: \"bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400\",\n  minor:\n    \"bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400\",\n  patch: \"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\",\n  removed: \"bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400\",\n}\n\nconst changeTypeIcons: Record<ChangeType, React.ReactNode> = {\n  added: <PlusIcon className=\"size-3\" />,\n  major: <ArrowRightIcon className=\"size-3\" />,\n  minor: <ArrowRightIcon className=\"size-3\" />,\n  patch: <ArrowRightIcon className=\"size-3\" />,\n  removed: <MinusIcon className=\"size-3\" />,\n}\n\nexport type PackageInfoChangeTypeProps = HTMLAttributes<HTMLDivElement>\n\nexport const PackageInfoChangeType = ({\n  className,\n  children,\n  ...props\n}: PackageInfoChangeTypeProps) => {\n  const { changeType } = useContext(PackageInfoContext)\n\n  if (!changeType) {\n    return null\n  }\n\n  return (\n    <Badge\n      className={cn(\n        \"gap-1 text-xs capitalize\",\n        changeTypeStyles[changeType],\n        className\n      )}\n      variant=\"secondary\"\n      {...props}\n    >\n      {changeTypeIcons[changeType]}\n      {children ?? changeType}\n    </Badge>\n  )\n}\n\nexport type PackageInfoVersionProps = HTMLAttributes<HTMLDivElement>\n\nexport const PackageInfoVersion = ({\n  className,\n  children,\n  ...props\n}: PackageInfoVersionProps) => {\n  const { currentVersion, newVersion } = useContext(PackageInfoContext)\n\n  if (!(currentVersion || newVersion)) {\n    return null\n  }\n\n  return (\n    <div\n      className={cn(\n        \"text-muted-foreground mt-2 flex items-center gap-2 font-mono text-sm\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? (\n        <>\n          {currentVersion && <span>{currentVersion}</span>}\n          {currentVersion && newVersion && (\n            <ArrowRightIcon className=\"size-3\" />\n          )}\n          {newVersion && (\n            <span className=\"text-foreground font-medium\">{newVersion}</span>\n          )}\n        </>\n      )}\n    </div>\n  )\n}\n\nexport type PackageInfoProps = HTMLAttributes<HTMLDivElement> & {\n  name: string\n  currentVersion?: string\n  newVersion?: string\n  changeType?: ChangeType\n}\n\nexport const PackageInfo = ({\n  name,\n  currentVersion,\n  newVersion,\n  changeType,\n  className,\n  children,\n  ...props\n}: PackageInfoProps) => {\n  const contextValue = useMemo(\n    () => ({ changeType, currentVersion, name, newVersion }),\n    [changeType, currentVersion, name, newVersion]\n  )\n\n  return (\n    <PackageInfoContext.Provider value={contextValue}>\n      <div\n        className={cn(\"bg-background rounded-lg border p-4\", className)}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <PackageInfoHeader>\n              <PackageInfoName />\n              {changeType && <PackageInfoChangeType />}\n            </PackageInfoHeader>\n            {(currentVersion || newVersion) && <PackageInfoVersion />}\n          </>\n        )}\n      </div>\n    </PackageInfoContext.Provider>\n  )\n}\n\nexport type PackageInfoDescriptionProps = HTMLAttributes<HTMLParagraphElement>\n\nexport const PackageInfoDescription = ({\n  className,\n  children,\n  ...props\n}: PackageInfoDescriptionProps) => (\n  <p className={cn(\"text-muted-foreground mt-2 text-sm\", className)} {...props}>\n    {children}\n  </p>\n)\n\nexport type PackageInfoContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const PackageInfoContent = ({\n  className,\n  children,\n  ...props\n}: PackageInfoContentProps) => (\n  <div className={cn(\"mt-3 border-t pt-3\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type PackageInfoDependenciesProps = HTMLAttributes<HTMLDivElement>\n\nexport const PackageInfoDependencies = ({\n  className,\n  children,\n  ...props\n}: PackageInfoDependenciesProps) => (\n  <div className={cn(\"space-y-2\", className)} {...props}>\n    <span className=\"text-muted-foreground text-xs font-medium tracking-wide uppercase\">\n      Dependencies\n    </span>\n    <div className=\"space-y-1\">{children}</div>\n  </div>\n)\n\nexport type PackageInfoDependencyProps = HTMLAttributes<HTMLDivElement> & {\n  name: string\n  version?: string\n}\n\nexport const PackageInfoDependency = ({\n  name,\n  version,\n  className,\n  children,\n  ...props\n}: PackageInfoDependencyProps) => (\n  <div\n    className={cn(\"flex items-center justify-between text-sm\", className)}\n    {...props}\n  >\n    {children ?? (\n      <>\n        <span className=\"text-muted-foreground font-mono\">{name}</span>\n        {version && <span className=\"font-mono text-xs\">{version}</span>}\n      </>\n    )}\n  </div>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-panel",
      "type": "registry:block",
      "title": "Ai Elements Panel",
      "description": "panel",
      "dependencies": [
        "@xyflow/react@12.10.0",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/panel.tsx",
          "target": "@components/ai-elements/panel.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Panel as PanelPrimitive } from \"@xyflow/react\"\nimport type { ComponentProps } from \"react\"\n\ntype PanelProps = ComponentProps<typeof PanelPrimitive>\n\nexport const Panel = ({ className, ...props }: PanelProps) => (\n  <PanelPrimitive\n    className={cn(\n      \"bg-card m-4 overflow-hidden rounded-md border p-1\",\n      className\n    )}\n    {...props}\n  />\n)\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-persona",
      "type": "registry:block",
      "title": "Ai Elements Persona",
      "description": "persona",
      "dependencies": [
        "@rive-app/react-webgl2@4.26.1",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/persona.tsx",
          "target": "@components/ai-elements/persona.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport type { RiveParameters } from \"@rive-app/react-webgl2\"\nimport {\n  useRive,\n  useStateMachineInput,\n  useViewModel,\n  useViewModelInstance,\n  useViewModelInstanceColor,\n} from \"@rive-app/react-webgl2\"\nimport type { FC, ReactNode } from \"react\"\nimport { memo, useEffect, useMemo, useRef, useState } from \"react\"\n\n// Delays Rive initialization by one frame so that React Strict Mode's\n// immediate unmount cycle never creates a WebGL2 context. Only the\n// second (real) mount will initialise, avoiding context exhaustion.\nconst useStrictModeSafeInit = () => {\n  const [ready, setReady] = useState(false)\n\n  useEffect(() => {\n    const id = requestAnimationFrame(() => setReady(true))\n    return () => {\n      cancelAnimationFrame(id)\n      setReady(false)\n    }\n  }, [])\n\n  return ready\n}\n\nexport type PersonaState =\n  | \"idle\"\n  | \"listening\"\n  | \"thinking\"\n  | \"speaking\"\n  | \"asleep\"\n\ninterface PersonaProps {\n  state: PersonaState\n  onLoad?: RiveParameters[\"onLoad\"]\n  onLoadError?: RiveParameters[\"onLoadError\"]\n  onReady?: () => void\n  onPause?: RiveParameters[\"onPause\"]\n  onPlay?: RiveParameters[\"onPlay\"]\n  onStop?: RiveParameters[\"onStop\"]\n  className?: string\n  variant?: keyof typeof sources\n}\n\n// The state machine name is always 'default' for Elements AI visuals\nconst stateMachine = \"default\"\n\nconst sources = {\n  command: {\n    dynamicColor: true,\n    hasModel: true,\n    source:\n      \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/command-2.0.riv\",\n  },\n  glint: {\n    dynamicColor: true,\n    hasModel: true,\n    source:\n      \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/glint-2.0.riv\",\n  },\n  halo: {\n    dynamicColor: true,\n    hasModel: true,\n    source:\n      \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/halo-2.0.riv\",\n  },\n  mana: {\n    dynamicColor: false,\n    hasModel: true,\n    source:\n      \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/mana-2.0.riv\",\n  },\n  obsidian: {\n    dynamicColor: true,\n    hasModel: true,\n    source:\n      \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/obsidian-2.0.riv\",\n  },\n  opal: {\n    dynamicColor: false,\n    hasModel: false,\n    source:\n      \"https://ejiidnob33g9ap1r.public.blob.vercel-storage.com/orb-1.2.riv\",\n  },\n}\n\nconst getCurrentTheme = (): \"light\" | \"dark\" => {\n  if (typeof window !== \"undefined\") {\n    if (document.documentElement.classList.contains(\"dark\")) {\n      return \"dark\"\n    }\n    if (window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches) {\n      return \"dark\"\n    }\n  }\n  return \"light\"\n}\n\nconst useTheme = (enabled: boolean) => {\n  const [theme, setTheme] = useState<\"light\" | \"dark\">(getCurrentTheme)\n\n  useEffect(() => {\n    // Skip if not enabled (avoids unnecessary observers for non-dynamic-color variants)\n    if (!enabled) {\n      return\n    }\n\n    // Watch for classList changes\n    const observer = new MutationObserver(() => {\n      setTheme(getCurrentTheme())\n    })\n\n    observer.observe(document.documentElement, {\n      attributeFilter: [\"class\"],\n      attributes: true,\n    })\n\n    // Watch for OS-level theme changes\n    let mql: MediaQueryList | null = null\n    const handleMediaChange = () => {\n      setTheme(getCurrentTheme())\n    }\n\n    if (window.matchMedia) {\n      mql = window.matchMedia(\"(prefers-color-scheme: dark)\")\n      mql.addEventListener(\"change\", handleMediaChange)\n    }\n\n    return () => {\n      observer.disconnect()\n      if (mql) {\n        mql.removeEventListener(\"change\", handleMediaChange)\n      }\n    }\n  }, [enabled])\n\n  return theme\n}\n\ninterface PersonaWithModelProps {\n  rive: ReturnType<typeof useRive>[\"rive\"]\n  source: (typeof sources)[keyof typeof sources]\n  children: React.ReactNode\n}\n\nconst PersonaWithModel = memo(\n  ({ rive, source, children }: PersonaWithModelProps) => {\n    const theme = useTheme(source.dynamicColor)\n    const viewModel = useViewModel(rive, { useDefault: true })\n    const viewModelInstance = useViewModelInstance(viewModel, {\n      rive,\n      useDefault: true,\n    })\n    const viewModelInstanceColor = useViewModelInstanceColor(\n      \"color\",\n      viewModelInstance\n    )\n\n    useEffect(() => {\n      if (!(viewModelInstanceColor && source.dynamicColor)) {\n        return\n      }\n\n      const [r, g, b] = theme === \"dark\" ? [255, 255, 255] : [0, 0, 0]\n      viewModelInstanceColor.setRgb(r, g, b)\n    }, [viewModelInstanceColor, theme, source.dynamicColor])\n\n    return children\n  }\n)\n\nPersonaWithModel.displayName = \"PersonaWithModel\"\n\ninterface PersonaWithoutModelProps {\n  children: ReactNode\n}\n\nconst PersonaWithoutModel = memo(\n  ({ children }: PersonaWithoutModelProps) => children\n)\n\nPersonaWithoutModel.displayName = \"PersonaWithoutModel\"\n\nexport const Persona: FC<PersonaProps> = memo(\n  ({\n    variant = \"obsidian\",\n    state = \"idle\",\n    onLoad,\n    onLoadError,\n    onReady,\n    onPause,\n    onPlay,\n    onStop,\n    className,\n  }) => {\n    const source = sources[variant]\n\n    if (!source) {\n      throw new Error(`Invalid variant: ${variant}`)\n    }\n\n    // Stabilize callbacks to prevent useRive from reinitializing\n    const callbacksRef = useRef({\n      onLoad,\n      onLoadError,\n      onPause,\n      onPlay,\n      onReady,\n      onStop,\n    })\n\n    useEffect(() => {\n      callbacksRef.current = {\n        onLoad,\n        onLoadError,\n        onPause,\n        onPlay,\n        onReady,\n        onStop,\n      }\n    }, [onLoad, onLoadError, onPause, onPlay, onReady, onStop])\n\n    const stableCallbacks = useMemo(\n      () => ({\n        onLoad: ((loadedRive) =>\n          callbacksRef.current.onLoad?.(\n            loadedRive\n          )) as RiveParameters[\"onLoad\"],\n        onLoadError: ((err) =>\n          callbacksRef.current.onLoadError?.(\n            err\n          )) as RiveParameters[\"onLoadError\"],\n        onPause: ((event) =>\n          callbacksRef.current.onPause?.(event)) as RiveParameters[\"onPause\"],\n        onPlay: ((event) =>\n          callbacksRef.current.onPlay?.(event)) as RiveParameters[\"onPlay\"],\n        onReady: () => callbacksRef.current.onReady?.(),\n        onStop: ((event) =>\n          callbacksRef.current.onStop?.(event)) as RiveParameters[\"onStop\"],\n      }),\n      []\n    )\n\n    // Delay initialisation by one frame to avoid creating (and leaking)\n    // a WebGL2 context during React Strict Mode's first throw-away mount.\n    const ready = useStrictModeSafeInit()\n\n    const { rive, RiveComponent } = useRive(\n      ready\n        ? {\n            autoplay: true,\n            onLoad: stableCallbacks.onLoad,\n            onLoadError: stableCallbacks.onLoadError,\n            onPause: stableCallbacks.onPause,\n            onPlay: stableCallbacks.onPlay,\n            onRiveReady: stableCallbacks.onReady,\n            onStop: stableCallbacks.onStop,\n            src: source.source,\n            stateMachines: stateMachine,\n          }\n        : null\n    )\n\n    const listeningInput = useStateMachineInput(rive, stateMachine, \"listening\")\n    const thinkingInput = useStateMachineInput(rive, stateMachine, \"thinking\")\n    const speakingInput = useStateMachineInput(rive, stateMachine, \"speaking\")\n    const asleepInput = useStateMachineInput(rive, stateMachine, \"asleep\")\n\n    // Rive state machine inputs are mutable objects that must be set via direct\n    // property assignment — this is the intended Rive API, not a React anti-pattern.\n    useEffect(() => {\n      if (listeningInput) {\n        listeningInput.value = state === \"listening\"\n      }\n      if (thinkingInput) {\n        thinkingInput.value = state === \"thinking\"\n      }\n      if (speakingInput) {\n        speakingInput.value = state === \"speaking\"\n      }\n      if (asleepInput) {\n        asleepInput.value = state === \"asleep\"\n      }\n    }, [state, listeningInput, thinkingInput, speakingInput, asleepInput])\n\n    const Component = source.hasModel ? PersonaWithModel : PersonaWithoutModel\n\n    return (\n      <Component rive={rive} source={source}>\n        <RiveComponent className={cn(\"size-16 shrink-0\", className)} />\n      </Component>\n    )\n  }\n)\n\nPersona.displayName = \"Persona\"\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-plan",
      "type": "registry:block",
      "title": "Ai Elements Plan",
      "description": "plan",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/plan.tsx",
          "target": "@components/ai-elements/plan.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Card,\n  CardAction,\n  CardContent,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ai-elements/_ui/card\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronsUpDownIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport { createContext, useContext, useMemo } from \"react\"\nimport { Shimmer } from \"./shimmer\"\n\ninterface PlanContextValue {\n  isStreaming: boolean\n}\n\nconst PlanContext = createContext<PlanContextValue | null>(null)\n\nconst usePlan = () => {\n  const context = useContext(PlanContext)\n  if (!context) {\n    throw new Error(\"Plan components must be used within Plan\")\n  }\n  return context\n}\n\nexport type PlanProps = ComponentProps<typeof Collapsible> & {\n  isStreaming?: boolean\n}\n\nexport const Plan = ({\n  className,\n  isStreaming = false,\n  children,\n  ...props\n}: PlanProps) => {\n  const contextValue = useMemo(() => ({ isStreaming }), [isStreaming])\n\n  return (\n    <PlanContext.Provider value={contextValue}>\n      <Collapsible asChild data-slot=\"plan\" {...props}>\n        <Card className={cn(\"shadow-none\", className)}>{children}</Card>\n      </Collapsible>\n    </PlanContext.Provider>\n  )\n}\n\nexport type PlanHeaderProps = ComponentProps<typeof CardHeader>\n\nexport const PlanHeader = ({ className, ...props }: PlanHeaderProps) => (\n  <CardHeader\n    className={cn(\"flex items-start justify-between\", className)}\n    data-slot=\"plan-header\"\n    {...props}\n  />\n)\n\nexport type PlanTitleProps = Omit<\n  ComponentProps<typeof CardTitle>,\n  \"children\"\n> & {\n  children: string\n}\n\nexport const PlanTitle = ({ children, ...props }: PlanTitleProps) => {\n  const { isStreaming } = usePlan()\n\n  return (\n    <CardTitle data-slot=\"plan-title\" {...props}>\n      {isStreaming ? <Shimmer>{children}</Shimmer> : children}\n    </CardTitle>\n  )\n}\n\nexport type PlanDescriptionProps = Omit<\n  ComponentProps<typeof CardDescription>,\n  \"children\"\n> & {\n  children: string\n}\n\nexport const PlanDescription = ({\n  className,\n  children,\n  ...props\n}: PlanDescriptionProps) => {\n  const { isStreaming } = usePlan()\n\n  return (\n    <CardDescription\n      className={cn(\"text-balance\", className)}\n      data-slot=\"plan-description\"\n      {...props}\n    >\n      {isStreaming ? <Shimmer>{children}</Shimmer> : children}\n    </CardDescription>\n  )\n}\n\nexport type PlanActionProps = ComponentProps<typeof CardAction>\n\nexport const PlanAction = (props: PlanActionProps) => (\n  <CardAction data-slot=\"plan-action\" {...props} />\n)\n\nexport type PlanContentProps = ComponentProps<typeof CardContent>\n\nexport const PlanContent = (props: PlanContentProps) => (\n  <CollapsibleContent asChild>\n    <CardContent data-slot=\"plan-content\" {...props} />\n  </CollapsibleContent>\n)\n\nexport type PlanFooterProps = ComponentProps<\"div\">\n\nexport const PlanFooter = (props: PlanFooterProps) => (\n  <CardFooter data-slot=\"plan-footer\" {...props} />\n)\n\nexport type PlanTriggerProps = ComponentProps<typeof CollapsibleTrigger>\n\nexport const PlanTrigger = ({ className, ...props }: PlanTriggerProps) => (\n  <CollapsibleTrigger asChild>\n    <Button\n      className={cn(\"size-8\", className)}\n      data-slot=\"plan-trigger\"\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      <ChevronsUpDownIcon className=\"size-4\" />\n      <span className=\"sr-only\">Toggle plan</span>\n    </Button>\n  </CollapsibleTrigger>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/card.tsx",
          "target": "@components/ai-elements/_ui/card.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card\"\n      className={cn(\n        \"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-header\"\n      className={cn(\n        \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-title\"\n      className={cn(\"leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-action\"\n      className={cn(\n        \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-content\"\n      className={cn(\"px-6\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-footer\"\n      className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Card,\n  CardHeader,\n  CardFooter,\n  CardTitle,\n  CardAction,\n  CardDescription,\n  CardContent,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "components/ai-elements/shimmer.tsx",
          "target": "@components/ai-elements/shimmer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport type { MotionProps } from \"motion/react\"\nimport { motion } from \"motion/react\"\nimport type { CSSProperties, ElementType, JSX } from \"react\"\nimport { memo, useMemo } from \"react\"\n\ntype MotionHTMLProps = MotionProps & Record<string, unknown>\n\n// Cache motion components at module level to avoid creating during render\nconst motionComponentCache = new Map<\n  keyof JSX.IntrinsicElements,\n  React.ComponentType<MotionHTMLProps>\n>()\n\nconst getMotionComponent = (element: keyof JSX.IntrinsicElements) => {\n  let component = motionComponentCache.get(element)\n  if (!component) {\n    component = motion.create(element)\n    motionComponentCache.set(element, component)\n  }\n  return component\n}\n\nexport interface TextShimmerProps {\n  children: string\n  as?: ElementType\n  className?: string\n  duration?: number\n  spread?: number\n}\n\nconst ShimmerComponent = ({\n  children,\n  as: Component = \"p\",\n  className,\n  duration = 2,\n  spread = 2,\n}: TextShimmerProps) => {\n  const MotionComponent = getMotionComponent(\n    Component as keyof JSX.IntrinsicElements\n  )\n\n  const dynamicSpread = useMemo(\n    () => (children?.length ?? 0) * spread,\n    [children, spread]\n  )\n\n  return (\n    <MotionComponent\n      animate={{ backgroundPosition: \"0% center\" }}\n      className={cn(\n        \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n        \"[background-repeat:no-repeat,padding-box] [--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))]\",\n        className\n      )}\n      initial={{ backgroundPosition: \"100% center\" }}\n      style={\n        {\n          \"--spread\": `${dynamicSpread}px`,\n          backgroundImage:\n            \"var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))\",\n        } as CSSProperties\n      }\n      transition={{\n        duration,\n        ease: \"linear\",\n        repeat: Number.POSITIVE_INFINITY,\n      }}\n    >\n      {children}\n    </MotionComponent>\n  )\n}\n\nexport const Shimmer = memo(ShimmerComponent)\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-prompt-input",
      "type": "registry:block",
      "title": "Ai Elements Prompt Input",
      "description": "prompt input",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "cmdk@1.1.1",
        "lucide-react@0.577.0",
        "nanoid@5.1.16",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/prompt-input.tsx",
          "target": "@components/ai-elements/prompt-input.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n} from \"@/components/ai-elements/_ui/command\"\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ai-elements/_ui/dropdown-menu\"\nimport {\n  HoverCard,\n  HoverCardContent,\n  HoverCardTrigger,\n} from \"@/components/ai-elements/_ui/hover-card\"\nimport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupTextarea,\n} from \"@/components/ai-elements/_ui/input-group\"\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ai-elements/_ui/select\"\nimport { Spinner } from \"@/components/ai-elements/_ui/spinner\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipTrigger,\n} from \"@/components/ai-elements/_ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport type { ChatStatus, FileUIPart, SourceDocumentUIPart } from \"ai\"\nimport {\n  CornerDownLeftIcon,\n  ImageIcon,\n  Monitor,\n  PlusIcon,\n  SquareIcon,\n  XIcon,\n} from \"lucide-react\"\nimport { nanoid } from \"nanoid\"\nimport type {\n  ChangeEvent,\n  ChangeEventHandler,\n  ClipboardEventHandler,\n  ComponentProps,\n  FormEvent,\n  FormEventHandler,\n  HTMLAttributes,\n  KeyboardEventHandler,\n  PropsWithChildren,\n  ReactNode,\n  RefObject,\n} from \"react\"\nimport {\n  Children,\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst convertBlobUrlToDataUrl = async (url: string): Promise<string | null> => {\n  try {\n    const response = await fetch(url)\n    const blob = await response.blob()\n    // FileReader uses callback-based API, wrapping in Promise is necessary\n    // oxlint-disable-next-line eslint-plugin-promise(avoid-new)\n    return new Promise((resolve) => {\n      const reader = new FileReader()\n      // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)\n      reader.onloadend = () => resolve(reader.result as string)\n      // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)\n      reader.onerror = () => resolve(null)\n      reader.readAsDataURL(blob)\n    })\n  } catch {\n    return null\n  }\n}\n\nconst captureScreenshot = async (): Promise<File | null> => {\n  if (\n    typeof navigator === \"undefined\" ||\n    !navigator.mediaDevices?.getDisplayMedia\n  ) {\n    return null\n  }\n\n  let stream: MediaStream | null = null\n  const video = document.createElement(\"video\")\n  video.muted = true\n  video.playsInline = true\n\n  try {\n    stream = await navigator.mediaDevices.getDisplayMedia({\n      audio: false,\n      video: true,\n    })\n\n    video.srcObject = stream\n\n    // Video element uses callback-based API, wrapping in Promise is necessary\n    // oxlint-disable-next-line eslint-plugin-promise(avoid-new)\n    await new Promise<void>((resolve, reject) => {\n      // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)\n      video.onloadedmetadata = () => resolve()\n      // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)\n      video.onerror = () => reject(new Error(\"Failed to load screen stream\"))\n    })\n\n    await video.play()\n\n    const width = video.videoWidth\n    const height = video.videoHeight\n    if (!width || !height) {\n      return null\n    }\n\n    const canvas = document.createElement(\"canvas\")\n    canvas.width = width\n    canvas.height = height\n    const context = canvas.getContext(\"2d\")\n    if (!context) {\n      return null\n    }\n\n    context.drawImage(video, 0, 0, width, height)\n    // canvas.toBlob uses callback-based API, wrapping in Promise is necessary\n    // oxlint-disable-next-line eslint-plugin-promise(avoid-new)\n    const blob = await new Promise<Blob | null>((resolve) => {\n      canvas.toBlob(resolve, \"image/png\")\n    })\n    if (!blob) {\n      return null\n    }\n\n    const timestamp = new Date()\n      .toISOString()\n      .replaceAll(/[:.]/g, \"-\")\n      .replace(\"T\", \"_\")\n      .replace(\"Z\", \"\")\n\n    return new File([blob], `screenshot-${timestamp}.png`, {\n      lastModified: Date.now(),\n      type: \"image/png\",\n    })\n  } finally {\n    if (stream) {\n      for (const track of stream.getTracks()) {\n        track.stop()\n      }\n    }\n    video.pause()\n    video.srcObject = null\n  }\n}\n\n// ============================================================================\n// Provider Context & Types\n// ============================================================================\n\nexport interface AttachmentsContext {\n  files: (FileUIPart & { id: string })[]\n  add: (files: File[] | FileList) => void\n  remove: (id: string) => void\n  clear: () => void\n  openFileDialog: () => void\n  fileInputRef: RefObject<HTMLInputElement | null>\n}\n\nexport interface TextInputContext {\n  value: string\n  setInput: (v: string) => void\n  clear: () => void\n}\n\nexport interface PromptInputControllerProps {\n  textInput: TextInputContext\n  attachments: AttachmentsContext\n  /** INTERNAL: Allows PromptInput to register its file textInput + \"open\" callback */\n  __registerFileInput: (\n    ref: RefObject<HTMLInputElement | null>,\n    open: () => void\n  ) => void\n}\n\nconst PromptInputController = createContext<PromptInputControllerProps | null>(\n  null\n)\nconst ProviderAttachmentsContext = createContext<AttachmentsContext | null>(\n  null\n)\n\nexport const usePromptInputController = () => {\n  const ctx = useContext(PromptInputController)\n  if (!ctx) {\n    throw new Error(\n      \"Wrap your component inside <PromptInputProvider> to use usePromptInputController().\"\n    )\n  }\n  return ctx\n}\n\n// Optional variants (do NOT throw). Useful for dual-mode components.\nconst useOptionalPromptInputController = () => useContext(PromptInputController)\n\nexport const useProviderAttachments = () => {\n  const ctx = useContext(ProviderAttachmentsContext)\n  if (!ctx) {\n    throw new Error(\n      \"Wrap your component inside <PromptInputProvider> to use useProviderAttachments().\"\n    )\n  }\n  return ctx\n}\n\nconst useOptionalProviderAttachments = () =>\n  useContext(ProviderAttachmentsContext)\n\nexport type PromptInputProviderProps = PropsWithChildren<{\n  initialInput?: string\n}>\n\n/**\n * Optional global provider that lifts PromptInput state outside of PromptInput.\n * If you don't use it, PromptInput stays fully self-managed.\n */\nexport const PromptInputProvider = ({\n  initialInput: initialTextInput = \"\",\n  children,\n}: PromptInputProviderProps) => {\n  // ----- textInput state\n  const [textInput, setTextInput] = useState(initialTextInput)\n  const clearInput = useCallback(() => setTextInput(\"\"), [])\n\n  // ----- attachments state (global when wrapped)\n  const [attachmentFiles, setAttachmentFiles] = useState<\n    (FileUIPart & { id: string })[]\n  >([])\n  const fileInputRef = useRef<HTMLInputElement | null>(null)\n  // oxlint-disable-next-line eslint(no-empty-function)\n  const openRef = useRef<() => void>(() => {})\n\n  const add = useCallback((files: File[] | FileList) => {\n    const incoming = [...files]\n    if (incoming.length === 0) {\n      return\n    }\n\n    setAttachmentFiles((prev) => [\n      ...prev,\n      ...incoming.map((file) => ({\n        filename: file.name,\n        id: nanoid(),\n        mediaType: file.type,\n        type: \"file\" as const,\n        url: URL.createObjectURL(file),\n      })),\n    ])\n  }, [])\n\n  const remove = useCallback((id: string) => {\n    setAttachmentFiles((prev) => {\n      const found = prev.find((f) => f.id === id)\n      if (found?.url) {\n        URL.revokeObjectURL(found.url)\n      }\n      return prev.filter((f) => f.id !== id)\n    })\n  }, [])\n\n  const clear = useCallback(() => {\n    setAttachmentFiles((prev) => {\n      for (const f of prev) {\n        if (f.url) {\n          URL.revokeObjectURL(f.url)\n        }\n      }\n      return []\n    })\n  }, [])\n\n  // Keep a ref to attachments for cleanup on unmount (avoids stale closure)\n  const attachmentsRef = useRef(attachmentFiles)\n\n  useEffect(() => {\n    attachmentsRef.current = attachmentFiles\n  }, [attachmentFiles])\n\n  // Cleanup blob URLs on unmount to prevent memory leaks\n  useEffect(\n    () => () => {\n      for (const f of attachmentsRef.current) {\n        if (f.url) {\n          URL.revokeObjectURL(f.url)\n        }\n      }\n    },\n    []\n  )\n\n  const openFileDialog = useCallback(() => {\n    openRef.current?.()\n  }, [])\n\n  const attachments = useMemo<AttachmentsContext>(\n    () => ({\n      add,\n      clear,\n      fileInputRef,\n      files: attachmentFiles,\n      openFileDialog,\n      remove,\n    }),\n    [attachmentFiles, add, remove, clear, openFileDialog]\n  )\n\n  const __registerFileInput = useCallback(\n    (ref: RefObject<HTMLInputElement | null>, open: () => void) => {\n      fileInputRef.current = ref.current\n      openRef.current = open\n    },\n    []\n  )\n\n  const controller = useMemo<PromptInputControllerProps>(\n    () => ({\n      __registerFileInput,\n      attachments,\n      textInput: {\n        clear: clearInput,\n        setInput: setTextInput,\n        value: textInput,\n      },\n    }),\n    [textInput, clearInput, attachments, __registerFileInput]\n  )\n\n  return (\n    <PromptInputController.Provider value={controller}>\n      <ProviderAttachmentsContext.Provider value={attachments}>\n        {children}\n      </ProviderAttachmentsContext.Provider>\n    </PromptInputController.Provider>\n  )\n}\n\n// ============================================================================\n// Component Context & Hooks\n// ============================================================================\n\nconst LocalAttachmentsContext = createContext<AttachmentsContext | null>(null)\n\nexport const usePromptInputAttachments = () => {\n  // Prefer local context (inside PromptInput) as it has validation, fall back to provider\n  const provider = useOptionalProviderAttachments()\n  const local = useContext(LocalAttachmentsContext)\n  const context = local ?? provider\n  if (!context) {\n    throw new Error(\n      \"usePromptInputAttachments must be used within a PromptInput or PromptInputProvider\"\n    )\n  }\n  return context\n}\n\n// ============================================================================\n// Referenced Sources (Local to PromptInput)\n// ============================================================================\n\nexport interface ReferencedSourcesContext {\n  sources: (SourceDocumentUIPart & { id: string })[]\n  add: (sources: SourceDocumentUIPart[] | SourceDocumentUIPart) => void\n  remove: (id: string) => void\n  clear: () => void\n}\n\nexport const LocalReferencedSourcesContext =\n  createContext<ReferencedSourcesContext | null>(null)\n\nexport const usePromptInputReferencedSources = () => {\n  const ctx = useContext(LocalReferencedSourcesContext)\n  if (!ctx) {\n    throw new Error(\n      \"usePromptInputReferencedSources must be used within a LocalReferencedSourcesContext.Provider\"\n    )\n  }\n  return ctx\n}\n\nexport type PromptInputActionAddAttachmentsProps = ComponentProps<\n  typeof DropdownMenuItem\n> & {\n  label?: string\n}\n\nexport const PromptInputActionAddAttachments = ({\n  label = \"Add photos or files\",\n  ...props\n}: PromptInputActionAddAttachmentsProps) => {\n  const attachments = usePromptInputAttachments()\n\n  const handleSelect = useCallback(\n    (e: Event) => {\n      e.preventDefault()\n      attachments.openFileDialog()\n    },\n    [attachments]\n  )\n\n  return (\n    <DropdownMenuItem {...props} onSelect={handleSelect}>\n      <ImageIcon className=\"mr-2 size-4\" /> {label}\n    </DropdownMenuItem>\n  )\n}\n\nexport type PromptInputActionAddScreenshotProps = ComponentProps<\n  typeof DropdownMenuItem\n> & {\n  label?: string\n}\n\nexport const PromptInputActionAddScreenshot = ({\n  label = \"Take screenshot\",\n  onSelect,\n  ...props\n}: PromptInputActionAddScreenshotProps) => {\n  const attachments = usePromptInputAttachments()\n\n  const handleSelect = useCallback(\n    async (event: Event) => {\n      onSelect?.(event)\n      if (event.defaultPrevented) {\n        return\n      }\n\n      try {\n        const screenshot = await captureScreenshot()\n        if (screenshot) {\n          attachments.add([screenshot])\n        }\n      } catch (error) {\n        if (\n          error instanceof DOMException &&\n          (error.name === \"NotAllowedError\" || error.name === \"AbortError\")\n        ) {\n          return\n        }\n        throw error\n      }\n    },\n    [onSelect, attachments]\n  )\n\n  return (\n    <DropdownMenuItem {...props} onSelect={handleSelect}>\n      <Monitor className=\"mr-2 size-4\" />\n      {label}\n    </DropdownMenuItem>\n  )\n}\n\nexport interface PromptInputMessage {\n  text: string\n  files: FileUIPart[]\n}\n\nexport type PromptInputProps = Omit<\n  HTMLAttributes<HTMLFormElement>,\n  \"onSubmit\" | \"onError\"\n> & {\n  // e.g., \"image/*\" or leave undefined for any\n  accept?: string\n  multiple?: boolean\n  // When true, accepts drops anywhere on document. Default false (opt-in).\n  globalDrop?: boolean\n  // Render a hidden input with given name and keep it in sync for native form posts. Default false.\n  syncHiddenInput?: boolean\n  // Minimal constraints\n  maxFiles?: number\n  // bytes\n  maxFileSize?: number\n  onError?: (err: {\n    code: \"max_files\" | \"max_file_size\" | \"accept\"\n    message: string\n  }) => void\n  onSubmit: (\n    message: PromptInputMessage,\n    event: FormEvent<HTMLFormElement>\n  ) => void | Promise<void>\n}\n\nexport const PromptInput = ({\n  className,\n  accept,\n  multiple,\n  globalDrop,\n  syncHiddenInput,\n  maxFiles,\n  maxFileSize,\n  onError,\n  onSubmit,\n  children,\n  ...props\n}: PromptInputProps) => {\n  // Try to use a provider controller if present\n  const controller = useOptionalPromptInputController()\n  const usingProvider = !!controller\n\n  // Refs\n  const inputRef = useRef<HTMLInputElement | null>(null)\n  const formRef = useRef<HTMLFormElement | null>(null)\n\n  // ----- Local attachments (only used when no provider)\n  const [items, setItems] = useState<(FileUIPart & { id: string })[]>([])\n  const files = usingProvider ? controller.attachments.files : items\n\n  // ----- Local referenced sources (always local to PromptInput)\n  const [referencedSources, setReferencedSources] = useState<\n    (SourceDocumentUIPart & { id: string })[]\n  >([])\n\n  // Keep a ref to files for cleanup on unmount (avoids stale closure)\n  const filesRef = useRef(files)\n\n  useEffect(() => {\n    filesRef.current = files\n  }, [files])\n\n  const openFileDialogLocal = useCallback(() => {\n    inputRef.current?.click()\n  }, [])\n\n  const matchesAccept = useCallback(\n    (f: File) => {\n      if (!accept || accept.trim() === \"\") {\n        return true\n      }\n\n      const patterns = accept\n        .split(\",\")\n        .map((s) => s.trim())\n        .filter(Boolean)\n\n      return patterns.some((pattern) => {\n        if (pattern.endsWith(\"/*\")) {\n          // e.g: image/* -> image/\n          const prefix = pattern.slice(0, -1)\n          return f.type.startsWith(prefix)\n        }\n        return f.type === pattern\n      })\n    },\n    [accept]\n  )\n\n  const addLocal = useCallback(\n    (fileList: File[] | FileList) => {\n      const incoming = [...fileList]\n      const accepted = incoming.filter((f) => matchesAccept(f))\n      if (incoming.length && accepted.length === 0) {\n        onError?.({\n          code: \"accept\",\n          message: \"No files match the accepted types.\",\n        })\n        return\n      }\n      const withinSize = (f: File) =>\n        maxFileSize ? f.size <= maxFileSize : true\n      const sized = accepted.filter(withinSize)\n      if (accepted.length > 0 && sized.length === 0) {\n        onError?.({\n          code: \"max_file_size\",\n          message: \"All files exceed the maximum size.\",\n        })\n        return\n      }\n\n      setItems((prev) => {\n        const capacity =\n          typeof maxFiles === \"number\"\n            ? Math.max(0, maxFiles - prev.length)\n            : undefined\n        const capped =\n          typeof capacity === \"number\" ? sized.slice(0, capacity) : sized\n        if (typeof capacity === \"number\" && sized.length > capacity) {\n          onError?.({\n            code: \"max_files\",\n            message: \"Too many files. Some were not added.\",\n          })\n        }\n        const next: (FileUIPart & { id: string })[] = []\n        for (const file of capped) {\n          next.push({\n            filename: file.name,\n            id: nanoid(),\n            mediaType: file.type,\n            type: \"file\",\n            url: URL.createObjectURL(file),\n          })\n        }\n        return [...prev, ...next]\n      })\n    },\n    [matchesAccept, maxFiles, maxFileSize, onError]\n  )\n\n  const removeLocal = useCallback(\n    (id: string) =>\n      setItems((prev) => {\n        const found = prev.find((file) => file.id === id)\n        if (found?.url) {\n          URL.revokeObjectURL(found.url)\n        }\n        return prev.filter((file) => file.id !== id)\n      }),\n    []\n  )\n\n  // Wrapper that validates files before calling provider's add\n  const addWithProviderValidation = useCallback(\n    (fileList: File[] | FileList) => {\n      const incoming = [...fileList]\n      const accepted = incoming.filter((f) => matchesAccept(f))\n      if (incoming.length && accepted.length === 0) {\n        onError?.({\n          code: \"accept\",\n          message: \"No files match the accepted types.\",\n        })\n        return\n      }\n      const withinSize = (f: File) =>\n        maxFileSize ? f.size <= maxFileSize : true\n      const sized = accepted.filter(withinSize)\n      if (accepted.length > 0 && sized.length === 0) {\n        onError?.({\n          code: \"max_file_size\",\n          message: \"All files exceed the maximum size.\",\n        })\n        return\n      }\n\n      const currentCount = files.length\n      const capacity =\n        typeof maxFiles === \"number\"\n          ? Math.max(0, maxFiles - currentCount)\n          : undefined\n      const capped =\n        typeof capacity === \"number\" ? sized.slice(0, capacity) : sized\n      if (typeof capacity === \"number\" && sized.length > capacity) {\n        onError?.({\n          code: \"max_files\",\n          message: \"Too many files. Some were not added.\",\n        })\n      }\n\n      if (capped.length > 0) {\n        controller?.attachments.add(capped)\n      }\n    },\n    [matchesAccept, maxFileSize, maxFiles, onError, files.length, controller]\n  )\n\n  const clearAttachments = useCallback(\n    () =>\n      usingProvider\n        ? controller?.attachments.clear()\n        : setItems((prev) => {\n            for (const file of prev) {\n              if (file.url) {\n                URL.revokeObjectURL(file.url)\n              }\n            }\n            return []\n          }),\n    [usingProvider, controller]\n  )\n\n  const clearReferencedSources = useCallback(() => setReferencedSources([]), [])\n\n  const add = usingProvider ? addWithProviderValidation : addLocal\n  const remove = usingProvider ? controller.attachments.remove : removeLocal\n  const openFileDialog = usingProvider\n    ? controller.attachments.openFileDialog\n    : openFileDialogLocal\n\n  const clear = useCallback(() => {\n    clearAttachments()\n    clearReferencedSources()\n  }, [clearAttachments, clearReferencedSources])\n\n  // Let provider know about our hidden file input so external menus can call openFileDialog()\n  useEffect(() => {\n    if (!usingProvider) {\n      return\n    }\n    controller.__registerFileInput(inputRef, () => inputRef.current?.click())\n  }, [usingProvider, controller])\n\n  // Note: File input cannot be programmatically set for security reasons\n  // The syncHiddenInput prop is no longer functional\n  useEffect(() => {\n    if (syncHiddenInput && inputRef.current && files.length === 0) {\n      inputRef.current.value = \"\"\n    }\n  }, [files, syncHiddenInput])\n\n  // Attach drop handlers on nearest form and document (opt-in)\n  useEffect(() => {\n    const form = formRef.current\n    if (!form) {\n      return\n    }\n    if (globalDrop) {\n      // when global drop is on, let the document-level handler own drops\n      return\n    }\n\n    const onDragOver = (e: DragEvent) => {\n      if (e.dataTransfer?.types?.includes(\"Files\")) {\n        e.preventDefault()\n      }\n    }\n    const onDrop = (e: DragEvent) => {\n      if (e.dataTransfer?.types?.includes(\"Files\")) {\n        e.preventDefault()\n      }\n      if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {\n        add(e.dataTransfer.files)\n      }\n    }\n    form.addEventListener(\"dragover\", onDragOver)\n    form.addEventListener(\"drop\", onDrop)\n    return () => {\n      form.removeEventListener(\"dragover\", onDragOver)\n      form.removeEventListener(\"drop\", onDrop)\n    }\n  }, [add, globalDrop])\n\n  useEffect(() => {\n    if (!globalDrop) {\n      return\n    }\n\n    const onDragOver = (e: DragEvent) => {\n      if (e.dataTransfer?.types?.includes(\"Files\")) {\n        e.preventDefault()\n      }\n    }\n    const onDrop = (e: DragEvent) => {\n      if (e.dataTransfer?.types?.includes(\"Files\")) {\n        e.preventDefault()\n      }\n      if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {\n        add(e.dataTransfer.files)\n      }\n    }\n    document.addEventListener(\"dragover\", onDragOver)\n    document.addEventListener(\"drop\", onDrop)\n    return () => {\n      document.removeEventListener(\"dragover\", onDragOver)\n      document.removeEventListener(\"drop\", onDrop)\n    }\n  }, [add, globalDrop])\n\n  useEffect(\n    () => () => {\n      if (!usingProvider) {\n        for (const f of filesRef.current) {\n          if (f.url) {\n            URL.revokeObjectURL(f.url)\n          }\n        }\n      }\n    },\n    [usingProvider]\n  )\n\n  const handleChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n    (event) => {\n      if (event.currentTarget.files) {\n        add(event.currentTarget.files)\n      }\n      // Reset input value to allow selecting files that were previously removed\n      event.currentTarget.value = \"\"\n    },\n    [add]\n  )\n\n  const attachmentsCtx = useMemo<AttachmentsContext>(\n    () => ({\n      add,\n      clear: clearAttachments,\n      fileInputRef: inputRef,\n      files: files.map((item) => ({ ...item, id: item.id })),\n      openFileDialog,\n      remove,\n    }),\n    [files, add, remove, clearAttachments, openFileDialog]\n  )\n\n  const refsCtx = useMemo<ReferencedSourcesContext>(\n    () => ({\n      add: (incoming: SourceDocumentUIPart[] | SourceDocumentUIPart) => {\n        const array = Array.isArray(incoming) ? incoming : [incoming]\n        setReferencedSources((prev) => [\n          ...prev,\n          ...array.map((s) => ({ ...s, id: nanoid() })),\n        ])\n      },\n      clear: clearReferencedSources,\n      remove: (id: string) => {\n        setReferencedSources((prev) => prev.filter((s) => s.id !== id))\n      },\n      sources: referencedSources,\n    }),\n    [referencedSources, clearReferencedSources]\n  )\n\n  const handleSubmit: FormEventHandler<HTMLFormElement> = useCallback(\n    async (event) => {\n      event.preventDefault()\n\n      const form = event.currentTarget\n      const text = usingProvider\n        ? controller.textInput.value\n        : (() => {\n            const formData = new FormData(form)\n            return (formData.get(\"message\") as string) || \"\"\n          })()\n\n      // Reset form immediately after capturing text to avoid race condition\n      // where user input during async blob conversion would be lost\n      if (!usingProvider) {\n        form.reset()\n      }\n\n      try {\n        // Convert blob URLs to data URLs asynchronously\n        const convertedFiles: FileUIPart[] = await Promise.all(\n          files.map(async ({ id, ...item }) => {\n            void id\n            if (item.url?.startsWith(\"blob:\")) {\n              const dataUrl = await convertBlobUrlToDataUrl(item.url)\n              // If conversion failed, keep the original blob URL\n              return {\n                ...item,\n                url: dataUrl ?? item.url,\n              }\n            }\n            return item\n          })\n        )\n\n        const result = onSubmit({ files: convertedFiles, text }, event)\n\n        // Handle both sync and async onSubmit\n        if (result instanceof Promise) {\n          try {\n            await result\n            clear()\n            if (usingProvider) {\n              controller.textInput.clear()\n            }\n          } catch {\n            // Don't clear on error - user may want to retry\n          }\n        } else {\n          // Sync function completed without throwing, clear inputs\n          clear()\n          if (usingProvider) {\n            controller.textInput.clear()\n          }\n        }\n      } catch {\n        // Don't clear on error - user may want to retry\n      }\n    },\n    [usingProvider, controller, files, onSubmit, clear]\n  )\n\n  // Render with or without local provider\n  const inner = (\n    <>\n      <input\n        accept={accept}\n        aria-label=\"Upload files\"\n        className=\"hidden\"\n        multiple={multiple}\n        onChange={handleChange}\n        ref={inputRef}\n        title=\"Upload files\"\n        type=\"file\"\n      />\n      <form\n        className={cn(\"w-full\", className)}\n        onSubmit={handleSubmit}\n        ref={formRef}\n        {...props}\n      >\n        <InputGroup className=\"overflow-hidden\">{children}</InputGroup>\n      </form>\n    </>\n  )\n\n  const withReferencedSources = (\n    <LocalReferencedSourcesContext.Provider value={refsCtx}>\n      {inner}\n    </LocalReferencedSourcesContext.Provider>\n  )\n\n  // Always provide LocalAttachmentsContext so children get validated add function\n  return (\n    <LocalAttachmentsContext.Provider value={attachmentsCtx}>\n      {withReferencedSources}\n    </LocalAttachmentsContext.Provider>\n  )\n}\n\nexport type PromptInputBodyProps = HTMLAttributes<HTMLDivElement>\n\nexport const PromptInputBody = ({\n  className,\n  ...props\n}: PromptInputBodyProps) => (\n  <div className={cn(\"contents\", className)} {...props} />\n)\n\nexport type PromptInputTextareaProps = ComponentProps<typeof InputGroupTextarea>\n\nexport const PromptInputTextarea = ({\n  onChange,\n  onKeyDown,\n  className,\n  placeholder = \"What would you like to know?\",\n  ...props\n}: PromptInputTextareaProps) => {\n  const controller = useOptionalPromptInputController()\n  const attachments = usePromptInputAttachments()\n  const [isComposing, setIsComposing] = useState(false)\n\n  const handleKeyDown: KeyboardEventHandler<HTMLTextAreaElement> = useCallback(\n    (e) => {\n      // Call the external onKeyDown handler first\n      onKeyDown?.(e)\n\n      // If the external handler prevented default, don't run internal logic\n      if (e.defaultPrevented) {\n        return\n      }\n\n      if (e.key === \"Enter\") {\n        if (isComposing || e.nativeEvent.isComposing) {\n          return\n        }\n        if (e.shiftKey) {\n          return\n        }\n        e.preventDefault()\n\n        // Check if the submit button is disabled before submitting\n        const { form } = e.currentTarget\n        const submitButton = form?.querySelector(\n          'button[type=\"submit\"]'\n        ) as HTMLButtonElement | null\n        if (submitButton?.disabled) {\n          return\n        }\n\n        form?.requestSubmit()\n      }\n\n      // Remove last attachment when Backspace is pressed and textarea is empty\n      if (\n        e.key === \"Backspace\" &&\n        e.currentTarget.value === \"\" &&\n        attachments.files.length > 0\n      ) {\n        e.preventDefault()\n        const lastAttachment = attachments.files.at(-1)\n        if (lastAttachment) {\n          attachments.remove(lastAttachment.id)\n        }\n      }\n    },\n    [onKeyDown, isComposing, attachments]\n  )\n\n  const handlePaste: ClipboardEventHandler<HTMLTextAreaElement> = useCallback(\n    (event) => {\n      const items = event.clipboardData?.items\n\n      if (!items) {\n        return\n      }\n\n      const files: File[] = []\n\n      for (const item of items) {\n        if (item.kind === \"file\") {\n          const file = item.getAsFile()\n          if (file) {\n            files.push(file)\n          }\n        }\n      }\n\n      if (files.length > 0) {\n        event.preventDefault()\n        attachments.add(files)\n      }\n    },\n    [attachments]\n  )\n\n  const handleCompositionEnd = useCallback(() => setIsComposing(false), [])\n  const handleCompositionStart = useCallback(() => setIsComposing(true), [])\n\n  const controlledProps = controller\n    ? {\n        onChange: (e: ChangeEvent<HTMLTextAreaElement>) => {\n          controller.textInput.setInput(e.currentTarget.value)\n          onChange?.(e)\n        },\n        value: controller.textInput.value,\n      }\n    : {\n        onChange,\n      }\n\n  return (\n    <InputGroupTextarea\n      className={cn(\"field-sizing-content max-h-48 min-h-16\", className)}\n      name=\"message\"\n      onCompositionEnd={handleCompositionEnd}\n      onCompositionStart={handleCompositionStart}\n      onKeyDown={handleKeyDown}\n      onPaste={handlePaste}\n      placeholder={placeholder}\n      {...props}\n      {...controlledProps}\n    />\n  )\n}\n\nexport type PromptInputHeaderProps = Omit<\n  ComponentProps<typeof InputGroupAddon>,\n  \"align\"\n>\n\nexport const PromptInputHeader = ({\n  className,\n  ...props\n}: PromptInputHeaderProps) => (\n  <InputGroupAddon\n    align=\"block-end\"\n    className={cn(\"order-first flex-wrap gap-1\", className)}\n    {...props}\n  />\n)\n\nexport type PromptInputFooterProps = Omit<\n  ComponentProps<typeof InputGroupAddon>,\n  \"align\"\n>\n\nexport const PromptInputFooter = ({\n  className,\n  ...props\n}: PromptInputFooterProps) => (\n  <InputGroupAddon\n    align=\"block-end\"\n    className={cn(\"justify-between gap-1\", className)}\n    {...props}\n  />\n)\n\nexport type PromptInputToolsProps = HTMLAttributes<HTMLDivElement>\n\nexport const PromptInputTools = ({\n  className,\n  ...props\n}: PromptInputToolsProps) => (\n  <div\n    className={cn(\"flex min-w-0 items-center gap-1\", className)}\n    {...props}\n  />\n)\n\nexport type PromptInputButtonTooltip =\n  | string\n  | {\n      content: ReactNode\n      shortcut?: string\n      side?: ComponentProps<typeof TooltipContent>[\"side\"]\n    }\n\nexport type PromptInputButtonProps = ComponentProps<typeof InputGroupButton> & {\n  tooltip?: PromptInputButtonTooltip\n}\n\nexport const PromptInputButton = ({\n  variant = \"ghost\",\n  className,\n  size,\n  tooltip,\n  ...props\n}: PromptInputButtonProps) => {\n  const newSize =\n    size ?? (Children.count(props.children) > 1 ? \"sm\" : \"icon-sm\")\n\n  const button = (\n    <InputGroupButton\n      className={cn(className)}\n      size={newSize}\n      type=\"button\"\n      variant={variant}\n      {...props}\n    />\n  )\n\n  if (!tooltip) {\n    return button\n  }\n\n  const tooltipContent = typeof tooltip === \"string\" ? tooltip : tooltip.content\n  const shortcut = typeof tooltip === \"string\" ? undefined : tooltip.shortcut\n  const side = typeof tooltip === \"string\" ? \"top\" : (tooltip.side ?? \"top\")\n\n  return (\n    <Tooltip>\n      <TooltipTrigger asChild>{button}</TooltipTrigger>\n      <TooltipContent side={side}>\n        {tooltipContent}\n        {shortcut && (\n          <span className=\"text-muted-foreground ml-2\">{shortcut}</span>\n        )}\n      </TooltipContent>\n    </Tooltip>\n  )\n}\n\nexport type PromptInputActionMenuProps = ComponentProps<typeof DropdownMenu>\nexport const PromptInputActionMenu = (props: PromptInputActionMenuProps) => (\n  <DropdownMenu {...props} />\n)\n\nexport type PromptInputActionMenuTriggerProps = PromptInputButtonProps\n\nexport const PromptInputActionMenuTrigger = ({\n  className,\n  children,\n  ...props\n}: PromptInputActionMenuTriggerProps) => (\n  <DropdownMenuTrigger asChild>\n    <PromptInputButton className={className} {...props}>\n      {children ?? <PlusIcon className=\"size-4\" />}\n    </PromptInputButton>\n  </DropdownMenuTrigger>\n)\n\nexport type PromptInputActionMenuContentProps = ComponentProps<\n  typeof DropdownMenuContent\n>\nexport const PromptInputActionMenuContent = ({\n  className,\n  ...props\n}: PromptInputActionMenuContentProps) => (\n  <DropdownMenuContent align=\"start\" className={cn(className)} {...props} />\n)\n\nexport type PromptInputActionMenuItemProps = ComponentProps<\n  typeof DropdownMenuItem\n>\nexport const PromptInputActionMenuItem = ({\n  className,\n  ...props\n}: PromptInputActionMenuItemProps) => (\n  <DropdownMenuItem className={cn(className)} {...props} />\n)\n\n// Note: Actions that perform side-effects (like opening a file dialog)\n// are provided in opt-in modules (e.g., prompt-input-attachments).\n\nexport type PromptInputSubmitProps = ComponentProps<typeof InputGroupButton> & {\n  status?: ChatStatus\n  onStop?: () => void\n}\n\nexport const PromptInputSubmit = ({\n  className,\n  variant = \"default\",\n  size = \"icon-sm\",\n  status,\n  onStop,\n  onClick,\n  children,\n  ...props\n}: PromptInputSubmitProps) => {\n  const isGenerating = status === \"submitted\" || status === \"streaming\"\n\n  let Icon = <CornerDownLeftIcon className=\"size-4\" />\n\n  if (status === \"submitted\") {\n    Icon = <Spinner />\n  } else if (status === \"streaming\") {\n    Icon = <SquareIcon className=\"size-4\" />\n  } else if (status === \"error\") {\n    Icon = <XIcon className=\"size-4\" />\n  }\n\n  const handleClick = useCallback(\n    (e: React.MouseEvent<HTMLButtonElement>) => {\n      if (isGenerating && onStop) {\n        e.preventDefault()\n        onStop()\n        return\n      }\n      onClick?.(e)\n    },\n    [isGenerating, onStop, onClick]\n  )\n\n  return (\n    <InputGroupButton\n      aria-label={isGenerating ? \"Stop\" : \"Submit\"}\n      className={cn(className)}\n      onClick={handleClick}\n      size={size}\n      type={isGenerating && onStop ? \"button\" : \"submit\"}\n      variant={variant}\n      {...props}\n    >\n      {children ?? Icon}\n    </InputGroupButton>\n  )\n}\n\nexport type PromptInputSelectProps = ComponentProps<typeof Select>\n\nexport const PromptInputSelect = (props: PromptInputSelectProps) => (\n  <Select {...props} />\n)\n\nexport type PromptInputSelectTriggerProps = ComponentProps<typeof SelectTrigger>\n\nexport const PromptInputSelectTrigger = ({\n  className,\n  ...props\n}: PromptInputSelectTriggerProps) => (\n  <SelectTrigger\n    className={cn(\n      \"text-muted-foreground border-none bg-transparent font-medium shadow-none transition-colors\",\n      \"hover:bg-accent hover:text-foreground aria-expanded:bg-accent aria-expanded:text-foreground\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type PromptInputSelectContentProps = ComponentProps<typeof SelectContent>\n\nexport const PromptInputSelectContent = ({\n  className,\n  ...props\n}: PromptInputSelectContentProps) => (\n  <SelectContent className={cn(className)} {...props} />\n)\n\nexport type PromptInputSelectItemProps = ComponentProps<typeof SelectItem>\n\nexport const PromptInputSelectItem = ({\n  className,\n  ...props\n}: PromptInputSelectItemProps) => (\n  <SelectItem className={cn(className)} {...props} />\n)\n\nexport type PromptInputSelectValueProps = ComponentProps<typeof SelectValue>\n\nexport const PromptInputSelectValue = ({\n  className,\n  ...props\n}: PromptInputSelectValueProps) => (\n  <SelectValue className={cn(className)} {...props} />\n)\n\nexport type PromptInputHoverCardProps = ComponentProps<typeof HoverCard>\n\nexport const PromptInputHoverCard = ({\n  openDelay = 0,\n  closeDelay = 0,\n  ...props\n}: PromptInputHoverCardProps) => (\n  <HoverCard closeDelay={closeDelay} openDelay={openDelay} {...props} />\n)\n\nexport type PromptInputHoverCardTriggerProps = ComponentProps<\n  typeof HoverCardTrigger\n>\n\nexport const PromptInputHoverCardTrigger = (\n  props: PromptInputHoverCardTriggerProps\n) => <HoverCardTrigger {...props} />\n\nexport type PromptInputHoverCardContentProps = ComponentProps<\n  typeof HoverCardContent\n>\n\nexport const PromptInputHoverCardContent = ({\n  align = \"start\",\n  ...props\n}: PromptInputHoverCardContentProps) => (\n  <HoverCardContent align={align} {...props} />\n)\n\nexport type PromptInputTabsListProps = HTMLAttributes<HTMLDivElement>\n\nexport const PromptInputTabsList = ({\n  className,\n  ...props\n}: PromptInputTabsListProps) => <div className={cn(className)} {...props} />\n\nexport type PromptInputTabProps = HTMLAttributes<HTMLDivElement>\n\nexport const PromptInputTab = ({\n  className,\n  ...props\n}: PromptInputTabProps) => <div className={cn(className)} {...props} />\n\nexport type PromptInputTabLabelProps = HTMLAttributes<HTMLHeadingElement>\n\nexport const PromptInputTabLabel = ({\n  className,\n  ...props\n}: PromptInputTabLabelProps) => (\n  // Content provided via children in props\n  // oxlint-disable-next-line eslint-plugin-jsx-a11y(heading-has-content)\n  <h3\n    className={cn(\n      \"text-muted-foreground mb-2 px-3 text-xs font-medium\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type PromptInputTabBodyProps = HTMLAttributes<HTMLDivElement>\n\nexport const PromptInputTabBody = ({\n  className,\n  ...props\n}: PromptInputTabBodyProps) => (\n  <div className={cn(\"space-y-1\", className)} {...props} />\n)\n\nexport type PromptInputTabItemProps = HTMLAttributes<HTMLDivElement>\n\nexport const PromptInputTabItem = ({\n  className,\n  ...props\n}: PromptInputTabItemProps) => (\n  <div\n    className={cn(\n      \"hover:bg-accent flex items-center gap-2 px-3 py-2 text-xs\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type PromptInputCommandProps = ComponentProps<typeof Command>\n\nexport const PromptInputCommand = ({\n  className,\n  ...props\n}: PromptInputCommandProps) => <Command className={cn(className)} {...props} />\n\nexport type PromptInputCommandInputProps = ComponentProps<typeof CommandInput>\n\nexport const PromptInputCommandInput = ({\n  className,\n  ...props\n}: PromptInputCommandInputProps) => (\n  <CommandInput className={cn(className)} {...props} />\n)\n\nexport type PromptInputCommandListProps = ComponentProps<typeof CommandList>\n\nexport const PromptInputCommandList = ({\n  className,\n  ...props\n}: PromptInputCommandListProps) => (\n  <CommandList className={cn(className)} {...props} />\n)\n\nexport type PromptInputCommandEmptyProps = ComponentProps<typeof CommandEmpty>\n\nexport const PromptInputCommandEmpty = ({\n  className,\n  ...props\n}: PromptInputCommandEmptyProps) => (\n  <CommandEmpty className={cn(className)} {...props} />\n)\n\nexport type PromptInputCommandGroupProps = ComponentProps<typeof CommandGroup>\n\nexport const PromptInputCommandGroup = ({\n  className,\n  ...props\n}: PromptInputCommandGroupProps) => (\n  <CommandGroup className={cn(className)} {...props} />\n)\n\nexport type PromptInputCommandItemProps = ComponentProps<typeof CommandItem>\n\nexport const PromptInputCommandItem = ({\n  className,\n  ...props\n}: PromptInputCommandItemProps) => (\n  <CommandItem className={cn(className)} {...props} />\n)\n\nexport type PromptInputCommandSeparatorProps = ComponentProps<\n  typeof CommandSeparator\n>\n\nexport const PromptInputCommandSeparator = ({\n  className,\n  ...props\n}: PromptInputCommandSeparatorProps) => (\n  <CommandSeparator className={cn(className)} {...props} />\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/command.tsx",
          "target": "@components/ai-elements/_ui/command.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ai-elements/_ui/dialog\"\nimport { cn } from \"@/lib/utils\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction Command({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\n        \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandDialog({\n  title = \"Command Palette\",\n  description = \"Search for a command to run...\",\n  children,\n  className,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string\n  description?: string\n  className?: string\n  showCloseButton?: boolean\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent\n        className={cn(\"overflow-hidden p-0\", className)}\n        showCloseButton={showCloseButton}\n      >\n        <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction CommandInput({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div\n      data-slot=\"command-input-wrapper\"\n      className=\"flex h-9 items-center gap-2 border-b px-3\"\n    >\n      <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n      <CommandPrimitive.Input\n        data-slot=\"command-input\"\n        className={cn(\n          \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  )\n}\n\nfunction CommandList({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(\n        \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandEmpty({\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return (\n    <CommandPrimitive.Empty\n      data-slot=\"command-empty\"\n      className=\"py-6 text-center text-sm\"\n      {...props}\n    />\n  )\n}\n\nfunction CommandGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(\"bg-border -mx-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandItem({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"command-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandInput,\n  CommandList,\n  CommandEmpty,\n  CommandGroup,\n  CommandItem,\n  CommandShortcut,\n  CommandSeparator,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/dialog.tsx",
          "target": "@components/ai-elements/_ui/dialog.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as DialogPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Dialog({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n  showCloseButton?: boolean\n}) {\n  return (\n    <DialogPortal data-slot=\"dialog-portal\">\n      <DialogOverlay />\n      <DialogPrimitive.Content\n        data-slot=\"dialog-content\"\n        className={cn(\n          \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <DialogPrimitive.Close\n            data-slot=\"dialog-close\"\n            className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n          >\n            <XIcon />\n            <span className=\"sr-only\">Close</span>\n          </DialogPrimitive.Close>\n        )}\n      </DialogPrimitive.Content>\n    </DialogPortal>\n  )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"text-lg leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/dropdown-menu.tsx",
          "target": "@components/ai-elements/_ui/dropdown-menu.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction DropdownMenu({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  return (\n    <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n  )\n}\n\nfunction DropdownMenuTrigger({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return (\n    <DropdownMenuPrimitive.Trigger\n      data-slot=\"dropdown-menu-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuContent({\n  className,\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPrimitive.Portal>\n      <DropdownMenuPrimitive.Content\n        data-slot=\"dropdown-menu-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n          className\n        )}\n        {...props}\n      />\n    </DropdownMenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return (\n    <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return (\n    <DropdownMenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CircleIcon className=\"size-2 fill-current\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.Label\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return (\n    <DropdownMenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n  inset?: boolean\n}) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPrimitive.SubContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/hover-card.tsx",
          "target": "@components/ai-elements/_ui/hover-card.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { HoverCard as HoverCardPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction HoverCard({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n  return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />\n}\n\nfunction HoverCardTrigger({\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n  return (\n    <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n  )\n}\n\nfunction HoverCardContent({\n  className,\n  align = \"center\",\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n  return (\n    <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n      <HoverCardPrimitive.Content\n        data-slot=\"hover-card-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n          className\n        )}\n        {...props}\n      />\n    </HoverCardPrimitive.Portal>\n  )\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent }\n"
        },
        {
          "path": "components/ai-elements/_ui/input-group.tsx",
          "target": "@components/ai-elements/_ui/input-group.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { Input } from \"@/components/ai-elements/_ui/input\"\nimport { Textarea } from \"@/components/ai-elements/_ui/textarea\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"input-group\"\n      role=\"group\"\n      className={cn(\n        \"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none\",\n        \"h-9 min-w-0 has-[>textarea]:h-auto\",\n\n        // Variants based on alignment.\n        \"has-[>[data-align=inline-start]]:[&>input]:pl-2\",\n        \"has-[>[data-align=inline-end]]:[&>input]:pr-2\",\n        \"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3\",\n        \"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3\",\n\n        // Focus state.\n        \"has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]\",\n\n        // Error state.\n        \"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40\",\n\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupAddonVariants = cva(\n  \"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50\",\n  {\n    variants: {\n      align: {\n        \"inline-start\":\n          \"order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]\",\n        \"inline-end\":\n          \"order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]\",\n        \"block-start\":\n          \"order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5\",\n        \"block-end\":\n          \"order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5\",\n      },\n    },\n    defaultVariants: {\n      align: \"inline-start\",\n    },\n  }\n)\n\nfunction InputGroupAddon({\n  className,\n  align = \"inline-start\",\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"input-group-addon\"\n      data-align={align}\n      className={cn(inputGroupAddonVariants({ align }), className)}\n      onClick={(e) => {\n        if ((e.target as HTMLElement).closest(\"button\")) {\n          return\n        }\n        e.currentTarget.parentElement?.querySelector(\"input\")?.focus()\n      }}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupButtonVariants = cva(\n  \"text-sm shadow-none flex min-w-0 gap-2 items-center\",\n  {\n    variants: {\n      size: {\n        xs: \"h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2\",\n        sm: \"h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5\",\n        \"icon-xs\":\n          \"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0\",\n        \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n      },\n    },\n    defaultVariants: {\n      size: \"xs\",\n    },\n  }\n)\n\nfunction InputGroupButton({\n  className,\n  type = \"button\",\n  variant = \"ghost\",\n  size = \"xs\",\n  ...props\n}: Omit<React.ComponentProps<typeof Button>, \"size\"> &\n  VariantProps<typeof inputGroupButtonVariants>) {\n  return (\n    <Button\n      type={type}\n      data-size={size}\n      variant={variant}\n      className={cn(inputGroupButtonVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      className={cn(\n        \"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupInput({\n  className,\n  ...props\n}: React.ComponentProps<\"input\">) {\n  return (\n    <Input\n      data-slot=\"input-group-control\"\n      className={cn(\n        \"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupTextarea({\n  className,\n  ...props\n}: React.ComponentProps<\"textarea\">) {\n  return (\n    <Textarea\n      data-slot=\"input-group-control\"\n      className={cn(\n        \"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupText,\n  InputGroupInput,\n  InputGroupTextarea,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ai-elements/_ui/input.tsx",
          "target": "@components/ai-elements/_ui/input.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      className={cn(\n        \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n        \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n        \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Input }\n"
        },
        {
          "path": "components/ai-elements/_ui/textarea.tsx",
          "target": "@components/ai-elements/_ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "components/ai-elements/_ui/select.tsx",
          "target": "@components/ai-elements/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"popper\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/spinner.tsx",
          "target": "@components/ai-elements/_ui/spinner.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Loader2Icon } from \"lucide-react\"\n\nfunction Spinner({ className, ...props }: React.ComponentProps<\"svg\">) {\n  return (\n    <Loader2Icon\n      role=\"status\"\n      aria-label=\"Loading\"\n      className={cn(\"size-4 animate-spin\", className)}\n      {...props}\n    />\n  )\n}\n\nexport { Spinner }\n"
        },
        {
          "path": "components/ai-elements/_ui/tooltip.tsx",
          "target": "@components/ai-elements/_ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 0,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-question",
      "type": "registry:block",
      "title": "Ai Elements Question",
      "description": "question",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/question.tsx",
          "target": "@components/ai-elements/question.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { Textarea } from \"@/components/ai-elements/_ui/textarea\"\nimport { cn } from \"@/lib/utils\"\nimport type {\n  ChangeEvent,\n  ComponentProps,\n  FormEvent,\n  HTMLAttributes,\n  MouseEvent,\n  ReactNode,\n} from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useMemo,\n  useState,\n} from \"react\"\n\nexport interface QuestionValue {\n  selectedValues: readonly string[]\n  text: string\n}\n\nexport interface QuestionResponse {\n  selectedValues: readonly string[]\n  text?: string\n}\n\ntype SelectionMode = \"multiple\" | \"single\"\n\ninterface QuestionContextValue {\n  disabled: boolean\n  selectedValues: readonly string[]\n  selectionMode: SelectionMode\n  setText: (text: string) => void\n  text: string\n  toggleValue: (value: string) => void\n}\n\nconst QuestionContext = createContext<QuestionContextValue | null>(null)\n\nconst useQuestion = () => {\n  const context = useContext(QuestionContext)\n\n  if (!context) {\n    throw new Error(\"Question components must be used within Question\")\n  }\n\n  return context\n}\n\nexport type QuestionProps = Omit<\n  ComponentProps<\"form\">,\n  \"defaultValue\" | \"onSubmit\" | \"value\"\n> & {\n  defaultValue?: QuestionValue\n  disabled?: boolean\n  onSubmit?: (\n    response: QuestionResponse,\n    event: FormEvent<HTMLFormElement>\n  ) => void | Promise<void>\n  onValueChange?: (value: QuestionValue) => void\n  selectionMode?: SelectionMode\n  value?: QuestionValue\n}\n\nconst EMPTY_VALUE: QuestionValue = { selectedValues: [], text: \"\" }\n\nconst getSelectedValues = (\n  currentValues: readonly string[],\n  optionValue: string,\n  selectionMode: SelectionMode\n): readonly string[] => {\n  const isSelected = currentValues.includes(optionValue)\n\n  if (selectionMode === \"single\") {\n    return isSelected ? [] : [optionValue]\n  }\n\n  if (isSelected) {\n    return currentValues.filter((item) => item !== optionValue)\n  }\n\n  return [...currentValues, optionValue]\n}\n\nexport const Question = ({\n  children,\n  className,\n  defaultValue = EMPTY_VALUE,\n  disabled = false,\n  onSubmit,\n  onValueChange,\n  selectionMode = \"single\",\n  value: controlledValue,\n  ...props\n}: QuestionProps) => {\n  const [internalValue, setInternalValue] = useState(defaultValue)\n  const value = controlledValue ?? internalValue\n\n  const setValue = useCallback(\n    (nextValue: QuestionValue) => {\n      if (controlledValue === undefined) {\n        setInternalValue(nextValue)\n      }\n      onValueChange?.(nextValue)\n    },\n    [controlledValue, onValueChange]\n  )\n\n  const setText = useCallback(\n    (text: string) => {\n      setValue({ ...value, text })\n    },\n    [setValue, value]\n  )\n\n  const toggleValue = useCallback(\n    (optionValue: string) => {\n      const selectedValues = getSelectedValues(\n        value.selectedValues,\n        optionValue,\n        selectionMode\n      )\n      setValue({ ...value, selectedValues })\n    },\n    [selectionMode, setValue, value]\n  )\n\n  const contextValue = useMemo(\n    () => ({\n      disabled,\n      selectedValues: value.selectedValues,\n      selectionMode,\n      setText,\n      text: value.text,\n      toggleValue,\n    }),\n    [disabled, selectionMode, setText, toggleValue, value]\n  )\n\n  const handleSubmit = useCallback(\n    async (event: FormEvent<HTMLFormElement>) => {\n      event.preventDefault()\n      if (disabled) {\n        return\n      }\n\n      const text = value.text.trim()\n      if (value.selectedValues.length === 0 && text.length === 0) {\n        return\n      }\n\n      await onSubmit?.(\n        {\n          selectedValues: value.selectedValues,\n          text: text.length > 0 ? text : undefined,\n        },\n        event\n      )\n    },\n    [disabled, onSubmit, value]\n  )\n\n  return (\n    <QuestionContext.Provider value={contextValue}>\n      <form\n        className={cn(\n          \"bg-background space-y-4 rounded-lg border p-4\",\n          className\n        )}\n        onSubmit={handleSubmit}\n        {...props}\n      >\n        {children}\n      </form>\n    </QuestionContext.Provider>\n  )\n}\n\nexport type QuestionPromptProps = HTMLAttributes<HTMLParagraphElement>\n\nexport const QuestionPrompt = ({\n  className,\n  ...props\n}: QuestionPromptProps) => (\n  <p className={cn(\"text-sm font-medium\", className)} {...props} />\n)\n\nexport type QuestionDescriptionProps = HTMLAttributes<HTMLParagraphElement>\n\nexport const QuestionDescription = ({\n  className,\n  ...props\n}: QuestionDescriptionProps) => (\n  <p className={cn(\"text-muted-foreground text-sm\", className)} {...props} />\n)\n\nexport type QuestionOptionsProps = HTMLAttributes<HTMLDivElement>\n\nexport const QuestionOptions = ({\n  className,\n  ...props\n}: QuestionOptionsProps) => {\n  const { selectionMode } = useQuestion()\n\n  return (\n    <div\n      className={cn(\"flex flex-wrap gap-2\", className)}\n      role={selectionMode === \"single\" ? \"radiogroup\" : \"group\"}\n      {...props}\n    />\n  )\n}\n\nexport type QuestionOptionProps = Omit<\n  ComponentProps<typeof Button>,\n  \"value\"\n> & {\n  value: string\n}\n\nexport const QuestionOption = ({\n  children,\n  className,\n  disabled,\n  onClick,\n  value,\n  variant,\n  ...props\n}: QuestionOptionProps) => {\n  const question = useQuestion()\n  const isSelected = question.selectedValues.includes(value)\n  const role = question.selectionMode === \"single\" ? \"radio\" : \"checkbox\"\n  const handleClick = useCallback(\n    (event: MouseEvent<HTMLButtonElement>) => {\n      question.toggleValue(value)\n      onClick?.(event)\n    },\n    [onClick, question, value]\n  )\n\n  return (\n    <Button\n      aria-checked={isSelected}\n      className={cn(\"h-auto whitespace-normal\", className)}\n      disabled={question.disabled || disabled}\n      onClick={handleClick}\n      role={role}\n      type=\"button\"\n      variant={variant ?? (isSelected ? \"default\" : \"outline\")}\n      {...props}\n    >\n      {children ?? value}\n    </Button>\n  )\n}\n\nexport type QuestionInputProps = Omit<\n  ComponentProps<typeof Textarea>,\n  \"defaultValue\" | \"value\"\n>\n\nexport const QuestionInput = ({\n  className,\n  disabled,\n  onChange,\n  ...props\n}: QuestionInputProps) => {\n  const question = useQuestion()\n  const handleChange = useCallback(\n    (event: ChangeEvent<HTMLTextAreaElement>) => {\n      question.setText(event.currentTarget.value)\n      onChange?.(event)\n    },\n    [onChange, question]\n  )\n\n  return (\n    <Textarea\n      className={cn(\"min-h-20\", className)}\n      disabled={question.disabled || disabled}\n      onChange={handleChange}\n      value={question.text}\n      {...props}\n    />\n  )\n}\n\nexport type QuestionActionsProps = HTMLAttributes<HTMLDivElement>\n\nexport const QuestionActions = ({\n  className,\n  ...props\n}: QuestionActionsProps) => (\n  <div\n    className={cn(\"flex items-center justify-end gap-2\", className)}\n    {...props}\n  />\n)\n\nexport type QuestionSubmitProps = ComponentProps<typeof Button> & {\n  children?: ReactNode\n}\n\nexport const QuestionSubmit = ({\n  children = \"Submit\",\n  disabled,\n  ...props\n}: QuestionSubmitProps) => {\n  const question = useQuestion()\n  const hasResponse =\n    question.selectedValues.length > 0 || question.text.trim().length > 0\n\n  return (\n    <Button\n      disabled={question.disabled || disabled || !hasResponse}\n      type=\"submit\"\n      {...props}\n    >\n      {children}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/textarea.tsx",
          "target": "@components/ai-elements/_ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-queue",
      "type": "registry:block",
      "title": "Ai Elements Queue",
      "description": "queue",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/queue.tsx",
          "target": "@components/ai-elements/queue.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { ScrollArea } from \"@/components/ai-elements/_ui/scroll-area\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDownIcon, PaperclipIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\n\nexport interface QueueMessagePart {\n  type: string\n  text?: string\n  url?: string\n  filename?: string\n  mediaType?: string\n}\n\nexport interface QueueMessage {\n  id: string\n  parts: QueueMessagePart[]\n}\n\nexport interface QueueTodo {\n  id: string\n  title: string\n  description?: string\n  status?: \"pending\" | \"completed\"\n}\n\nexport type QueueItemProps = ComponentProps<\"li\">\n\nexport const QueueItem = ({ className, ...props }: QueueItemProps) => (\n  <li\n    className={cn(\n      \"group hover:bg-muted flex flex-col gap-1 rounded-md px-3 py-1 text-sm transition-colors\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type QueueItemIndicatorProps = ComponentProps<\"span\"> & {\n  completed?: boolean\n}\n\nexport const QueueItemIndicator = ({\n  completed = false,\n  className,\n  ...props\n}: QueueItemIndicatorProps) => (\n  <span\n    className={cn(\n      \"mt-0.5 inline-block size-2.5 rounded-full border\",\n      completed\n        ? \"border-muted-foreground/20 bg-muted-foreground/10\"\n        : \"border-muted-foreground/50\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type QueueItemContentProps = ComponentProps<\"span\"> & {\n  completed?: boolean\n}\n\nexport const QueueItemContent = ({\n  completed = false,\n  className,\n  ...props\n}: QueueItemContentProps) => (\n  <span\n    className={cn(\n      \"line-clamp-1 grow break-words\",\n      completed\n        ? \"text-muted-foreground/50 line-through\"\n        : \"text-muted-foreground\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type QueueItemDescriptionProps = ComponentProps<\"div\"> & {\n  completed?: boolean\n}\n\nexport const QueueItemDescription = ({\n  completed = false,\n  className,\n  ...props\n}: QueueItemDescriptionProps) => (\n  <div\n    className={cn(\n      \"ml-6 text-xs\",\n      completed\n        ? \"text-muted-foreground/40 line-through\"\n        : \"text-muted-foreground\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type QueueItemActionsProps = ComponentProps<\"div\">\n\nexport const QueueItemActions = ({\n  className,\n  ...props\n}: QueueItemActionsProps) => (\n  <div className={cn(\"flex gap-1\", className)} {...props} />\n)\n\nexport type QueueItemActionProps = Omit<\n  ComponentProps<typeof Button>,\n  \"variant\" | \"size\"\n>\n\nexport const QueueItemAction = ({\n  className,\n  ...props\n}: QueueItemActionProps) => (\n  <Button\n    className={cn(\n      \"text-muted-foreground hover:bg-muted-foreground/10 hover:text-foreground size-auto rounded p-1 opacity-0 transition-opacity group-hover:opacity-100\",\n      className\n    )}\n    size=\"icon\"\n    type=\"button\"\n    variant=\"ghost\"\n    {...props}\n  />\n)\n\nexport type QueueItemAttachmentProps = ComponentProps<\"div\">\n\nexport const QueueItemAttachment = ({\n  className,\n  ...props\n}: QueueItemAttachmentProps) => (\n  <div className={cn(\"mt-1 flex flex-wrap gap-2\", className)} {...props} />\n)\n\nexport type QueueItemImageProps = ComponentProps<\"img\">\n\nexport const QueueItemImage = ({\n  className,\n  ...props\n}: QueueItemImageProps) => (\n  <img\n    alt=\"\"\n    className={cn(\"h-8 w-8 rounded border object-cover\", className)}\n    height={32}\n    width={32}\n    {...props}\n  />\n)\n\nexport type QueueItemFileProps = ComponentProps<\"span\">\n\nexport const QueueItemFile = ({\n  children,\n  className,\n  ...props\n}: QueueItemFileProps) => (\n  <span\n    className={cn(\n      \"bg-muted flex items-center gap-1 rounded border px-2 py-1 text-xs\",\n      className\n    )}\n    {...props}\n  >\n    <PaperclipIcon size={12} />\n    <span className=\"max-w-[100px] truncate\">{children}</span>\n  </span>\n)\n\nexport type QueueListProps = ComponentProps<typeof ScrollArea>\n\nexport const QueueList = ({\n  children,\n  className,\n  ...props\n}: QueueListProps) => (\n  <ScrollArea className={cn(\"mt-2 -mb-1\", className)} {...props}>\n    <div className=\"max-h-40 pr-4\">\n      <ul>{children}</ul>\n    </div>\n  </ScrollArea>\n)\n\n// QueueSection - collapsible section container\nexport type QueueSectionProps = ComponentProps<typeof Collapsible>\n\nexport const QueueSection = ({\n  className,\n  defaultOpen = true,\n  ...props\n}: QueueSectionProps) => (\n  <Collapsible className={cn(className)} defaultOpen={defaultOpen} {...props} />\n)\n\n// QueueSectionTrigger - section header/trigger\nexport type QueueSectionTriggerProps = ComponentProps<\"button\">\n\nexport const QueueSectionTrigger = ({\n  children,\n  className,\n  ...props\n}: QueueSectionTriggerProps) => (\n  <CollapsibleTrigger asChild>\n    <button\n      className={cn(\n        \"group bg-muted/40 text-muted-foreground hover:bg-muted flex w-full items-center justify-between rounded-md px-3 py-2 text-left text-sm font-medium transition-colors\",\n        className\n      )}\n      type=\"button\"\n      {...props}\n    >\n      {children}\n    </button>\n  </CollapsibleTrigger>\n)\n\n// QueueSectionLabel - label content with icon and count\nexport type QueueSectionLabelProps = ComponentProps<\"span\"> & {\n  count?: number\n  label: string\n  icon?: React.ReactNode\n}\n\nexport const QueueSectionLabel = ({\n  count,\n  label,\n  icon,\n  className,\n  ...props\n}: QueueSectionLabelProps) => (\n  <span className={cn(\"flex items-center gap-2\", className)} {...props}>\n    <ChevronDownIcon className=\"size-4 transition-transform group-data-[state=closed]:-rotate-90\" />\n    {icon}\n    <span>\n      {count} {label}\n    </span>\n  </span>\n)\n\n// QueueSectionContent - collapsible content area\nexport type QueueSectionContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const QueueSectionContent = ({\n  className,\n  ...props\n}: QueueSectionContentProps) => (\n  <CollapsibleContent className={cn(className)} {...props} />\n)\n\nexport type QueueProps = ComponentProps<\"div\">\n\nexport const Queue = ({ className, ...props }: QueueProps) => (\n  <div\n    className={cn(\n      \"border-border bg-background flex flex-col gap-2 rounded-xl border px-3 pt-2 pb-2 shadow-xs\",\n      className\n    )}\n    {...props}\n  />\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "components/ai-elements/_ui/scroll-area.tsx",
          "target": "@components/ai-elements/_ui/scroll-area.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ScrollArea as ScrollAreaPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction ScrollArea({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n  return (\n    <ScrollAreaPrimitive.Root\n      data-slot=\"scroll-area\"\n      className={cn(\"relative\", className)}\n      {...props}\n    >\n      <ScrollAreaPrimitive.Viewport\n        data-slot=\"scroll-area-viewport\"\n        className=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n      >\n        {children}\n      </ScrollAreaPrimitive.Viewport>\n      <ScrollBar />\n      <ScrollAreaPrimitive.Corner />\n    </ScrollAreaPrimitive.Root>\n  )\n}\n\nfunction ScrollBar({\n  className,\n  orientation = \"vertical\",\n  ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n  return (\n    <ScrollAreaPrimitive.ScrollAreaScrollbar\n      data-slot=\"scroll-area-scrollbar\"\n      orientation={orientation}\n      className={cn(\n        \"flex touch-none p-px transition-colors select-none\",\n        orientation === \"vertical\" &&\n          \"h-full w-2.5 border-l border-l-transparent\",\n        orientation === \"horizontal\" &&\n          \"h-2.5 flex-col border-t border-t-transparent\",\n        className\n      )}\n      {...props}\n    >\n      <ScrollAreaPrimitive.ScrollAreaThumb\n        data-slot=\"scroll-area-thumb\"\n        className=\"bg-border relative flex-1 rounded-full\"\n      />\n    </ScrollAreaPrimitive.ScrollAreaScrollbar>\n  )\n}\n\nexport { ScrollArea, ScrollBar }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-reasoning",
      "type": "registry:block",
      "title": "Ai Elements Reasoning",
      "description": "reasoning",
      "dependencies": [
        "@radix-ui/react-use-controllable-state@1.2.2",
        "@streamdown/cjk@1.0.2",
        "@streamdown/code@1.1.0",
        "@streamdown/math@1.0.2",
        "@streamdown/mermaid@1.0.2",
        "clsx@^2.1.1",
        "katex@0.16.28",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "radix-ui@1.6.7",
        "streamdown@2.4.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/reasoning.tsx",
          "target": "@components/ai-elements/reasoning.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\"\nimport { cjk } from \"@streamdown/cjk\"\nimport { code } from \"@streamdown/code\"\nimport { math } from \"@streamdown/math\"\nimport { mermaid } from \"@streamdown/mermaid\"\nimport { BrainIcon, ChevronDownIcon } from \"lucide-react\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport {\n  createContext,\n  memo,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport { Streamdown } from \"streamdown\"\nimport { Shimmer } from \"./shimmer\"\n\ninterface ReasoningContextValue {\n  isStreaming: boolean\n  isOpen: boolean\n  setIsOpen: (open: boolean) => void\n  duration: number | undefined\n}\n\nconst ReasoningContext = createContext<ReasoningContextValue | null>(null)\n\nexport const useReasoning = () => {\n  const context = useContext(ReasoningContext)\n  if (!context) {\n    throw new Error(\"Reasoning components must be used within Reasoning\")\n  }\n  return context\n}\n\nexport type ReasoningProps = ComponentProps<typeof Collapsible> & {\n  isStreaming?: boolean\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n  duration?: number\n}\n\nconst AUTO_CLOSE_DELAY = 1000\nconst MS_IN_S = 1000\n\nexport const Reasoning = memo(\n  ({\n    className,\n    isStreaming = false,\n    open,\n    defaultOpen,\n    onOpenChange,\n    duration: durationProp,\n    children,\n    ...props\n  }: ReasoningProps) => {\n    const resolvedDefaultOpen = defaultOpen ?? isStreaming\n    // Track if defaultOpen was explicitly set to false (to prevent auto-open)\n    const isExplicitlyClosed = defaultOpen === false\n\n    const [isOpen, setIsOpen] = useControllableState<boolean>({\n      defaultProp: resolvedDefaultOpen,\n      onChange: onOpenChange,\n      prop: open,\n    })\n    const [duration, setDuration] = useControllableState<number | undefined>({\n      defaultProp: undefined,\n      prop: durationProp,\n    })\n\n    const hasEverStreamedRef = useRef(isStreaming)\n    const [hasAutoClosed, setHasAutoClosed] = useState(false)\n    const startTimeRef = useRef<number | null>(null)\n\n    // Track when streaming starts and compute duration\n    useEffect(() => {\n      if (isStreaming) {\n        hasEverStreamedRef.current = true\n        if (startTimeRef.current === null) {\n          startTimeRef.current = Date.now()\n        }\n      } else if (startTimeRef.current !== null) {\n        setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S))\n        startTimeRef.current = null\n      }\n    }, [isStreaming, setDuration])\n\n    // Auto-open when streaming starts (unless explicitly closed)\n    useEffect(() => {\n      if (isStreaming && !isOpen && !isExplicitlyClosed) {\n        setIsOpen(true)\n      }\n    }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed])\n\n    // Auto-close when streaming ends (once only, and only if it ever streamed)\n    useEffect(() => {\n      if (\n        hasEverStreamedRef.current &&\n        !isStreaming &&\n        isOpen &&\n        !hasAutoClosed\n      ) {\n        const timer = setTimeout(() => {\n          setIsOpen(false)\n          setHasAutoClosed(true)\n        }, AUTO_CLOSE_DELAY)\n\n        return () => clearTimeout(timer)\n      }\n    }, [isStreaming, isOpen, setIsOpen, hasAutoClosed])\n\n    const handleOpenChange = useCallback(\n      (newOpen: boolean) => {\n        setIsOpen(newOpen)\n      },\n      [setIsOpen]\n    )\n\n    const contextValue = useMemo(\n      () => ({ duration, isOpen, isStreaming, setIsOpen }),\n      [duration, isOpen, isStreaming, setIsOpen]\n    )\n\n    return (\n      <ReasoningContext.Provider value={contextValue}>\n        <Collapsible\n          className={cn(\"not-prose mb-4\", className)}\n          onOpenChange={handleOpenChange}\n          open={isOpen}\n          {...props}\n        >\n          {children}\n        </Collapsible>\n      </ReasoningContext.Provider>\n    )\n  }\n)\n\nexport type ReasoningTriggerProps = ComponentProps<\n  typeof CollapsibleTrigger\n> & {\n  getThinkingMessage?: (isStreaming: boolean, duration?: number) => ReactNode\n}\n\nconst defaultGetThinkingMessage = (isStreaming: boolean, duration?: number) => {\n  if (isStreaming || duration === 0) {\n    return <Shimmer duration={1}>Thinking...</Shimmer>\n  }\n  if (duration === undefined) {\n    return <p>Thought for a few seconds</p>\n  }\n  return <p>Thought for {duration} seconds</p>\n}\n\nexport const ReasoningTrigger = memo(\n  ({\n    className,\n    children,\n    getThinkingMessage = defaultGetThinkingMessage,\n    ...props\n  }: ReasoningTriggerProps) => {\n    const { isStreaming, isOpen, duration } = useReasoning()\n\n    return (\n      <CollapsibleTrigger\n        className={cn(\n          \"text-muted-foreground hover:text-foreground flex w-full items-center gap-2 text-sm transition-colors\",\n          className\n        )}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <BrainIcon className=\"size-4\" />\n            {getThinkingMessage(isStreaming, duration)}\n            <ChevronDownIcon\n              className={cn(\n                \"size-4 transition-transform\",\n                isOpen ? \"rotate-180\" : \"rotate-0\"\n              )}\n            />\n          </>\n        )}\n      </CollapsibleTrigger>\n    )\n  }\n)\n\nexport type ReasoningContentProps = ComponentProps<\n  typeof CollapsibleContent\n> & {\n  children: string\n}\n\nconst streamdownPlugins = { cjk, code, math, mermaid }\n\nexport const ReasoningContent = memo(\n  ({ className, children, ...props }: ReasoningContentProps) => (\n    <CollapsibleContent\n      className={cn(\n        \"mt-4 text-sm\",\n        \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground data-[state=closed]:animate-out data-[state=open]:animate-in outline-none\",\n        className\n      )}\n      {...props}\n    >\n      <Streamdown plugins={streamdownPlugins}>{children}</Streamdown>\n    </CollapsibleContent>\n  )\n)\n\nReasoning.displayName = \"Reasoning\"\nReasoningTrigger.displayName = \"ReasoningTrigger\"\nReasoningContent.displayName = \"ReasoningContent\"\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/shimmer.tsx",
          "target": "@components/ai-elements/shimmer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport type { MotionProps } from \"motion/react\"\nimport { motion } from \"motion/react\"\nimport type { CSSProperties, ElementType, JSX } from \"react\"\nimport { memo, useMemo } from \"react\"\n\ntype MotionHTMLProps = MotionProps & Record<string, unknown>\n\n// Cache motion components at module level to avoid creating during render\nconst motionComponentCache = new Map<\n  keyof JSX.IntrinsicElements,\n  React.ComponentType<MotionHTMLProps>\n>()\n\nconst getMotionComponent = (element: keyof JSX.IntrinsicElements) => {\n  let component = motionComponentCache.get(element)\n  if (!component) {\n    component = motion.create(element)\n    motionComponentCache.set(element, component)\n  }\n  return component\n}\n\nexport interface TextShimmerProps {\n  children: string\n  as?: ElementType\n  className?: string\n  duration?: number\n  spread?: number\n}\n\nconst ShimmerComponent = ({\n  children,\n  as: Component = \"p\",\n  className,\n  duration = 2,\n  spread = 2,\n}: TextShimmerProps) => {\n  const MotionComponent = getMotionComponent(\n    Component as keyof JSX.IntrinsicElements\n  )\n\n  const dynamicSpread = useMemo(\n    () => (children?.length ?? 0) * spread,\n    [children, spread]\n  )\n\n  return (\n    <MotionComponent\n      animate={{ backgroundPosition: \"0% center\" }}\n      className={cn(\n        \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n        \"[background-repeat:no-repeat,padding-box] [--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))]\",\n        className\n      )}\n      initial={{ backgroundPosition: \"100% center\" }}\n      style={\n        {\n          \"--spread\": `${dynamicSpread}px`,\n          backgroundImage:\n            \"var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))\",\n        } as CSSProperties\n      }\n      transition={{\n        duration,\n        ease: \"linear\",\n        repeat: Number.POSITIVE_INFINITY,\n      }}\n    >\n      {children}\n    </MotionComponent>\n  )\n}\n\nexport const Shimmer = memo(ShimmerComponent)\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/markdown.css",
          "target": "@components/ai-elements/markdown.css",
          "type": "registry:file",
          "content": "@import \"streamdown/styles.css\";\n@import \"katex/dist/katex.min.css\";\n\n@source \"../../node_modules/streamdown/dist\";\n@source \"../../node_modules/@streamdown/code/dist\";\n@source \"../../node_modules/@streamdown/cjk/dist\";\n@source \"../../node_modules/@streamdown/math/dist\";\n@source \"../../node_modules/@streamdown/mermaid/dist\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-sandbox",
      "type": "registry:block",
      "title": "Ai Elements Sandbox",
      "description": "sandbox",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/sandbox.tsx",
          "target": "@components/ai-elements/sandbox.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport {\n  Tabs,\n  TabsContent,\n  TabsList,\n  TabsTrigger,\n} from \"@/components/ai-elements/_ui/tabs\"\nimport { cn } from \"@/lib/utils\"\nimport type { ToolUIPart } from \"ai\"\nimport { ChevronDownIcon, Code } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport { getStatusBadge } from \"./tool\"\n\nexport type SandboxRootProps = ComponentProps<typeof Collapsible>\n\nexport const Sandbox = ({ className, ...props }: SandboxRootProps) => (\n  <Collapsible\n    className={cn(\n      \"not-prose group mb-4 w-full overflow-hidden rounded-md border\",\n      className\n    )}\n    defaultOpen\n    {...props}\n  />\n)\n\nexport interface SandboxHeaderProps {\n  title?: string\n  state: ToolUIPart[\"state\"]\n  className?: string\n}\n\nexport const SandboxHeader = ({\n  className,\n  title,\n  state,\n  ...props\n}: SandboxHeaderProps) => (\n  <CollapsibleTrigger\n    className={cn(\n      \"flex w-full items-center justify-between gap-4 p-3\",\n      className\n    )}\n    {...props}\n  >\n    <div className=\"flex items-center gap-2\">\n      <Code className=\"text-muted-foreground size-4\" />\n      <span className=\"text-sm font-medium\">{title}</span>\n      {getStatusBadge(state)}\n    </div>\n    <ChevronDownIcon className=\"text-muted-foreground size-4 transition-transform group-data-[state=open]:rotate-180\" />\n  </CollapsibleTrigger>\n)\n\nexport type SandboxContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const SandboxContent = ({\n  className,\n  ...props\n}: SandboxContentProps) => (\n  <CollapsibleContent\n    className={cn(\n      \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 data-[state=closed]:animate-out data-[state=open]:animate-in outline-none\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type SandboxTabsProps = ComponentProps<typeof Tabs>\n\nexport const SandboxTabs = ({ className, ...props }: SandboxTabsProps) => (\n  <Tabs className={cn(\"w-full gap-0\", className)} {...props} />\n)\n\nexport type SandboxTabsBarProps = ComponentProps<\"div\">\n\nexport const SandboxTabsBar = ({\n  className,\n  ...props\n}: SandboxTabsBarProps) => (\n  <div\n    className={cn(\n      \"border-border flex w-full items-center border-t border-b\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type SandboxTabsListProps = ComponentProps<typeof TabsList>\n\nexport const SandboxTabsList = ({\n  className,\n  ...props\n}: SandboxTabsListProps) => (\n  <TabsList\n    className={cn(\"h-auto rounded-none border-0 bg-transparent p-0\", className)}\n    {...props}\n  />\n)\n\nexport type SandboxTabsTriggerProps = ComponentProps<typeof TabsTrigger>\n\nexport const SandboxTabsTrigger = ({\n  className,\n  ...props\n}: SandboxTabsTriggerProps) => (\n  <TabsTrigger\n    className={cn(\n      \"text-muted-foreground data-[state=active]:border-primary data-[state=active]:text-foreground rounded-none border-0 border-b-2 border-transparent px-4 py-2 text-sm font-medium transition-colors data-[state=active]:bg-transparent data-[state=active]:shadow-none\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type SandboxTabContentProps = ComponentProps<typeof TabsContent>\n\nexport const SandboxTabContent = ({\n  className,\n  ...props\n}: SandboxTabContentProps) => (\n  <TabsContent className={cn(\"mt-0 text-sm\", className)} {...props} />\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "components/ai-elements/_ui/tabs.tsx",
          "target": "@components/ai-elements/_ui/tabs.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tabs as TabsPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Tabs({\n  className,\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.Root>) {\n  return (\n    <TabsPrimitive.Root\n      data-slot=\"tabs\"\n      className={cn(\"flex flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction TabsList({\n  className,\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.List>) {\n  return (\n    <TabsPrimitive.List\n      data-slot=\"tabs-list\"\n      className={cn(\n        \"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TabsTrigger({\n  className,\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n  return (\n    <TabsPrimitive.Trigger\n      data-slot=\"tabs-trigger\"\n      className={cn(\n        \"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TabsContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.Content>) {\n  return (\n    <TabsPrimitive.Content\n      data-slot=\"tabs-content\"\n      className={cn(\"flex-1 outline-none\", className)}\n      {...props}\n    />\n  )\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/tool.tsx",
          "target": "@components/ai-elements/tool.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport type { DynamicToolUIPart, ToolUIPart } from \"ai\"\nimport {\n  CheckCircleIcon,\n  ChevronDownIcon,\n  CircleIcon,\n  ClockIcon,\n  WrenchIcon,\n  XCircleIcon,\n} from \"lucide-react\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport { isValidElement } from \"react\"\nimport { CodeBlock } from \"./code-block\"\n\nexport type ToolProps = ComponentProps<typeof Collapsible>\n\nexport const Tool = ({ className, ...props }: ToolProps) => (\n  <Collapsible\n    className={cn(\"group not-prose mb-4 w-full rounded-md border\", className)}\n    {...props}\n  />\n)\n\nexport type ToolPart = ToolUIPart | DynamicToolUIPart\n\nexport type ToolHeaderProps = {\n  title?: string\n  className?: string\n} & (\n  | { type: ToolUIPart[\"type\"]; state: ToolUIPart[\"state\"]; toolName?: never }\n  | {\n      type: DynamicToolUIPart[\"type\"]\n      state: DynamicToolUIPart[\"state\"]\n      toolName: string\n    }\n)\n\nconst statusLabels: Record<ToolPart[\"state\"], string> = {\n  \"approval-requested\": \"Awaiting Approval\",\n  \"approval-responded\": \"Responded\",\n  \"input-available\": \"Running\",\n  \"input-streaming\": \"Pending\",\n  \"output-available\": \"Completed\",\n  \"output-denied\": \"Denied\",\n  \"output-error\": \"Error\",\n}\n\nconst statusIcons: Record<ToolPart[\"state\"], ReactNode> = {\n  \"approval-requested\": <ClockIcon className=\"size-4 text-yellow-600\" />,\n  \"approval-responded\": <CheckCircleIcon className=\"size-4 text-blue-600\" />,\n  \"input-available\": <ClockIcon className=\"size-4 animate-pulse\" />,\n  \"input-streaming\": <CircleIcon className=\"size-4\" />,\n  \"output-available\": <CheckCircleIcon className=\"size-4 text-green-600\" />,\n  \"output-denied\": <XCircleIcon className=\"size-4 text-orange-600\" />,\n  \"output-error\": <XCircleIcon className=\"size-4 text-red-600\" />,\n}\n\nexport const getStatusBadge = (status: ToolPart[\"state\"]) => (\n  <Badge className=\"gap-1.5 rounded-full text-xs\" variant=\"secondary\">\n    {statusIcons[status]}\n    {statusLabels[status]}\n  </Badge>\n)\n\nexport const ToolHeader = ({\n  className,\n  title,\n  type,\n  state,\n  toolName,\n  ...props\n}: ToolHeaderProps) => {\n  const derivedName =\n    type === \"dynamic-tool\" ? toolName : type.split(\"-\").slice(1).join(\"-\")\n\n  return (\n    <CollapsibleTrigger\n      className={cn(\n        \"flex w-full items-center justify-between gap-4 p-3\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"flex items-center gap-2\">\n        <WrenchIcon className=\"text-muted-foreground size-4\" />\n        <span className=\"text-sm font-medium\">{title ?? derivedName}</span>\n        {getStatusBadge(state)}\n      </div>\n      <ChevronDownIcon className=\"text-muted-foreground size-4 transition-transform group-data-[state=open]:rotate-180\" />\n    </CollapsibleTrigger>\n  )\n}\n\nexport type ToolContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const ToolContent = ({ className, ...props }: ToolContentProps) => (\n  <CollapsibleContent\n    className={cn(\n      \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground data-[state=closed]:animate-out data-[state=open]:animate-in space-y-4 p-4 outline-none\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type ToolInputProps = ComponentProps<\"div\"> & {\n  input: ToolPart[\"input\"]\n}\n\nexport const ToolInput = ({ className, input, ...props }: ToolInputProps) => (\n  <div className={cn(\"space-y-2 overflow-hidden\", className)} {...props}>\n    <h4 className=\"text-muted-foreground text-xs font-medium tracking-wide uppercase\">\n      Parameters\n    </h4>\n    <div className=\"bg-muted/50 rounded-md\">\n      <CodeBlock code={JSON.stringify(input, null, 2)} language=\"json\" />\n    </div>\n  </div>\n)\n\nexport type ToolOutputProps = ComponentProps<\"div\"> & {\n  output: ToolPart[\"output\"]\n  errorText: ToolPart[\"errorText\"]\n}\n\nexport const ToolOutput = ({\n  className,\n  output,\n  errorText,\n  ...props\n}: ToolOutputProps) => {\n  if (!(output || errorText)) {\n    return null\n  }\n\n  let Output = <div>{output as ReactNode}</div>\n\n  if (typeof output === \"object\" && !isValidElement(output)) {\n    Output = (\n      <CodeBlock code={JSON.stringify(output, null, 2)} language=\"json\" />\n    )\n  } else if (typeof output === \"string\") {\n    Output = <CodeBlock code={output} language=\"json\" />\n  }\n\n  return (\n    <div className={cn(\"space-y-2\", className)} {...props}>\n      <h4 className=\"text-muted-foreground text-xs font-medium tracking-wide uppercase\">\n        {errorText ? \"Error\" : \"Result\"}\n      </h4>\n      <div\n        className={cn(\n          \"overflow-x-auto rounded-md text-xs [&_table]:w-full\",\n          errorText\n            ? \"bg-destructive/10 text-destructive\"\n            : \"bg-muted/50 text-foreground\"\n        )}\n      >\n        {errorText && <div>{errorText}</div>}\n        {Output}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "components/ai-elements/code-block.tsx",
          "target": "@components/ai-elements/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ai-elements/_ui/select\"\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, CopyIcon } from \"lucide-react\"\nimport type { ComponentProps, CSSProperties, HTMLAttributes } from \"react\"\nimport {\n  createContext,\n  memo,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport type {\n  BundledLanguage,\n  BundledTheme,\n  HighlighterGeneric,\n  ThemedToken,\n} from \"shiki\"\nimport { createHighlighter } from \"shiki\"\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2\nconst isUnderline = (fontStyle: number | undefined) =>\n  // oxlint-disable-next-line eslint(no-bitwise)\n  fontStyle && fontStyle & 4\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n  token: ThemedToken\n  key: string\n}\ninterface KeyedLine {\n  tokens: KeyedToken[]\n  key: string\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n  lines.map((line, lineIdx) => ({\n    key: `line-${lineIdx}`,\n    tokens: line.map((token, tokenIdx) => ({\n      key: `line-${lineIdx}-${tokenIdx}`,\n      token,\n    })),\n  }))\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n  <span\n    className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n    style={\n      {\n        backgroundColor: token.bgColor,\n        color: token.color,\n        fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n        fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n        textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n        ...token.htmlStyle,\n      } as CSSProperties\n    }\n  >\n    {token.content}\n  </span>\n)\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n  \"block\",\n  \"before:content-[counter(line)]\",\n  \"before:inline-block\",\n  \"before:[counter-increment:line]\",\n  \"before:w-8\",\n  \"before:mr-4\",\n  \"before:text-right\",\n  \"before:text-muted-foreground/50\",\n  \"before:font-mono\",\n  \"before:select-none\"\n)\n\n// Line rendering component\nconst LineSpan = ({\n  keyedLine,\n  showLineNumbers,\n}: {\n  keyedLine: KeyedLine\n  showLineNumbers: boolean\n}) => (\n  <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n    {keyedLine.tokens.length === 0\n      ? \"\\n\"\n      : keyedLine.tokens.map(({ token, key }) => (\n          <TokenSpan key={key} token={token} />\n        ))}\n  </span>\n)\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n  code: string\n  language: BundledLanguage\n  showLineNumbers?: boolean\n}\n\ninterface TokenizedCode {\n  tokens: ThemedToken[][]\n  fg: string\n  bg: string\n}\n\ninterface CodeBlockContextType {\n  code: string\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n  code: \"\",\n})\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n  string,\n  Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>()\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>()\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>()\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n  const start = code.slice(0, 100)\n  const end = code.length > 100 ? code.slice(-100) : \"\"\n  return `${language}:${code.length}:${start}:${end}`\n}\n\nconst getHighlighter = (\n  language: BundledLanguage\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n  const cached = highlighterCache.get(language)\n  if (cached) {\n    return cached\n  }\n\n  const highlighterPromise = createHighlighter({\n    langs: [language],\n    themes: [\"github-light\", \"github-dark\"],\n  })\n\n  highlighterCache.set(language, highlighterPromise)\n  return highlighterPromise\n}\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n  bg: \"transparent\",\n  fg: \"inherit\",\n  tokens: code.split(\"\\n\").map((line) =>\n    line === \"\"\n      ? []\n      : [\n          {\n            color: \"inherit\",\n            content: line,\n          } as ThemedToken,\n        ]\n  ),\n})\n\n// Synchronous highlight with callback for async results\nexport const highlightCode = (\n  code: string,\n  language: BundledLanguage,\n  // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-callbacks)\n  callback?: (result: TokenizedCode) => void\n): TokenizedCode | null => {\n  const tokensCacheKey = getTokensCacheKey(code, language)\n\n  // Return cached result if available\n  const cached = tokensCache.get(tokensCacheKey)\n  if (cached) {\n    return cached\n  }\n\n  // Subscribe callback if provided\n  if (callback) {\n    if (!subscribers.has(tokensCacheKey)) {\n      subscribers.set(tokensCacheKey, new Set())\n    }\n    subscribers.get(tokensCacheKey)?.add(callback)\n  }\n\n  // Start highlighting in background - fire-and-forget async pattern\n  getHighlighter(language)\n    // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then)\n    .then((highlighter) => {\n      const availableLangs = highlighter.getLoadedLanguages()\n      const langToUse = availableLangs.includes(language) ? language : \"text\"\n\n      const result = highlighter.codeToTokens(code, {\n        lang: langToUse,\n        themes: {\n          dark: \"github-dark\",\n          light: \"github-light\",\n        },\n      })\n\n      const tokenized: TokenizedCode = {\n        bg: result.bg ?? \"transparent\",\n        fg: result.fg ?? \"inherit\",\n        tokens: result.tokens,\n      }\n\n      // Cache the result\n      tokensCache.set(tokensCacheKey, tokenized)\n\n      // Notify all subscribers\n      const subs = subscribers.get(tokensCacheKey)\n      if (subs) {\n        for (const sub of subs) {\n          sub(tokenized)\n        }\n        subscribers.delete(tokensCacheKey)\n      }\n    })\n    // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then), eslint-plugin-promise(prefer-await-to-callbacks)\n    .catch((error) => {\n      console.error(\"Failed to highlight code:\", error)\n      subscribers.delete(tokensCacheKey)\n    })\n\n  return null\n}\n\nconst CodeBlockBody = memo(\n  ({\n    tokenized,\n    showLineNumbers,\n    className,\n  }: {\n    tokenized: TokenizedCode\n    showLineNumbers: boolean\n    className?: string\n  }) => {\n    const preStyle = useMemo(\n      () => ({\n        backgroundColor: tokenized.bg,\n        color: tokenized.fg,\n      }),\n      [tokenized.bg, tokenized.fg]\n    )\n\n    const keyedLines = useMemo(\n      () => addKeysToTokens(tokenized.tokens),\n      [tokenized.tokens]\n    )\n\n    return (\n      <pre\n        className={cn(\n          \"m-0 p-4 text-sm dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\",\n          className\n        )}\n        style={preStyle}\n      >\n        <code\n          className={cn(\n            \"font-mono text-sm\",\n            showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\"\n          )}\n        >\n          {keyedLines.map((keyedLine) => (\n            <LineSpan\n              key={keyedLine.key}\n              keyedLine={keyedLine}\n              showLineNumbers={showLineNumbers}\n            />\n          ))}\n        </code>\n      </pre>\n    )\n  },\n  (prevProps, nextProps) =>\n    prevProps.tokenized === nextProps.tokenized &&\n    prevProps.showLineNumbers === nextProps.showLineNumbers &&\n    prevProps.className === nextProps.className\n)\n\nCodeBlockBody.displayName = \"CodeBlockBody\"\n\nexport const CodeBlockContainer = ({\n  className,\n  language,\n  style,\n  ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n  <div\n    className={cn(\n      \"group bg-background text-foreground relative w-full overflow-hidden rounded-md border\",\n      className\n    )}\n    data-language={language}\n    style={{\n      containIntrinsicSize: \"auto 200px\",\n      contentVisibility: \"auto\",\n      ...style,\n    }}\n    {...props}\n  />\n)\n\nexport const CodeBlockHeader = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"bg-muted/80 text-muted-foreground flex items-center justify-between border-b px-3 py-2 text-xs\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport const CodeBlockTitle = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport const CodeBlockFilename = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n  <span className={cn(\"font-mono\", className)} {...props}>\n    {children}\n  </span>\n)\n\nexport const CodeBlockActions = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport const CodeBlockContent = ({\n  code,\n  language,\n  showLineNumbers = false,\n}: {\n  code: string\n  language: BundledLanguage\n  showLineNumbers?: boolean\n}) => {\n  // Memoized raw tokens for immediate display\n  const rawTokens = useMemo(() => createRawTokens(code), [code])\n\n  // Synchronous cache lookup — avoids setState in effect for cached results\n  const syncTokens = useMemo(\n    () => highlightCode(code, language) ?? rawTokens,\n    [code, language, rawTokens]\n  )\n\n  // Async highlighting result (populated after shiki loads)\n  const [asyncTokens, setAsyncTokens] = useState<TokenizedCode | null>(null)\n  const asyncKeyRef = useRef({ code, language })\n\n  // Invalidate stale async tokens synchronously during render\n  if (\n    asyncKeyRef.current.code !== code ||\n    asyncKeyRef.current.language !== language\n  ) {\n    asyncKeyRef.current = { code, language }\n    setAsyncTokens(null)\n  }\n\n  useEffect(() => {\n    let cancelled = false\n\n    highlightCode(code, language, (result) => {\n      if (!cancelled) {\n        setAsyncTokens(result)\n      }\n    })\n\n    return () => {\n      cancelled = true\n    }\n  }, [code, language])\n\n  const tokenized = asyncTokens ?? syncTokens\n\n  return (\n    <div className=\"relative overflow-auto\">\n      <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n    </div>\n  )\n}\n\nexport const CodeBlock = ({\n  code,\n  language,\n  showLineNumbers = false,\n  className,\n  children,\n  ...props\n}: CodeBlockProps) => {\n  const contextValue = useMemo(() => ({ code }), [code])\n\n  return (\n    <CodeBlockContext.Provider value={contextValue}>\n      <CodeBlockContainer className={className} language={language} {...props}>\n        {children}\n        <CodeBlockContent\n          code={code}\n          language={language}\n          showLineNumbers={showLineNumbers}\n        />\n      </CodeBlockContainer>\n    </CodeBlockContext.Provider>\n  )\n}\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const CodeBlockCopyButton = ({\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  className,\n  ...props\n}: CodeBlockCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n  const { code } = useContext(CodeBlockContext)\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      if (!isCopied) {\n        await navigator.clipboard.writeText(code)\n        setIsCopied(true)\n        onCopy?.()\n        timeoutRef.current = window.setTimeout(\n          () => setIsCopied(false),\n          timeout\n        )\n      }\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [code, onCopy, onError, timeout, isCopied])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <Button\n      className={cn(\"shrink-0\", className)}\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>\n\nexport const CodeBlockLanguageSelector = (\n  props: CodeBlockLanguageSelectorProps\n) => <Select {...props} />\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<\n  typeof SelectTrigger\n>\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n  className,\n  ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n  <SelectTrigger\n    className={cn(\n      \"h-7 border-none bg-transparent px-2 text-xs shadow-none\",\n      className\n    )}\n    size=\"sm\"\n    {...props}\n  />\n)\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<\n  typeof SelectValue\n>\n\nexport const CodeBlockLanguageSelectorValue = (\n  props: CodeBlockLanguageSelectorValueProps\n) => <SelectValue {...props} />\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<\n  typeof SelectContent\n>\n\nexport const CodeBlockLanguageSelectorContent = ({\n  align = \"end\",\n  ...props\n}: CodeBlockLanguageSelectorContentProps) => (\n  <SelectContent align={align} {...props} />\n)\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<\n  typeof SelectItem\n>\n\nexport const CodeBlockLanguageSelectorItem = (\n  props: CodeBlockLanguageSelectorItemProps\n) => <SelectItem {...props} />\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ai-elements/_ui/select.tsx",
          "target": "@components/ai-elements/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"popper\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-schema-display",
      "type": "registry:block",
      "title": "Ai Elements Schema Display",
      "description": "schema display",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/schema-display.tsx",
          "target": "@components/ai-elements/schema-display.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronRightIcon } from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\nimport { createContext, useContext, useMemo } from \"react\"\n\ntype HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\"\n\ninterface SchemaParameter {\n  name: string\n  type: string\n  required?: boolean\n  description?: string\n  location?: \"path\" | \"query\" | \"header\"\n}\n\ninterface SchemaProperty {\n  name: string\n  type: string\n  required?: boolean\n  description?: string\n  properties?: SchemaProperty[]\n  items?: SchemaProperty\n}\n\ninterface SchemaDisplayContextType {\n  method: HttpMethod\n  path: string\n  description?: string\n  parameters?: SchemaParameter[]\n  requestBody?: SchemaProperty[]\n  responseBody?: SchemaProperty[]\n}\n\nconst SchemaDisplayContext = createContext<SchemaDisplayContextType>({\n  method: \"GET\",\n  path: \"\",\n})\n\nconst methodStyles: Record<HttpMethod, string> = {\n  DELETE: \"bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400\",\n  GET: \"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\",\n  PATCH:\n    \"bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400\",\n  POST: \"bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400\",\n  PUT: \"bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400\",\n}\n\nexport type SchemaDisplayHeaderProps = HTMLAttributes<HTMLDivElement>\n\nexport const SchemaDisplayHeader = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayHeaderProps) => (\n  <div\n    className={cn(\"flex items-center gap-3 border-b px-4 py-3\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type SchemaDisplayMethodProps = ComponentProps<typeof Badge>\n\nexport const SchemaDisplayMethod = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayMethodProps) => {\n  const { method } = useContext(SchemaDisplayContext)\n\n  return (\n    <Badge\n      className={cn(\"font-mono text-xs\", methodStyles[method], className)}\n      variant=\"secondary\"\n      {...props}\n    >\n      {children ?? method}\n    </Badge>\n  )\n}\n\nexport type SchemaDisplayPathProps = Omit<\n  HTMLAttributes<HTMLSpanElement>,\n  \"children\"\n> & { children?: string }\n\nexport const SchemaDisplayPath = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayPathProps) => {\n  const { path } = useContext(SchemaDisplayContext)\n\n  // Highlight path parameters\n  const highlightedPath = path.replaceAll(\n    /\\{([^}]+)\\}/g,\n    '<span class=\"text-blue-600 dark:text-blue-400\">{$1}</span>'\n  )\n\n  return (\n    <span\n      className={cn(\"font-mono text-sm\", className)}\n      // oxlint-disable-next-line eslint-plugin-react(no-danger)\n      dangerouslySetInnerHTML={{ __html: children ?? highlightedPath }}\n      {...props}\n    />\n  )\n}\n\nexport type SchemaDisplayDescriptionProps = HTMLAttributes<HTMLParagraphElement>\n\nexport const SchemaDisplayDescription = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayDescriptionProps) => {\n  const { description } = useContext(SchemaDisplayContext)\n\n  return (\n    <p\n      className={cn(\n        \"text-muted-foreground border-b px-4 py-3 text-sm\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? description}\n    </p>\n  )\n}\n\nexport type SchemaDisplayContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const SchemaDisplayContent = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayContentProps) => (\n  <div className={cn(\"divide-y\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type SchemaDisplayParameterProps = HTMLAttributes<HTMLDivElement> &\n  SchemaParameter\n\nexport const SchemaDisplayParameter = ({\n  name,\n  type,\n  required,\n  description,\n  location,\n  className,\n  ...props\n}: SchemaDisplayParameterProps) => (\n  <div className={cn(\"px-4 py-3 pl-10\", className)} {...props}>\n    <div className=\"flex items-center gap-2\">\n      <span className=\"font-mono text-sm\">{name}</span>\n      <Badge className=\"text-xs\" variant=\"outline\">\n        {type}\n      </Badge>\n      {location && (\n        <Badge className=\"text-xs\" variant=\"secondary\">\n          {location}\n        </Badge>\n      )}\n      {required && (\n        <Badge\n          className=\"bg-red-100 text-xs text-red-700 dark:bg-red-900/30 dark:text-red-400\"\n          variant=\"secondary\"\n        >\n          required\n        </Badge>\n      )}\n    </div>\n    {description && (\n      <p className=\"text-muted-foreground mt-1 text-sm\">{description}</p>\n    )}\n  </div>\n)\n\nexport type SchemaDisplayParametersProps = ComponentProps<typeof Collapsible>\n\nexport const SchemaDisplayParameters = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayParametersProps) => {\n  const { parameters } = useContext(SchemaDisplayContext)\n\n  return (\n    <Collapsible className={cn(className)} defaultOpen {...props}>\n      <CollapsibleTrigger className=\"group hover:bg-muted/50 flex w-full items-center gap-2 px-4 py-3 text-left transition-colors\">\n        <ChevronRightIcon className=\"text-muted-foreground size-4 shrink-0 transition-transform group-data-[state=open]:rotate-90\" />\n        <span className=\"text-sm font-medium\">Parameters</span>\n        <Badge className=\"ml-auto text-xs\" variant=\"secondary\">\n          {parameters?.length}\n        </Badge>\n      </CollapsibleTrigger>\n      <CollapsibleContent>\n        <div className=\"divide-y border-t\">\n          {children ??\n            parameters?.map((param) => (\n              <SchemaDisplayParameter key={param.name} {...param} />\n            ))}\n        </div>\n      </CollapsibleContent>\n    </Collapsible>\n  )\n}\n\nexport type SchemaDisplayPropertyProps = HTMLAttributes<HTMLDivElement> &\n  SchemaProperty & {\n    depth?: number\n  }\n\nexport const SchemaDisplayProperty = ({\n  name,\n  type,\n  required,\n  description,\n  properties,\n  items,\n  depth = 0,\n  className,\n  ...props\n}: SchemaDisplayPropertyProps) => {\n  const hasChildren = properties || items\n  const paddingLeft = 40 + depth * 16\n\n  if (hasChildren) {\n    return (\n      <Collapsible defaultOpen={depth < 2}>\n        <CollapsibleTrigger\n          className={cn(\n            \"group hover:bg-muted/50 flex w-full items-center gap-2 py-3 text-left transition-colors\",\n            className\n          )}\n          style={{ paddingLeft }}\n        >\n          <ChevronRightIcon className=\"text-muted-foreground size-4 shrink-0 transition-transform group-data-[state=open]:rotate-90\" />\n          <span className=\"font-mono text-sm\">{name}</span>\n          <Badge className=\"text-xs\" variant=\"outline\">\n            {type}\n          </Badge>\n          {required && (\n            <Badge\n              className=\"bg-red-100 text-xs text-red-700 dark:bg-red-900/30 dark:text-red-400\"\n              variant=\"secondary\"\n            >\n              required\n            </Badge>\n          )}\n        </CollapsibleTrigger>\n        {description && (\n          <p\n            className=\"text-muted-foreground pb-2 text-sm\"\n            style={{ paddingLeft: paddingLeft + 24 }}\n          >\n            {description}\n          </p>\n        )}\n        <CollapsibleContent>\n          <div className=\"divide-y border-t\">\n            {properties?.map((prop) => (\n              <SchemaDisplayProperty\n                key={prop.name}\n                {...prop}\n                depth={depth + 1}\n              />\n            ))}\n            {items && (\n              <SchemaDisplayProperty\n                {...items}\n                depth={depth + 1}\n                name={`${name}[]`}\n              />\n            )}\n          </div>\n        </CollapsibleContent>\n      </Collapsible>\n    )\n  }\n\n  return (\n    <div\n      className={cn(\"py-3 pr-4\", className)}\n      style={{ paddingLeft }}\n      {...props}\n    >\n      <div className=\"flex items-center gap-2\">\n        {/* Spacer for alignment */}\n        <span className=\"size-4\" />\n        <span className=\"font-mono text-sm\">{name}</span>\n        <Badge className=\"text-xs\" variant=\"outline\">\n          {type}\n        </Badge>\n        {required && (\n          <Badge\n            className=\"bg-red-100 text-xs text-red-700 dark:bg-red-900/30 dark:text-red-400\"\n            variant=\"secondary\"\n          >\n            required\n          </Badge>\n        )}\n      </div>\n      {description && (\n        <p className=\"text-muted-foreground mt-1 pl-6 text-sm\">{description}</p>\n      )}\n    </div>\n  )\n}\n\nexport type SchemaDisplayRequestProps = ComponentProps<typeof Collapsible>\n\nexport const SchemaDisplayRequest = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayRequestProps) => {\n  const { requestBody } = useContext(SchemaDisplayContext)\n\n  return (\n    <Collapsible className={cn(className)} defaultOpen {...props}>\n      <CollapsibleTrigger className=\"group hover:bg-muted/50 flex w-full items-center gap-2 px-4 py-3 text-left transition-colors\">\n        <ChevronRightIcon className=\"text-muted-foreground size-4 shrink-0 transition-transform group-data-[state=open]:rotate-90\" />\n        <span className=\"text-sm font-medium\">Request Body</span>\n      </CollapsibleTrigger>\n      <CollapsibleContent>\n        <div className=\"border-t\">\n          {children ??\n            requestBody?.map((prop) => (\n              <SchemaDisplayProperty key={prop.name} {...prop} depth={0} />\n            ))}\n        </div>\n      </CollapsibleContent>\n    </Collapsible>\n  )\n}\n\nexport type SchemaDisplayResponseProps = ComponentProps<typeof Collapsible>\n\nexport const SchemaDisplayResponse = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayResponseProps) => {\n  const { responseBody } = useContext(SchemaDisplayContext)\n\n  return (\n    <Collapsible className={cn(className)} defaultOpen {...props}>\n      <CollapsibleTrigger className=\"group hover:bg-muted/50 flex w-full items-center gap-2 px-4 py-3 text-left transition-colors\">\n        <ChevronRightIcon className=\"text-muted-foreground size-4 shrink-0 transition-transform group-data-[state=open]:rotate-90\" />\n        <span className=\"text-sm font-medium\">Response</span>\n      </CollapsibleTrigger>\n      <CollapsibleContent>\n        <div className=\"border-t\">\n          {children ??\n            responseBody?.map((prop) => (\n              <SchemaDisplayProperty key={prop.name} {...prop} depth={0} />\n            ))}\n        </div>\n      </CollapsibleContent>\n    </Collapsible>\n  )\n}\n\nexport type SchemaDisplayProps = HTMLAttributes<HTMLDivElement> & {\n  method: HttpMethod\n  path: string\n  description?: string\n  parameters?: SchemaParameter[]\n  requestBody?: SchemaProperty[]\n  responseBody?: SchemaProperty[]\n}\n\nexport const SchemaDisplay = ({\n  method,\n  path,\n  description,\n  parameters,\n  requestBody,\n  responseBody,\n  className,\n  children,\n  ...props\n}: SchemaDisplayProps) => {\n  const contextValue = useMemo(\n    () => ({\n      description,\n      method,\n      parameters,\n      path,\n      requestBody,\n      responseBody,\n    }),\n    [description, method, parameters, path, requestBody, responseBody]\n  )\n\n  return (\n    <SchemaDisplayContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"bg-background overflow-hidden rounded-lg border\",\n          className\n        )}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <SchemaDisplayHeader>\n              <div className=\"flex items-center gap-3\">\n                <SchemaDisplayMethod />\n                <SchemaDisplayPath />\n              </div>\n            </SchemaDisplayHeader>\n            {description && <SchemaDisplayDescription />}\n            <SchemaDisplayContent>\n              {parameters && parameters.length > 0 && (\n                <SchemaDisplayParameters />\n              )}\n              {requestBody && requestBody.length > 0 && (\n                <SchemaDisplayRequest />\n              )}\n              {responseBody && responseBody.length > 0 && (\n                <SchemaDisplayResponse />\n              )}\n            </SchemaDisplayContent>\n          </>\n        )}\n      </div>\n    </SchemaDisplayContext.Provider>\n  )\n}\n\nexport type SchemaDisplayBodyProps = HTMLAttributes<HTMLDivElement>\n\nexport const SchemaDisplayBody = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayBodyProps) => (\n  <div className={cn(\"divide-y\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type SchemaDisplayExampleProps = HTMLAttributes<HTMLPreElement>\n\nexport const SchemaDisplayExample = ({\n  className,\n  children,\n  ...props\n}: SchemaDisplayExampleProps) => (\n  <pre\n    className={cn(\n      \"bg-muted mx-4 mb-4 overflow-auto rounded-md p-4 font-mono text-sm\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </pre>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-shimmer",
      "type": "registry:block",
      "title": "Ai Elements Shimmer",
      "description": "shimmer",
      "dependencies": [
        "clsx@^2.1.1",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/shimmer.tsx",
          "target": "@components/ai-elements/shimmer.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport type { MotionProps } from \"motion/react\"\nimport { motion } from \"motion/react\"\nimport type { CSSProperties, ElementType, JSX } from \"react\"\nimport { memo, useMemo } from \"react\"\n\ntype MotionHTMLProps = MotionProps & Record<string, unknown>\n\n// Cache motion components at module level to avoid creating during render\nconst motionComponentCache = new Map<\n  keyof JSX.IntrinsicElements,\n  React.ComponentType<MotionHTMLProps>\n>()\n\nconst getMotionComponent = (element: keyof JSX.IntrinsicElements) => {\n  let component = motionComponentCache.get(element)\n  if (!component) {\n    component = motion.create(element)\n    motionComponentCache.set(element, component)\n  }\n  return component\n}\n\nexport interface TextShimmerProps {\n  children: string\n  as?: ElementType\n  className?: string\n  duration?: number\n  spread?: number\n}\n\nconst ShimmerComponent = ({\n  children,\n  as: Component = \"p\",\n  className,\n  duration = 2,\n  spread = 2,\n}: TextShimmerProps) => {\n  const MotionComponent = getMotionComponent(\n    Component as keyof JSX.IntrinsicElements\n  )\n\n  const dynamicSpread = useMemo(\n    () => (children?.length ?? 0) * spread,\n    [children, spread]\n  )\n\n  return (\n    <MotionComponent\n      animate={{ backgroundPosition: \"0% center\" }}\n      className={cn(\n        \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n        \"[background-repeat:no-repeat,padding-box] [--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))]\",\n        className\n      )}\n      initial={{ backgroundPosition: \"100% center\" }}\n      style={\n        {\n          \"--spread\": `${dynamicSpread}px`,\n          backgroundImage:\n            \"var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))\",\n        } as CSSProperties\n      }\n      transition={{\n        duration,\n        ease: \"linear\",\n        repeat: Number.POSITIVE_INFINITY,\n      }}\n    >\n      {children}\n    </MotionComponent>\n  )\n}\n\nexport const Shimmer = memo(ShimmerComponent)\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-snippet",
      "type": "registry:block",
      "title": "Ai Elements Snippet",
      "description": "snippet",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/snippet.tsx",
          "target": "@components/ai-elements/snippet.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupInput,\n  InputGroupText,\n} from \"@/components/ai-elements/_ui/input-group\"\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, CopyIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\ninterface SnippetContextType {\n  code: string\n}\n\nconst SnippetContext = createContext<SnippetContextType>({\n  code: \"\",\n})\n\nexport type SnippetProps = ComponentProps<typeof InputGroup> & {\n  code: string\n}\n\nexport const Snippet = ({\n  code,\n  className,\n  children,\n  ...props\n}: SnippetProps) => {\n  const contextValue = useMemo(() => ({ code }), [code])\n\n  return (\n    <SnippetContext.Provider value={contextValue}>\n      <InputGroup className={cn(\"font-mono\", className)} {...props}>\n        {children}\n      </InputGroup>\n    </SnippetContext.Provider>\n  )\n}\n\nexport type SnippetAddonProps = ComponentProps<typeof InputGroupAddon>\n\nexport const SnippetAddon = (props: SnippetAddonProps) => (\n  <InputGroupAddon {...props} />\n)\n\nexport type SnippetTextProps = ComponentProps<typeof InputGroupText>\n\nexport const SnippetText = ({ className, ...props }: SnippetTextProps) => (\n  <InputGroupText\n    className={cn(\"text-muted-foreground pl-2 font-normal\", className)}\n    {...props}\n  />\n)\n\nexport type SnippetInputProps = Omit<\n  ComponentProps<typeof InputGroupInput>,\n  \"readOnly\" | \"value\"\n>\n\nexport const SnippetInput = ({ className, ...props }: SnippetInputProps) => {\n  const { code } = useContext(SnippetContext)\n\n  return (\n    <InputGroupInput\n      className={cn(\"text-foreground\", className)}\n      readOnly\n      value={code}\n      {...props}\n    />\n  )\n}\n\nexport type SnippetCopyButtonProps = ComponentProps<typeof InputGroupButton> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const SnippetCopyButton = ({\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  className,\n  ...props\n}: SnippetCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n  const { code } = useContext(SnippetContext)\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      if (!isCopied) {\n        await navigator.clipboard.writeText(code)\n        setIsCopied(true)\n        onCopy?.()\n        timeoutRef.current = window.setTimeout(\n          () => setIsCopied(false),\n          timeout\n        )\n      }\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [code, onCopy, onError, timeout, isCopied])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <InputGroupButton\n      aria-label=\"Copy\"\n      className={className}\n      onClick={copyToClipboard}\n      size=\"icon-sm\"\n      title=\"Copy\"\n      {...props}\n    >\n      {children ?? <Icon className=\"size-3.5\" size={14} />}\n    </InputGroupButton>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/input-group.tsx",
          "target": "@components/ai-elements/_ui/input-group.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { Input } from \"@/components/ai-elements/_ui/input\"\nimport { Textarea } from \"@/components/ai-elements/_ui/textarea\"\nimport { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"input-group\"\n      role=\"group\"\n      className={cn(\n        \"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none\",\n        \"h-9 min-w-0 has-[>textarea]:h-auto\",\n\n        // Variants based on alignment.\n        \"has-[>[data-align=inline-start]]:[&>input]:pl-2\",\n        \"has-[>[data-align=inline-end]]:[&>input]:pr-2\",\n        \"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3\",\n        \"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3\",\n\n        // Focus state.\n        \"has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]\",\n\n        // Error state.\n        \"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40\",\n\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupAddonVariants = cva(\n  \"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50\",\n  {\n    variants: {\n      align: {\n        \"inline-start\":\n          \"order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]\",\n        \"inline-end\":\n          \"order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]\",\n        \"block-start\":\n          \"order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5\",\n        \"block-end\":\n          \"order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5\",\n      },\n    },\n    defaultVariants: {\n      align: \"inline-start\",\n    },\n  }\n)\n\nfunction InputGroupAddon({\n  className,\n  align = \"inline-start\",\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"input-group-addon\"\n      data-align={align}\n      className={cn(inputGroupAddonVariants({ align }), className)}\n      onClick={(e) => {\n        if ((e.target as HTMLElement).closest(\"button\")) {\n          return\n        }\n        e.currentTarget.parentElement?.querySelector(\"input\")?.focus()\n      }}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupButtonVariants = cva(\n  \"text-sm shadow-none flex min-w-0 gap-2 items-center\",\n  {\n    variants: {\n      size: {\n        xs: \"h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2\",\n        sm: \"h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5\",\n        \"icon-xs\":\n          \"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0\",\n        \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n      },\n    },\n    defaultVariants: {\n      size: \"xs\",\n    },\n  }\n)\n\nfunction InputGroupButton({\n  className,\n  type = \"button\",\n  variant = \"ghost\",\n  size = \"xs\",\n  ...props\n}: Omit<React.ComponentProps<typeof Button>, \"size\"> &\n  VariantProps<typeof inputGroupButtonVariants>) {\n  return (\n    <Button\n      type={type}\n      data-size={size}\n      variant={variant}\n      className={cn(inputGroupButtonVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      className={cn(\n        \"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupInput({\n  className,\n  ...props\n}: React.ComponentProps<\"input\">) {\n  return (\n    <Input\n      data-slot=\"input-group-control\"\n      className={cn(\n        \"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupTextarea({\n  className,\n  ...props\n}: React.ComponentProps<\"textarea\">) {\n  return (\n    <Textarea\n      data-slot=\"input-group-control\"\n      className={cn(\n        \"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupText,\n  InputGroupInput,\n  InputGroupTextarea,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/input.tsx",
          "target": "@components/ai-elements/_ui/input.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      className={cn(\n        \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n        \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n        \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Input }\n"
        },
        {
          "path": "components/ai-elements/_ui/textarea.tsx",
          "target": "@components/ai-elements/_ui/textarea.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-sources",
      "type": "registry:block",
      "title": "Ai Elements Sources",
      "description": "sources",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/sources.tsx",
          "target": "@components/ai-elements/sources.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { BookIcon, ChevronDownIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\n\nexport type SourcesProps = ComponentProps<\"div\">\n\nexport const Sources = ({ className, ...props }: SourcesProps) => (\n  <Collapsible\n    className={cn(\"not-prose text-primary mb-4 text-xs\", className)}\n    {...props}\n  />\n)\n\nexport type SourcesTriggerProps = ComponentProps<typeof CollapsibleTrigger> & {\n  count: number\n}\n\nexport const SourcesTrigger = ({\n  className,\n  count,\n  children,\n  ...props\n}: SourcesTriggerProps) => (\n  <CollapsibleTrigger\n    className={cn(\"flex items-center gap-2\", className)}\n    {...props}\n  >\n    {children ?? (\n      <>\n        <p className=\"font-medium\">Used {count} sources</p>\n        <ChevronDownIcon className=\"h-4 w-4\" />\n      </>\n    )}\n  </CollapsibleTrigger>\n)\n\nexport type SourcesContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const SourcesContent = ({\n  className,\n  ...props\n}: SourcesContentProps) => (\n  <CollapsibleContent\n    className={cn(\n      \"mt-3 flex w-fit flex-col gap-2\",\n      \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 data-[state=closed]:animate-out data-[state=open]:animate-in outline-none\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type SourceProps = ComponentProps<\"a\">\n\nexport const Source = ({ href, title, children, ...props }: SourceProps) => (\n  <a\n    className=\"flex items-center gap-2\"\n    href={href}\n    rel=\"noreferrer\"\n    target=\"_blank\"\n    {...props}\n  >\n    {children ?? (\n      <>\n        <BookIcon className=\"h-4 w-4\" />\n        <span className=\"block font-medium\">{title}</span>\n      </>\n    )}\n  </a>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-speech-input",
      "type": "registry:block",
      "title": "Ai Elements Speech Input",
      "description": "speech input",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/speech-input.tsx",
          "target": "@components/ai-elements/speech-input.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { Spinner } from \"@/components/ai-elements/_ui/spinner\"\nimport { cn } from \"@/lib/utils\"\nimport { MicIcon, SquareIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\ninterface SpeechRecognition extends EventTarget {\n  continuous: boolean\n  interimResults: boolean\n  lang: string\n  start(): void\n  stop(): void\n  onstart: ((this: SpeechRecognition, ev: Event) => void) | null\n  onend: ((this: SpeechRecognition, ev: Event) => void) | null\n  onresult:\n    | ((this: SpeechRecognition, ev: SpeechRecognitionEvent) => void)\n    | null\n  onerror:\n    | ((this: SpeechRecognition, ev: SpeechRecognitionErrorEvent) => void)\n    | null\n}\n\ninterface SpeechRecognitionEvent extends Event {\n  results: SpeechRecognitionResultList\n  resultIndex: number\n}\n\ninterface SpeechRecognitionResultList {\n  readonly length: number\n  item(index: number): SpeechRecognitionResult\n  [index: number]: SpeechRecognitionResult\n}\n\ninterface SpeechRecognitionResult {\n  readonly length: number\n  item(index: number): SpeechRecognitionAlternative\n  [index: number]: SpeechRecognitionAlternative\n  isFinal: boolean\n}\n\ninterface SpeechRecognitionAlternative {\n  transcript: string\n  confidence: number\n}\n\ninterface SpeechRecognitionErrorEvent extends Event {\n  error: string\n}\n\ndeclare global {\n  interface Window {\n    SpeechRecognition: new () => SpeechRecognition\n    webkitSpeechRecognition: new () => SpeechRecognition\n  }\n}\n\ntype SpeechInputMode = \"speech-recognition\" | \"media-recorder\" | \"none\"\n\nexport type SpeechInputProps = ComponentProps<typeof Button> & {\n  onTranscriptionChange?: (text: string) => void\n  /**\n   * Callback for when audio is recorded using MediaRecorder fallback.\n   * This is called in browsers that don't support the Web Speech API (Firefox, Safari).\n   * The callback receives an audio Blob that should be sent to a transcription service.\n   * Return the transcribed text, which will be passed to onTranscriptionChange.\n   */\n  onAudioRecorded?: (audioBlob: Blob) => Promise<string>\n  lang?: string\n}\n\nconst detectSpeechInputMode = (): SpeechInputMode => {\n  if (typeof window === \"undefined\") {\n    return \"none\"\n  }\n\n  if (\"SpeechRecognition\" in window || \"webkitSpeechRecognition\" in window) {\n    return \"speech-recognition\"\n  }\n\n  if (\"MediaRecorder\" in window && \"mediaDevices\" in navigator) {\n    return \"media-recorder\"\n  }\n\n  return \"none\"\n}\n\nexport const SpeechInput = ({\n  className,\n  onTranscriptionChange,\n  onAudioRecorded,\n  lang = \"en-US\",\n  ...props\n}: SpeechInputProps) => {\n  const [isListening, setIsListening] = useState(false)\n  const [isProcessing, setIsProcessing] = useState(false)\n  const [mode] = useState<SpeechInputMode>(detectSpeechInputMode)\n  const [isRecognitionReady, setIsRecognitionReady] = useState(false)\n  const recognitionRef = useRef<SpeechRecognition | null>(null)\n  const mediaRecorderRef = useRef<MediaRecorder | null>(null)\n  const streamRef = useRef<MediaStream | null>(null)\n  const audioChunksRef = useRef<Blob[]>([])\n  const onTranscriptionChangeRef = useRef<\n    SpeechInputProps[\"onTranscriptionChange\"]\n  >(onTranscriptionChange)\n  const onAudioRecordedRef =\n    useRef<SpeechInputProps[\"onAudioRecorded\"]>(onAudioRecorded)\n\n  // Keep refs in sync\n  onTranscriptionChangeRef.current = onTranscriptionChange\n  onAudioRecordedRef.current = onAudioRecorded\n\n  // Initialize Speech Recognition when mode is speech-recognition\n  useEffect(() => {\n    if (mode !== \"speech-recognition\") {\n      return\n    }\n\n    const SpeechRecognition =\n      window.SpeechRecognition || window.webkitSpeechRecognition\n    const speechRecognition = new SpeechRecognition()\n\n    speechRecognition.continuous = true\n    speechRecognition.interimResults = true\n    speechRecognition.lang = lang\n\n    const handleStart = () => {\n      setIsListening(true)\n    }\n\n    const handleEnd = () => {\n      setIsListening(false)\n    }\n\n    const handleResult = (event: Event) => {\n      const speechEvent = event as SpeechRecognitionEvent\n      let finalTranscript = \"\"\n\n      for (\n        let i = speechEvent.resultIndex;\n        i < speechEvent.results.length;\n        i += 1\n      ) {\n        const result = speechEvent.results[i]\n        if (result.isFinal) {\n          finalTranscript += result[0]?.transcript ?? \"\"\n        }\n      }\n\n      if (finalTranscript) {\n        onTranscriptionChangeRef.current?.(finalTranscript)\n      }\n    }\n\n    const handleError = () => {\n      setIsListening(false)\n    }\n\n    speechRecognition.addEventListener(\"start\", handleStart)\n    speechRecognition.addEventListener(\"end\", handleEnd)\n    speechRecognition.addEventListener(\"result\", handleResult)\n    speechRecognition.addEventListener(\"error\", handleError)\n\n    recognitionRef.current = speechRecognition\n    setIsRecognitionReady(true)\n\n    return () => {\n      speechRecognition.removeEventListener(\"start\", handleStart)\n      speechRecognition.removeEventListener(\"end\", handleEnd)\n      speechRecognition.removeEventListener(\"result\", handleResult)\n      speechRecognition.removeEventListener(\"error\", handleError)\n      speechRecognition.stop()\n      recognitionRef.current = null\n      setIsRecognitionReady(false)\n    }\n  }, [mode, lang])\n\n  // Cleanup MediaRecorder and stream on unmount\n  useEffect(\n    () => () => {\n      if (mediaRecorderRef.current?.state === \"recording\") {\n        mediaRecorderRef.current.stop()\n      }\n      if (streamRef.current) {\n        for (const track of streamRef.current.getTracks()) {\n          track.stop()\n        }\n      }\n    },\n    []\n  )\n\n  // Start MediaRecorder recording\n  const startMediaRecorder = useCallback(async () => {\n    if (!onAudioRecordedRef.current) {\n      return\n    }\n\n    try {\n      const stream = await navigator.mediaDevices.getUserMedia({ audio: true })\n      streamRef.current = stream\n      const mediaRecorder = new MediaRecorder(stream)\n      audioChunksRef.current = []\n\n      const handleDataAvailable = (event: BlobEvent) => {\n        if (event.data.size > 0) {\n          audioChunksRef.current.push(event.data)\n        }\n      }\n\n      const handleStop = async () => {\n        for (const track of stream.getTracks()) {\n          track.stop()\n        }\n        streamRef.current = null\n\n        const audioBlob = new Blob(audioChunksRef.current, {\n          type: \"audio/webm\",\n        })\n\n        if (audioBlob.size > 0 && onAudioRecordedRef.current) {\n          setIsProcessing(true)\n          try {\n            const transcript = await onAudioRecordedRef.current(audioBlob)\n            if (transcript) {\n              onTranscriptionChangeRef.current?.(transcript)\n            }\n          } catch {\n            // Error handling delegated to the onAudioRecorded caller\n          } finally {\n            setIsProcessing(false)\n          }\n        }\n      }\n\n      const handleError = () => {\n        setIsListening(false)\n        for (const track of stream.getTracks()) {\n          track.stop()\n        }\n        streamRef.current = null\n      }\n\n      mediaRecorder.addEventListener(\"dataavailable\", handleDataAvailable)\n      mediaRecorder.addEventListener(\"stop\", handleStop)\n      mediaRecorder.addEventListener(\"error\", handleError)\n\n      mediaRecorderRef.current = mediaRecorder\n      mediaRecorder.start()\n      setIsListening(true)\n    } catch {\n      setIsListening(false)\n    }\n  }, [])\n\n  // Stop MediaRecorder recording\n  const stopMediaRecorder = useCallback(() => {\n    if (mediaRecorderRef.current?.state === \"recording\") {\n      mediaRecorderRef.current.stop()\n    }\n    setIsListening(false)\n  }, [])\n\n  const toggleListening = useCallback(() => {\n    if (mode === \"speech-recognition\" && recognitionRef.current) {\n      if (isListening) {\n        recognitionRef.current.stop()\n      } else {\n        recognitionRef.current.start()\n      }\n    } else if (mode === \"media-recorder\") {\n      if (isListening) {\n        stopMediaRecorder()\n      } else {\n        startMediaRecorder()\n      }\n    }\n  }, [mode, isListening, startMediaRecorder, stopMediaRecorder])\n\n  // Determine if button should be disabled\n  const isDisabled =\n    mode === \"none\" ||\n    (mode === \"speech-recognition\" && !isRecognitionReady) ||\n    (mode === \"media-recorder\" && !onAudioRecorded) ||\n    isProcessing\n\n  return (\n    <div className=\"relative inline-flex items-center justify-center\">\n      {/* Animated pulse rings */}\n      {isListening &&\n        [0, 1, 2].map((index) => (\n          <div\n            className=\"absolute inset-0 animate-ping rounded-full border-2 border-red-400/30\"\n            key={index}\n            style={{\n              animationDelay: `${index * 0.3}s`,\n              animationDuration: \"2s\",\n            }}\n          />\n        ))}\n\n      {/* Main record button */}\n      <Button\n        className={cn(\n          \"relative z-10 rounded-full transition-all duration-300\",\n          isListening\n            ? \"bg-destructive hover:bg-destructive/80 text-white hover:text-white\"\n            : \"bg-primary text-primary-foreground hover:bg-primary/80 hover:text-primary-foreground\",\n          className\n        )}\n        disabled={isDisabled}\n        onClick={toggleListening}\n        {...props}\n      >\n        {isProcessing && <Spinner />}\n        {!isProcessing && isListening && <SquareIcon className=\"size-4\" />}\n        {!(isProcessing || isListening) && <MicIcon className=\"size-4\" />}\n      </Button>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/spinner.tsx",
          "target": "@components/ai-elements/_ui/spinner.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Loader2Icon } from \"lucide-react\"\n\nfunction Spinner({ className, ...props }: React.ComponentProps<\"svg\">) {\n  return (\n    <Loader2Icon\n      role=\"status\"\n      aria-label=\"Loading\"\n      className={cn(\"size-4 animate-spin\", className)}\n      {...props}\n    />\n  )\n}\n\nexport { Spinner }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-stack-trace",
      "type": "registry:block",
      "title": "Ai Elements Stack Trace",
      "description": "stack trace",
      "dependencies": [
        "@radix-ui/react-use-controllable-state@1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/stack-trace.tsx",
          "target": "@components/ai-elements/stack-trace.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\"\nimport {\n  AlertTriangleIcon,\n  CheckIcon,\n  ChevronDownIcon,\n  CopyIcon,\n} from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\nimport {\n  createContext,\n  memo,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\n// Regex patterns for parsing stack traces\nconst STACK_FRAME_WITH_PARENS_REGEX = /^at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/\nconst STACK_FRAME_WITHOUT_FN_REGEX = /^at\\s+(.+):(\\d+):(\\d+)$/\nconst ERROR_TYPE_REGEX = /^(\\w+Error|Error):\\s*(.*)$/\nconst AT_PREFIX_REGEX = /^at\\s+/\n\ninterface StackFrame {\n  raw: string\n  functionName: string | null\n  filePath: string | null\n  lineNumber: number | null\n  columnNumber: number | null\n  isInternal: boolean\n}\n\ninterface ParsedStackTrace {\n  errorType: string | null\n  errorMessage: string\n  frames: StackFrame[]\n  raw: string\n}\n\ninterface StackTraceContextValue {\n  trace: ParsedStackTrace\n  raw: string\n  isOpen: boolean\n  setIsOpen: (open: boolean) => void\n  onFilePathClick?: (filePath: string, line?: number, column?: number) => void\n}\n\nconst StackTraceContext = createContext<StackTraceContextValue | null>(null)\n\nconst useStackTrace = () => {\n  const context = useContext(StackTraceContext)\n  if (!context) {\n    throw new Error(\"StackTrace components must be used within StackTrace\")\n  }\n  return context\n}\n\nconst parseStackFrame = (line: string): StackFrame => {\n  const trimmed = line.trim()\n\n  // Pattern: at functionName (filePath:line:column)\n  const withParensMatch = trimmed.match(STACK_FRAME_WITH_PARENS_REGEX)\n  if (withParensMatch) {\n    const [, functionName, filePath, lineNum, colNum] = withParensMatch\n    const isInternal =\n      filePath.includes(\"node_modules\") ||\n      filePath.startsWith(\"node:\") ||\n      filePath.includes(\"internal/\")\n    return {\n      columnNumber: colNum ? Number.parseInt(colNum, 10) : null,\n      filePath: filePath ?? null,\n      functionName: functionName ?? null,\n      isInternal,\n      lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null,\n      raw: trimmed,\n    }\n  }\n\n  // Pattern: at filePath:line:column (no function name)\n  const withoutFnMatch = trimmed.match(STACK_FRAME_WITHOUT_FN_REGEX)\n  if (withoutFnMatch) {\n    const [, filePath, lineNum, colNum] = withoutFnMatch\n    const isInternal =\n      (filePath?.includes(\"node_modules\") ?? false) ||\n      (filePath?.startsWith(\"node:\") ?? false) ||\n      (filePath?.includes(\"internal/\") ?? false)\n    return {\n      columnNumber: colNum ? Number.parseInt(colNum, 10) : null,\n      filePath: filePath ?? null,\n      functionName: null,\n      isInternal,\n      lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null,\n      raw: trimmed,\n    }\n  }\n\n  // Fallback: unparseable line\n  return {\n    columnNumber: null,\n    filePath: null,\n    functionName: null,\n    isInternal: trimmed.includes(\"node_modules\") || trimmed.includes(\"node:\"),\n    lineNumber: null,\n    raw: trimmed,\n  }\n}\n\nconst parseStackTrace = (trace: string): ParsedStackTrace => {\n  const lines = trace.split(\"\\n\").filter((line) => line.trim())\n\n  if (lines.length === 0) {\n    return {\n      errorMessage: trace,\n      errorType: null,\n      frames: [],\n      raw: trace,\n    }\n  }\n\n  const firstLine = lines[0].trim()\n  let errorType: string | null = null\n  let errorMessage = firstLine\n\n  // Try to extract error type from \"ErrorType: message\" format\n  const errorMatch = firstLine.match(ERROR_TYPE_REGEX)\n  if (errorMatch) {\n    const [, type, msg] = errorMatch\n    errorType = type\n    errorMessage = msg || \"\"\n  }\n\n  // Parse stack frames (lines starting with \"at\")\n  const frames = lines\n    .slice(1)\n    .filter((line) => line.trim().startsWith(\"at \"))\n    .map(parseStackFrame)\n\n  return {\n    errorMessage,\n    errorType,\n    frames,\n    raw: trace,\n  }\n}\n\nexport type StackTraceProps = ComponentProps<\"div\"> & {\n  trace: string\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n  onFilePathClick?: (filePath: string, line?: number, column?: number) => void\n}\n\nexport const StackTrace = memo(\n  ({\n    trace,\n    className,\n    open,\n    defaultOpen = false,\n    onOpenChange,\n    onFilePathClick,\n    children,\n    ...props\n  }: StackTraceProps) => {\n    const [isOpen, setIsOpen] = useControllableState({\n      defaultProp: defaultOpen,\n      onChange: onOpenChange,\n      prop: open,\n    })\n\n    const parsedTrace = useMemo(() => parseStackTrace(trace), [trace])\n\n    const contextValue = useMemo(\n      () => ({\n        isOpen,\n        onFilePathClick,\n        raw: trace,\n        setIsOpen,\n        trace: parsedTrace,\n      }),\n      [parsedTrace, trace, isOpen, setIsOpen, onFilePathClick]\n    )\n\n    return (\n      <StackTraceContext.Provider value={contextValue}>\n        <div\n          className={cn(\n            \"not-prose bg-background w-full overflow-hidden rounded-lg border font-mono text-sm\",\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </div>\n      </StackTraceContext.Provider>\n    )\n  }\n)\n\nexport type StackTraceHeaderProps = ComponentProps<typeof CollapsibleTrigger>\n\nexport const StackTraceHeader = memo(\n  ({ className, children, ...props }: StackTraceHeaderProps) => {\n    const { isOpen, setIsOpen } = useStackTrace()\n\n    return (\n      <Collapsible onOpenChange={setIsOpen} open={isOpen}>\n        <CollapsibleTrigger asChild {...props}>\n          <div\n            className={cn(\n              \"hover:bg-muted/50 flex w-full cursor-pointer items-center gap-3 p-3 text-left transition-colors\",\n              className\n            )}\n          >\n            {children}\n          </div>\n        </CollapsibleTrigger>\n      </Collapsible>\n    )\n  }\n)\n\nexport type StackTraceErrorProps = ComponentProps<\"div\">\n\nexport const StackTraceError = memo(\n  ({ className, children, ...props }: StackTraceErrorProps) => (\n    <div\n      className={cn(\n        \"flex flex-1 items-center gap-2 overflow-hidden\",\n        className\n      )}\n      {...props}\n    >\n      <AlertTriangleIcon className=\"text-destructive size-4 shrink-0\" />\n      {children}\n    </div>\n  )\n)\n\nexport type StackTraceErrorTypeProps = ComponentProps<\"span\">\n\nexport const StackTraceErrorType = memo(\n  ({ className, children, ...props }: StackTraceErrorTypeProps) => {\n    const { trace } = useStackTrace()\n\n    return (\n      <span\n        className={cn(\"text-destructive shrink-0 font-semibold\", className)}\n        {...props}\n      >\n        {children ?? trace.errorType}\n      </span>\n    )\n  }\n)\n\nexport type StackTraceErrorMessageProps = ComponentProps<\"span\">\n\nexport const StackTraceErrorMessage = memo(\n  ({ className, children, ...props }: StackTraceErrorMessageProps) => {\n    const { trace } = useStackTrace()\n\n    return (\n      <span className={cn(\"text-foreground truncate\", className)} {...props}>\n        {children ?? trace.errorMessage}\n      </span>\n    )\n  }\n)\n\nexport type StackTraceActionsProps = ComponentProps<\"div\">\n\nconst handleActionsClick = (e: React.MouseEvent) => e.stopPropagation()\nconst handleActionsKeyDown = (e: React.KeyboardEvent) => {\n  if (e.key === \"Enter\" || e.key === \" \") {\n    e.stopPropagation()\n  }\n}\n\nexport const StackTraceActions = memo(\n  ({ className, children, ...props }: StackTraceActionsProps) => (\n    <div\n      className={cn(\"flex shrink-0 items-center gap-1\", className)}\n      onClick={handleActionsClick}\n      onKeyDown={handleActionsKeyDown}\n      role=\"group\"\n      {...props}\n    >\n      {children}\n    </div>\n  )\n)\n\nexport type StackTraceCopyButtonProps = ComponentProps<typeof Button> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const StackTraceCopyButton = memo(\n  ({\n    onCopy,\n    onError,\n    timeout = 2000,\n    className,\n    children,\n    ...props\n  }: StackTraceCopyButtonProps) => {\n    const [isCopied, setIsCopied] = useState(false)\n    const timeoutRef = useRef<number>(0)\n    const { raw } = useStackTrace()\n\n    const copyToClipboard = useCallback(async () => {\n      if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n        onError?.(new Error(\"Clipboard API not available\"))\n        return\n      }\n\n      try {\n        await navigator.clipboard.writeText(raw)\n        setIsCopied(true)\n        onCopy?.()\n        timeoutRef.current = window.setTimeout(\n          () => setIsCopied(false),\n          timeout\n        )\n      } catch (error) {\n        onError?.(error as Error)\n      }\n    }, [raw, onCopy, onError, timeout])\n\n    useEffect(\n      () => () => {\n        window.clearTimeout(timeoutRef.current)\n      },\n      []\n    )\n\n    const Icon = isCopied ? CheckIcon : CopyIcon\n\n    return (\n      <Button\n        className={cn(\"size-7\", className)}\n        onClick={copyToClipboard}\n        size=\"icon\"\n        variant=\"ghost\"\n        {...props}\n      >\n        {children ?? <Icon size={14} />}\n      </Button>\n    )\n  }\n)\n\nexport type StackTraceExpandButtonProps = ComponentProps<\"div\">\n\nexport const StackTraceExpandButton = memo(\n  ({ className, ...props }: StackTraceExpandButtonProps) => {\n    const { isOpen } = useStackTrace()\n\n    return (\n      <div\n        className={cn(\"flex size-7 items-center justify-center\", className)}\n        {...props}\n      >\n        <ChevronDownIcon\n          className={cn(\n            \"text-muted-foreground size-4 transition-transform\",\n            isOpen ? \"rotate-180\" : \"rotate-0\"\n          )}\n        />\n      </div>\n    )\n  }\n)\n\nexport type StackTraceContentProps = ComponentProps<\n  typeof CollapsibleContent\n> & {\n  maxHeight?: number\n}\n\nexport const StackTraceContent = memo(\n  ({\n    className,\n    maxHeight = 400,\n    children,\n    ...props\n  }: StackTraceContentProps) => {\n    const { isOpen } = useStackTrace()\n\n    return (\n      <Collapsible open={isOpen}>\n        <CollapsibleContent\n          className={cn(\n            \"bg-muted/30 overflow-auto border-t\",\n            \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=open]:animate-in\",\n            className\n          )}\n          style={{ maxHeight }}\n          {...props}\n        >\n          {children}\n        </CollapsibleContent>\n      </Collapsible>\n    )\n  }\n)\n\nexport type StackTraceFramesProps = ComponentProps<\"div\"> & {\n  showInternalFrames?: boolean\n}\n\ninterface FilePathButtonProps {\n  frame: StackFrame\n  onFilePathClick?: (\n    filePath: string,\n    lineNumber?: number,\n    columnNumber?: number\n  ) => void\n}\n\nconst FilePathButton = memo(\n  ({ frame, onFilePathClick }: FilePathButtonProps) => {\n    const handleClick = useCallback(() => {\n      if (frame.filePath) {\n        onFilePathClick?.(\n          frame.filePath,\n          frame.lineNumber ?? undefined,\n          frame.columnNumber ?? undefined\n        )\n      }\n    }, [frame, onFilePathClick])\n\n    return (\n      <button\n        className={cn(\n          \"hover:text-primary underline decoration-dotted\",\n          onFilePathClick && \"cursor-pointer\"\n        )}\n        disabled={!onFilePathClick}\n        onClick={handleClick}\n        type=\"button\"\n      >\n        {frame.filePath}\n        {frame.lineNumber !== null && `:${frame.lineNumber}`}\n        {frame.columnNumber !== null && `:${frame.columnNumber}`}\n      </button>\n    )\n  }\n)\n\nFilePathButton.displayName = \"FilePathButton\"\n\nexport const StackTraceFrames = memo(\n  ({\n    className,\n    showInternalFrames = true,\n    ...props\n  }: StackTraceFramesProps) => {\n    const { trace, onFilePathClick } = useStackTrace()\n\n    const framesToShow = showInternalFrames\n      ? trace.frames\n      : trace.frames.filter((f) => !f.isInternal)\n\n    return (\n      <div className={cn(\"space-y-1 p-3\", className)} {...props}>\n        {framesToShow.map((frame) => (\n          <div\n            className={cn(\n              \"text-xs\",\n              frame.isInternal\n                ? \"text-muted-foreground/50\"\n                : \"text-foreground/90\"\n            )}\n            key={frame.raw}\n          >\n            <span className=\"text-muted-foreground\">at </span>\n            {frame.functionName && (\n              <span className={frame.isInternal ? \"\" : \"text-foreground\"}>\n                {frame.functionName}{\" \"}\n              </span>\n            )}\n            {frame.filePath && (\n              <>\n                <span className=\"text-muted-foreground\">(</span>\n                <FilePathButton\n                  frame={frame}\n                  onFilePathClick={onFilePathClick}\n                />\n                <span className=\"text-muted-foreground\">)</span>\n              </>\n            )}\n            {!(frame.filePath || frame.functionName) && (\n              <span>{frame.raw.replace(AT_PREFIX_REGEX, \"\")}</span>\n            )}\n          </div>\n        ))}\n        {framesToShow.length === 0 && (\n          <div className=\"text-muted-foreground text-xs\">No stack frames</div>\n        )}\n      </div>\n    )\n  }\n)\n\nStackTrace.displayName = \"StackTrace\"\nStackTraceHeader.displayName = \"StackTraceHeader\"\nStackTraceError.displayName = \"StackTraceError\"\nStackTraceErrorType.displayName = \"StackTraceErrorType\"\nStackTraceErrorMessage.displayName = \"StackTraceErrorMessage\"\nStackTraceActions.displayName = \"StackTraceActions\"\nStackTraceCopyButton.displayName = \"StackTraceCopyButton\"\nStackTraceExpandButton.displayName = \"StackTraceExpandButton\"\nStackTraceContent.displayName = \"StackTraceContent\"\nStackTraceFrames.displayName = \"StackTraceFrames\"\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-suggestion",
      "type": "registry:block",
      "title": "Ai Elements Suggestion",
      "description": "suggestion",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/suggestion.tsx",
          "target": "@components/ai-elements/suggestion.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { ScrollArea, ScrollBar } from \"@/components/ai-elements/_ui/scroll-area\"\nimport { cn } from \"@/lib/utils\"\nimport type { ComponentProps } from \"react\"\nimport { useCallback } from \"react\"\n\nexport type SuggestionsProps = ComponentProps<typeof ScrollArea>\n\nexport const Suggestions = ({\n  className,\n  children,\n  ...props\n}: SuggestionsProps) => (\n  <ScrollArea className=\"w-full overflow-x-auto whitespace-nowrap\" {...props}>\n    <div className={cn(\"flex w-max flex-nowrap items-center gap-2\", className)}>\n      {children}\n    </div>\n    <ScrollBar className=\"hidden\" orientation=\"horizontal\" />\n  </ScrollArea>\n)\n\nexport type SuggestionProps = Omit<ComponentProps<typeof Button>, \"onClick\"> & {\n  suggestion: string\n  onClick?: (suggestion: string) => void\n}\n\nexport const Suggestion = ({\n  suggestion,\n  onClick,\n  className,\n  variant = \"outline\",\n  size = \"sm\",\n  children,\n  ...props\n}: SuggestionProps) => {\n  const handleClick = useCallback(() => {\n    onClick?.(suggestion)\n  }, [onClick, suggestion])\n\n  return (\n    <Button\n      className={cn(\"cursor-pointer rounded-full px-4\", className)}\n      onClick={handleClick}\n      size={size}\n      type=\"button\"\n      variant={variant}\n      {...props}\n    >\n      {children || suggestion}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/scroll-area.tsx",
          "target": "@components/ai-elements/_ui/scroll-area.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ScrollArea as ScrollAreaPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction ScrollArea({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n  return (\n    <ScrollAreaPrimitive.Root\n      data-slot=\"scroll-area\"\n      className={cn(\"relative\", className)}\n      {...props}\n    >\n      <ScrollAreaPrimitive.Viewport\n        data-slot=\"scroll-area-viewport\"\n        className=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n      >\n        {children}\n      </ScrollAreaPrimitive.Viewport>\n      <ScrollBar />\n      <ScrollAreaPrimitive.Corner />\n    </ScrollAreaPrimitive.Root>\n  )\n}\n\nfunction ScrollBar({\n  className,\n  orientation = \"vertical\",\n  ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n  return (\n    <ScrollAreaPrimitive.ScrollAreaScrollbar\n      data-slot=\"scroll-area-scrollbar\"\n      orientation={orientation}\n      className={cn(\n        \"flex touch-none p-px transition-colors select-none\",\n        orientation === \"vertical\" &&\n          \"h-full w-2.5 border-l border-l-transparent\",\n        orientation === \"horizontal\" &&\n          \"h-2.5 flex-col border-t border-t-transparent\",\n        className\n      )}\n      {...props}\n    >\n      <ScrollAreaPrimitive.ScrollAreaThumb\n        data-slot=\"scroll-area-thumb\"\n        className=\"bg-border relative flex-1 rounded-full\"\n      />\n    </ScrollAreaPrimitive.ScrollAreaScrollbar>\n  )\n}\n\nexport { ScrollArea, ScrollBar }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-task",
      "type": "registry:block",
      "title": "Ai Elements Task",
      "description": "task",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/task.tsx",
          "target": "@components/ai-elements/task.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDownIcon, SearchIcon } from \"lucide-react\"\nimport type { ComponentProps } from \"react\"\n\nexport type TaskItemFileProps = ComponentProps<\"div\">\n\nexport const TaskItemFile = ({\n  children,\n  className,\n  ...props\n}: TaskItemFileProps) => (\n  <div\n    className={cn(\n      \"bg-secondary text-foreground inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-xs\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type TaskItemProps = ComponentProps<\"div\">\n\nexport const TaskItem = ({ children, className, ...props }: TaskItemProps) => (\n  <div className={cn(\"text-muted-foreground text-sm\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type TaskProps = ComponentProps<typeof Collapsible>\n\nexport const Task = ({\n  defaultOpen = true,\n  className,\n  ...props\n}: TaskProps) => (\n  <Collapsible className={cn(className)} defaultOpen={defaultOpen} {...props} />\n)\n\nexport type TaskTriggerProps = ComponentProps<typeof CollapsibleTrigger> & {\n  title: string\n}\n\nexport const TaskTrigger = ({\n  children,\n  className,\n  title,\n  ...props\n}: TaskTriggerProps) => (\n  <CollapsibleTrigger asChild className={cn(\"group\", className)} {...props}>\n    {children ?? (\n      <div className=\"text-muted-foreground hover:text-foreground flex w-full cursor-pointer items-center gap-2 text-sm transition-colors\">\n        <SearchIcon className=\"size-4\" />\n        <p className=\"text-sm\">{title}</p>\n        <ChevronDownIcon className=\"size-4 transition-transform group-data-[state=open]:rotate-180\" />\n      </div>\n    )}\n  </CollapsibleTrigger>\n)\n\nexport type TaskContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const TaskContent = ({\n  children,\n  className,\n  ...props\n}: TaskContentProps) => (\n  <CollapsibleContent\n    className={cn(\n      \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground data-[state=closed]:animate-out data-[state=open]:animate-in outline-none\",\n      className\n    )}\n    {...props}\n  >\n    <div className=\"border-muted mt-4 space-y-2 border-l-2 pl-4\">\n      {children}\n    </div>\n  </CollapsibleContent>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-terminal",
      "type": "registry:block",
      "title": "Ai Elements Terminal",
      "description": "terminal",
      "dependencies": [
        "ansi-to-react@6.2.6",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/terminal.tsx",
          "target": "@components/ai-elements/terminal.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport { cn } from \"@/lib/utils\"\nimport Ansi from \"ansi-to-react\"\nimport { CheckIcon, CopyIcon, TerminalIcon, Trash2Icon } from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\n\ninterface TerminalContextType {\n  output: string\n  isStreaming: boolean\n  autoScroll: boolean\n  onClear?: () => void\n}\n\nconst TerminalContext = createContext<TerminalContextType>({\n  autoScroll: true,\n  isStreaming: false,\n  output: \"\",\n})\n\nexport type TerminalHeaderProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalHeader = ({\n  className,\n  children,\n  ...props\n}: TerminalHeaderProps) => (\n  <div\n    className={cn(\n      \"flex items-center justify-between border-b border-zinc-800 px-4 py-2\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type TerminalTitleProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalTitle = ({\n  className,\n  children,\n  ...props\n}: TerminalTitleProps) => (\n  <div\n    className={cn(\"flex items-center gap-2 text-sm text-zinc-400\", className)}\n    {...props}\n  >\n    <TerminalIcon className=\"size-4\" />\n    {children ?? \"Terminal\"}\n  </div>\n)\n\nexport type TerminalStatusProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalStatus = ({\n  className,\n  children,\n  ...props\n}: TerminalStatusProps) => {\n  const { isStreaming } = useContext(TerminalContext)\n\n  if (!isStreaming) {\n    return null\n  }\n\n  return (\n    <div\n      className={cn(\"flex items-center gap-2 text-xs text-zinc-400\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport type TerminalActionsProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalActions = ({\n  className,\n  children,\n  ...props\n}: TerminalActionsProps) => (\n  <div className={cn(\"flex items-center gap-1\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type TerminalCopyButtonProps = ComponentProps<typeof Button> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const TerminalCopyButton = ({\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  className,\n  ...props\n}: TerminalCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n  const { output } = useContext(TerminalContext)\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      await navigator.clipboard.writeText(output)\n      setIsCopied(true)\n      onCopy?.()\n      timeoutRef.current = window.setTimeout(() => setIsCopied(false), timeout)\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [output, onCopy, onError, timeout])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <Button\n      className={cn(\n        \"size-7 shrink-0 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100\",\n        className\n      )}\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type TerminalClearButtonProps = ComponentProps<typeof Button>\n\nexport const TerminalClearButton = ({\n  children,\n  className,\n  ...props\n}: TerminalClearButtonProps) => {\n  const { onClear } = useContext(TerminalContext)\n\n  if (!onClear) {\n    return null\n  }\n\n  return (\n    <Button\n      className={cn(\n        \"size-7 shrink-0 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100\",\n        className\n      )}\n      onClick={onClear}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Trash2Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type TerminalContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const TerminalContent = ({\n  className,\n  children,\n  ...props\n}: TerminalContentProps) => {\n  const { output, isStreaming, autoScroll } = useContext(TerminalContext)\n  const containerRef = useRef<HTMLDivElement>(null)\n\n  useEffect(() => {\n    if (autoScroll && containerRef.current) {\n      containerRef.current.scrollTop = containerRef.current.scrollHeight\n    }\n  }, [output, autoScroll])\n\n  return (\n    <div\n      className={cn(\n        \"max-h-96 overflow-auto p-4 font-mono text-sm leading-relaxed\",\n        className\n      )}\n      ref={containerRef}\n      {...props}\n    >\n      {children ?? (\n        <pre className=\"break-words whitespace-pre-wrap\">\n          <Ansi>{output}</Ansi>\n          {isStreaming && (\n            <span className=\"ml-0.5 inline-block h-4 w-2 animate-pulse bg-zinc-100\" />\n          )}\n        </pre>\n      )}\n    </div>\n  )\n}\n\nexport type TerminalProps = HTMLAttributes<HTMLDivElement> & {\n  output: string\n  isStreaming?: boolean\n  autoScroll?: boolean\n  onClear?: () => void\n}\n\nexport const Terminal = ({\n  output,\n  isStreaming = false,\n  autoScroll = true,\n  onClear,\n  className,\n  children,\n  ...props\n}: TerminalProps) => {\n  const contextValue = useMemo(\n    () => ({ autoScroll, isStreaming, onClear, output }),\n    [autoScroll, isStreaming, onClear, output]\n  )\n\n  return (\n    <TerminalContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"flex flex-col overflow-hidden rounded-lg border bg-zinc-950 text-zinc-100\",\n          className\n        )}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <TerminalHeader>\n              <TerminalTitle />\n              <div className=\"flex items-center gap-1\">\n                <TerminalStatus />\n                <TerminalActions>\n                  <TerminalCopyButton />\n                  {onClear && <TerminalClearButton />}\n                </TerminalActions>\n              </div>\n            </TerminalHeader>\n            <TerminalContent />\n          </>\n        )}\n      </div>\n    </TerminalContext.Provider>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-test-results",
      "type": "registry:block",
      "title": "Ai Elements Test Results",
      "description": "test results",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/test-results.tsx",
          "target": "@components/ai-elements/test-results.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  CheckCircle2Icon,\n  ChevronRightIcon,\n  CircleDotIcon,\n  CircleIcon,\n  XCircleIcon,\n} from \"lucide-react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\nimport { createContext, useContext, useMemo } from \"react\"\n\ntype TestStatus = \"passed\" | \"failed\" | \"skipped\" | \"running\"\n\ninterface TestResultsSummary {\n  passed: number\n  failed: number\n  skipped: number\n  total: number\n  duration?: number\n}\n\ninterface TestResultsContextType {\n  summary?: TestResultsSummary\n}\n\nconst TestResultsContext = createContext<TestResultsContextType>({})\n\nconst formatDuration = (ms: number) => {\n  if (ms < 1000) {\n    return `${ms}ms`\n  }\n  return `${(ms / 1000).toFixed(2)}s`\n}\n\nexport type TestResultsHeaderProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestResultsHeader = ({\n  className,\n  children,\n  ...props\n}: TestResultsHeaderProps) => (\n  <div\n    className={cn(\n      \"flex items-center justify-between border-b px-4 py-3\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type TestResultsDurationProps = HTMLAttributes<HTMLSpanElement>\n\nexport const TestResultsDuration = ({\n  className,\n  children,\n  ...props\n}: TestResultsDurationProps) => {\n  const { summary } = useContext(TestResultsContext)\n\n  if (!summary?.duration) {\n    return null\n  }\n\n  return (\n    <span className={cn(\"text-muted-foreground text-sm\", className)} {...props}>\n      {children ?? formatDuration(summary.duration)}\n    </span>\n  )\n}\n\nexport type TestResultsSummaryProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestResultsSummary = ({\n  className,\n  children,\n  ...props\n}: TestResultsSummaryProps) => {\n  const { summary } = useContext(TestResultsContext)\n\n  if (!summary) {\n    return null\n  }\n\n  return (\n    <div className={cn(\"flex items-center gap-3\", className)} {...props}>\n      {children ?? (\n        <>\n          <Badge\n            className=\"gap-1 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400\"\n            variant=\"secondary\"\n          >\n            <CheckCircle2Icon className=\"size-3\" />\n            {summary.passed} passed\n          </Badge>\n          {summary.failed > 0 && (\n            <Badge\n              className=\"gap-1 bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400\"\n              variant=\"secondary\"\n            >\n              <XCircleIcon className=\"size-3\" />\n              {summary.failed} failed\n            </Badge>\n          )}\n          {summary.skipped > 0 && (\n            <Badge\n              className=\"gap-1 bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400\"\n              variant=\"secondary\"\n            >\n              <CircleIcon className=\"size-3\" />\n              {summary.skipped} skipped\n            </Badge>\n          )}\n        </>\n      )}\n    </div>\n  )\n}\n\nexport type TestResultsProps = HTMLAttributes<HTMLDivElement> & {\n  summary?: TestResultsSummary\n}\n\nexport const TestResults = ({\n  summary,\n  className,\n  children,\n  ...props\n}: TestResultsProps) => {\n  const contextValue = useMemo(() => ({ summary }), [summary])\n\n  return (\n    <TestResultsContext.Provider value={contextValue}>\n      <div\n        className={cn(\"bg-background rounded-lg border\", className)}\n        {...props}\n      >\n        {children ??\n          (summary && (\n            <TestResultsHeader>\n              <TestResultsSummary />\n              <TestResultsDuration />\n            </TestResultsHeader>\n          ))}\n      </div>\n    </TestResultsContext.Provider>\n  )\n}\n\nexport type TestResultsProgressProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestResultsProgress = ({\n  className,\n  children,\n  ...props\n}: TestResultsProgressProps) => {\n  const { summary } = useContext(TestResultsContext)\n\n  if (!summary) {\n    return null\n  }\n\n  const passedPercent = (summary.passed / summary.total) * 100\n  const failedPercent = (summary.failed / summary.total) * 100\n\n  return (\n    <div className={cn(\"space-y-2\", className)} {...props}>\n      {children ?? (\n        <>\n          <div className=\"bg-muted flex h-2 overflow-hidden rounded-full\">\n            <div\n              className=\"bg-green-500 transition-all\"\n              style={{ width: `${passedPercent}%` }}\n            />\n            <div\n              className=\"bg-red-500 transition-all\"\n              style={{ width: `${failedPercent}%` }}\n            />\n          </div>\n          <div className=\"text-muted-foreground flex justify-between text-xs\">\n            <span>\n              {summary.passed}/{summary.total} tests passed\n            </span>\n            <span>{passedPercent.toFixed(0)}%</span>\n          </div>\n        </>\n      )}\n    </div>\n  )\n}\n\nexport type TestResultsContentProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestResultsContent = ({\n  className,\n  children,\n  ...props\n}: TestResultsContentProps) => (\n  <div className={cn(\"space-y-2 p-4\", className)} {...props}>\n    {children}\n  </div>\n)\n\ninterface TestSuiteContextType {\n  name: string\n  status: TestStatus\n}\n\nconst TestSuiteContext = createContext<TestSuiteContextType>({\n  name: \"\",\n  status: \"passed\",\n})\n\nconst statusStyles: Record<TestStatus, string> = {\n  failed: \"text-red-600 dark:text-red-400\",\n  passed: \"text-green-600 dark:text-green-400\",\n  running: \"text-blue-600 dark:text-blue-400\",\n  skipped: \"text-yellow-600 dark:text-yellow-400\",\n}\n\nconst statusIcons: Record<TestStatus, React.ReactNode> = {\n  failed: <XCircleIcon className=\"size-4\" />,\n  passed: <CheckCircle2Icon className=\"size-4\" />,\n  running: <CircleDotIcon className=\"size-4 animate-pulse\" />,\n  skipped: <CircleIcon className=\"size-4\" />,\n}\n\nconst TestStatusIcon = ({ status }: { status: TestStatus }) => (\n  <span className={cn(\"shrink-0\", statusStyles[status])}>\n    {statusIcons[status]}\n  </span>\n)\n\nexport type TestSuiteProps = ComponentProps<typeof Collapsible> & {\n  name: string\n  status: TestStatus\n}\n\nexport const TestSuite = ({\n  name,\n  status,\n  className,\n  children,\n  ...props\n}: TestSuiteProps) => {\n  const contextValue = useMemo(() => ({ name, status }), [name, status])\n\n  return (\n    <TestSuiteContext.Provider value={contextValue}>\n      <Collapsible className={cn(\"rounded-lg border\", className)} {...props}>\n        {children}\n      </Collapsible>\n    </TestSuiteContext.Provider>\n  )\n}\n\nexport type TestSuiteNameProps = ComponentProps<typeof CollapsibleTrigger>\n\nexport const TestSuiteName = ({\n  className,\n  children,\n  ...props\n}: TestSuiteNameProps) => {\n  const { name, status } = useContext(TestSuiteContext)\n\n  return (\n    <CollapsibleTrigger\n      className={cn(\n        \"group hover:bg-muted/50 flex w-full items-center gap-2 px-4 py-3 text-left transition-colors\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronRightIcon className=\"text-muted-foreground size-4 shrink-0 transition-transform group-data-[state=open]:rotate-90\" />\n      <TestStatusIcon status={status} />\n      <span className=\"text-sm font-medium\">{children ?? name}</span>\n    </CollapsibleTrigger>\n  )\n}\n\nexport type TestSuiteStatsProps = HTMLAttributes<HTMLDivElement> & {\n  passed?: number\n  failed?: number\n  skipped?: number\n}\n\nexport const TestSuiteStats = ({\n  passed = 0,\n  failed = 0,\n  skipped = 0,\n  className,\n  children,\n  ...props\n}: TestSuiteStatsProps) => (\n  <div\n    className={cn(\"ml-auto flex items-center gap-2 text-xs\", className)}\n    {...props}\n  >\n    {children ?? (\n      <>\n        {passed > 0 && (\n          <span className=\"text-green-600 dark:text-green-400\">\n            {passed} passed\n          </span>\n        )}\n        {failed > 0 && (\n          <span className=\"text-red-600 dark:text-red-400\">\n            {failed} failed\n          </span>\n        )}\n        {skipped > 0 && (\n          <span className=\"text-yellow-600 dark:text-yellow-400\">\n            {skipped} skipped\n          </span>\n        )}\n      </>\n    )}\n  </div>\n)\n\nexport type TestSuiteContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const TestSuiteContent = ({\n  className,\n  children,\n  ...props\n}: TestSuiteContentProps) => (\n  <CollapsibleContent className={cn(\"border-t\", className)} {...props}>\n    <div className=\"divide-y\">{children}</div>\n  </CollapsibleContent>\n)\n\ninterface TestContextType {\n  name: string\n  status: TestStatus\n  duration?: number\n}\n\nconst TestContext = createContext<TestContextType>({\n  name: \"\",\n  status: \"passed\",\n})\n\nexport type TestNameProps = HTMLAttributes<HTMLSpanElement>\n\nexport const TestName = ({ className, children, ...props }: TestNameProps) => {\n  const { name } = useContext(TestContext)\n\n  return (\n    <span className={cn(\"flex-1\", className)} {...props}>\n      {children ?? name}\n    </span>\n  )\n}\n\nexport type TestDurationProps = HTMLAttributes<HTMLSpanElement>\n\nexport const TestDuration = ({\n  className,\n  children,\n  ...props\n}: TestDurationProps) => {\n  const { duration } = useContext(TestContext)\n\n  if (duration === undefined) {\n    return null\n  }\n\n  return (\n    <span\n      className={cn(\"text-muted-foreground ml-auto text-xs\", className)}\n      {...props}\n    >\n      {children ?? `${duration}ms`}\n    </span>\n  )\n}\n\nexport type TestStatusProps = HTMLAttributes<HTMLSpanElement>\n\nexport const TestStatus = ({\n  className,\n  children,\n  ...props\n}: TestStatusProps) => {\n  const { status } = useContext(TestContext)\n\n  return (\n    <span\n      className={cn(\"shrink-0\", statusStyles[status], className)}\n      {...props}\n    >\n      {children ?? statusIcons[status]}\n    </span>\n  )\n}\n\nexport type TestProps = HTMLAttributes<HTMLDivElement> & {\n  name: string\n  status: TestStatus\n  duration?: number\n}\n\nexport const Test = ({\n  name,\n  status,\n  duration,\n  className,\n  children,\n  ...props\n}: TestProps) => {\n  const contextValue = useMemo(\n    () => ({ duration, name, status }),\n    [duration, name, status]\n  )\n\n  return (\n    <TestContext.Provider value={contextValue}>\n      <div\n        className={cn(\"flex items-center gap-2 px-4 py-2 text-sm\", className)}\n        {...props}\n      >\n        {children ?? (\n          <>\n            <TestStatus />\n            <TestName />\n            {duration !== undefined && <TestDuration />}\n          </>\n        )}\n      </div>\n    </TestContext.Provider>\n  )\n}\n\nexport type TestErrorProps = HTMLAttributes<HTMLDivElement>\n\nexport const TestError = ({\n  className,\n  children,\n  ...props\n}: TestErrorProps) => (\n  <div\n    className={cn(\n      \"mt-2 rounded-md bg-red-50 p-3 dark:bg-red-900/20\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type TestErrorMessageProps = HTMLAttributes<HTMLParagraphElement>\n\nexport const TestErrorMessage = ({\n  className,\n  children,\n  ...props\n}: TestErrorMessageProps) => (\n  <p\n    className={cn(\n      \"text-sm font-medium text-red-700 dark:text-red-400\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </p>\n)\n\nexport type TestErrorStackProps = HTMLAttributes<HTMLPreElement>\n\nexport const TestErrorStack = ({\n  className,\n  children,\n  ...props\n}: TestErrorStackProps) => (\n  <pre\n    className={cn(\n      \"mt-2 overflow-auto font-mono text-xs text-red-600 dark:text-red-400\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </pre>\n)\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-tool",
      "type": "registry:block",
      "title": "Ai Elements Tool",
      "description": "tool",
      "dependencies": [
        "ai@6.0.280",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/tool.tsx",
          "target": "@components/ai-elements/tool.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Badge } from \"@/components/ai-elements/_ui/badge\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { cn } from \"@/lib/utils\"\nimport type { DynamicToolUIPart, ToolUIPart } from \"ai\"\nimport {\n  CheckCircleIcon,\n  ChevronDownIcon,\n  CircleIcon,\n  ClockIcon,\n  WrenchIcon,\n  XCircleIcon,\n} from \"lucide-react\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport { isValidElement } from \"react\"\nimport { CodeBlock } from \"./code-block\"\n\nexport type ToolProps = ComponentProps<typeof Collapsible>\n\nexport const Tool = ({ className, ...props }: ToolProps) => (\n  <Collapsible\n    className={cn(\"group not-prose mb-4 w-full rounded-md border\", className)}\n    {...props}\n  />\n)\n\nexport type ToolPart = ToolUIPart | DynamicToolUIPart\n\nexport type ToolHeaderProps = {\n  title?: string\n  className?: string\n} & (\n  | { type: ToolUIPart[\"type\"]; state: ToolUIPart[\"state\"]; toolName?: never }\n  | {\n      type: DynamicToolUIPart[\"type\"]\n      state: DynamicToolUIPart[\"state\"]\n      toolName: string\n    }\n)\n\nconst statusLabels: Record<ToolPart[\"state\"], string> = {\n  \"approval-requested\": \"Awaiting Approval\",\n  \"approval-responded\": \"Responded\",\n  \"input-available\": \"Running\",\n  \"input-streaming\": \"Pending\",\n  \"output-available\": \"Completed\",\n  \"output-denied\": \"Denied\",\n  \"output-error\": \"Error\",\n}\n\nconst statusIcons: Record<ToolPart[\"state\"], ReactNode> = {\n  \"approval-requested\": <ClockIcon className=\"size-4 text-yellow-600\" />,\n  \"approval-responded\": <CheckCircleIcon className=\"size-4 text-blue-600\" />,\n  \"input-available\": <ClockIcon className=\"size-4 animate-pulse\" />,\n  \"input-streaming\": <CircleIcon className=\"size-4\" />,\n  \"output-available\": <CheckCircleIcon className=\"size-4 text-green-600\" />,\n  \"output-denied\": <XCircleIcon className=\"size-4 text-orange-600\" />,\n  \"output-error\": <XCircleIcon className=\"size-4 text-red-600\" />,\n}\n\nexport const getStatusBadge = (status: ToolPart[\"state\"]) => (\n  <Badge className=\"gap-1.5 rounded-full text-xs\" variant=\"secondary\">\n    {statusIcons[status]}\n    {statusLabels[status]}\n  </Badge>\n)\n\nexport const ToolHeader = ({\n  className,\n  title,\n  type,\n  state,\n  toolName,\n  ...props\n}: ToolHeaderProps) => {\n  const derivedName =\n    type === \"dynamic-tool\" ? toolName : type.split(\"-\").slice(1).join(\"-\")\n\n  return (\n    <CollapsibleTrigger\n      className={cn(\n        \"flex w-full items-center justify-between gap-4 p-3\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"flex items-center gap-2\">\n        <WrenchIcon className=\"text-muted-foreground size-4\" />\n        <span className=\"text-sm font-medium\">{title ?? derivedName}</span>\n        {getStatusBadge(state)}\n      </div>\n      <ChevronDownIcon className=\"text-muted-foreground size-4 transition-transform group-data-[state=open]:rotate-180\" />\n    </CollapsibleTrigger>\n  )\n}\n\nexport type ToolContentProps = ComponentProps<typeof CollapsibleContent>\n\nexport const ToolContent = ({ className, ...props }: ToolContentProps) => (\n  <CollapsibleContent\n    className={cn(\n      \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground data-[state=closed]:animate-out data-[state=open]:animate-in space-y-4 p-4 outline-none\",\n      className\n    )}\n    {...props}\n  />\n)\n\nexport type ToolInputProps = ComponentProps<\"div\"> & {\n  input: ToolPart[\"input\"]\n}\n\nexport const ToolInput = ({ className, input, ...props }: ToolInputProps) => (\n  <div className={cn(\"space-y-2 overflow-hidden\", className)} {...props}>\n    <h4 className=\"text-muted-foreground text-xs font-medium tracking-wide uppercase\">\n      Parameters\n    </h4>\n    <div className=\"bg-muted/50 rounded-md\">\n      <CodeBlock code={JSON.stringify(input, null, 2)} language=\"json\" />\n    </div>\n  </div>\n)\n\nexport type ToolOutputProps = ComponentProps<\"div\"> & {\n  output: ToolPart[\"output\"]\n  errorText: ToolPart[\"errorText\"]\n}\n\nexport const ToolOutput = ({\n  className,\n  output,\n  errorText,\n  ...props\n}: ToolOutputProps) => {\n  if (!(output || errorText)) {\n    return null\n  }\n\n  let Output = <div>{output as ReactNode}</div>\n\n  if (typeof output === \"object\" && !isValidElement(output)) {\n    Output = (\n      <CodeBlock code={JSON.stringify(output, null, 2)} language=\"json\" />\n    )\n  } else if (typeof output === \"string\") {\n    Output = <CodeBlock code={output} language=\"json\" />\n  }\n\n  return (\n    <div className={cn(\"space-y-2\", className)} {...props}>\n      <h4 className=\"text-muted-foreground text-xs font-medium tracking-wide uppercase\">\n        {errorText ? \"Error\" : \"Result\"}\n      </h4>\n      <div\n        className={cn(\n          \"overflow-x-auto rounded-md text-xs [&_table]:w-full\",\n          errorText\n            ? \"bg-destructive/10 text-destructive\"\n            : \"bg-muted/50 text-foreground\"\n        )}\n      >\n        {errorText && <div>{errorText}</div>}\n        {Output}\n      </div>\n    </div>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/badge.tsx",
          "target": "@components/ai-elements/_ui/badge.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst badgeVariants = cva(\n  \"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n        secondary:\n          \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n        destructive:\n          \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "components/ai-elements/code-block.tsx",
          "target": "@components/ai-elements/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ai-elements/_ui/select\"\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, CopyIcon } from \"lucide-react\"\nimport type { ComponentProps, CSSProperties, HTMLAttributes } from \"react\"\nimport {\n  createContext,\n  memo,\n  useCallback,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\"\nimport type {\n  BundledLanguage,\n  BundledTheme,\n  HighlighterGeneric,\n  ThemedToken,\n} from \"shiki\"\nimport { createHighlighter } from \"shiki\"\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2\nconst isUnderline = (fontStyle: number | undefined) =>\n  // oxlint-disable-next-line eslint(no-bitwise)\n  fontStyle && fontStyle & 4\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n  token: ThemedToken\n  key: string\n}\ninterface KeyedLine {\n  tokens: KeyedToken[]\n  key: string\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n  lines.map((line, lineIdx) => ({\n    key: `line-${lineIdx}`,\n    tokens: line.map((token, tokenIdx) => ({\n      key: `line-${lineIdx}-${tokenIdx}`,\n      token,\n    })),\n  }))\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n  <span\n    className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n    style={\n      {\n        backgroundColor: token.bgColor,\n        color: token.color,\n        fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n        fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n        textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n        ...token.htmlStyle,\n      } as CSSProperties\n    }\n  >\n    {token.content}\n  </span>\n)\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n  \"block\",\n  \"before:content-[counter(line)]\",\n  \"before:inline-block\",\n  \"before:[counter-increment:line]\",\n  \"before:w-8\",\n  \"before:mr-4\",\n  \"before:text-right\",\n  \"before:text-muted-foreground/50\",\n  \"before:font-mono\",\n  \"before:select-none\"\n)\n\n// Line rendering component\nconst LineSpan = ({\n  keyedLine,\n  showLineNumbers,\n}: {\n  keyedLine: KeyedLine\n  showLineNumbers: boolean\n}) => (\n  <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n    {keyedLine.tokens.length === 0\n      ? \"\\n\"\n      : keyedLine.tokens.map(({ token, key }) => (\n          <TokenSpan key={key} token={token} />\n        ))}\n  </span>\n)\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n  code: string\n  language: BundledLanguage\n  showLineNumbers?: boolean\n}\n\ninterface TokenizedCode {\n  tokens: ThemedToken[][]\n  fg: string\n  bg: string\n}\n\ninterface CodeBlockContextType {\n  code: string\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n  code: \"\",\n})\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n  string,\n  Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>()\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>()\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>()\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n  const start = code.slice(0, 100)\n  const end = code.length > 100 ? code.slice(-100) : \"\"\n  return `${language}:${code.length}:${start}:${end}`\n}\n\nconst getHighlighter = (\n  language: BundledLanguage\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n  const cached = highlighterCache.get(language)\n  if (cached) {\n    return cached\n  }\n\n  const highlighterPromise = createHighlighter({\n    langs: [language],\n    themes: [\"github-light\", \"github-dark\"],\n  })\n\n  highlighterCache.set(language, highlighterPromise)\n  return highlighterPromise\n}\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n  bg: \"transparent\",\n  fg: \"inherit\",\n  tokens: code.split(\"\\n\").map((line) =>\n    line === \"\"\n      ? []\n      : [\n          {\n            color: \"inherit\",\n            content: line,\n          } as ThemedToken,\n        ]\n  ),\n})\n\n// Synchronous highlight with callback for async results\nexport const highlightCode = (\n  code: string,\n  language: BundledLanguage,\n  // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-callbacks)\n  callback?: (result: TokenizedCode) => void\n): TokenizedCode | null => {\n  const tokensCacheKey = getTokensCacheKey(code, language)\n\n  // Return cached result if available\n  const cached = tokensCache.get(tokensCacheKey)\n  if (cached) {\n    return cached\n  }\n\n  // Subscribe callback if provided\n  if (callback) {\n    if (!subscribers.has(tokensCacheKey)) {\n      subscribers.set(tokensCacheKey, new Set())\n    }\n    subscribers.get(tokensCacheKey)?.add(callback)\n  }\n\n  // Start highlighting in background - fire-and-forget async pattern\n  getHighlighter(language)\n    // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then)\n    .then((highlighter) => {\n      const availableLangs = highlighter.getLoadedLanguages()\n      const langToUse = availableLangs.includes(language) ? language : \"text\"\n\n      const result = highlighter.codeToTokens(code, {\n        lang: langToUse,\n        themes: {\n          dark: \"github-dark\",\n          light: \"github-light\",\n        },\n      })\n\n      const tokenized: TokenizedCode = {\n        bg: result.bg ?? \"transparent\",\n        fg: result.fg ?? \"inherit\",\n        tokens: result.tokens,\n      }\n\n      // Cache the result\n      tokensCache.set(tokensCacheKey, tokenized)\n\n      // Notify all subscribers\n      const subs = subscribers.get(tokensCacheKey)\n      if (subs) {\n        for (const sub of subs) {\n          sub(tokenized)\n        }\n        subscribers.delete(tokensCacheKey)\n      }\n    })\n    // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then), eslint-plugin-promise(prefer-await-to-callbacks)\n    .catch((error) => {\n      console.error(\"Failed to highlight code:\", error)\n      subscribers.delete(tokensCacheKey)\n    })\n\n  return null\n}\n\nconst CodeBlockBody = memo(\n  ({\n    tokenized,\n    showLineNumbers,\n    className,\n  }: {\n    tokenized: TokenizedCode\n    showLineNumbers: boolean\n    className?: string\n  }) => {\n    const preStyle = useMemo(\n      () => ({\n        backgroundColor: tokenized.bg,\n        color: tokenized.fg,\n      }),\n      [tokenized.bg, tokenized.fg]\n    )\n\n    const keyedLines = useMemo(\n      () => addKeysToTokens(tokenized.tokens),\n      [tokenized.tokens]\n    )\n\n    return (\n      <pre\n        className={cn(\n          \"m-0 p-4 text-sm dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\",\n          className\n        )}\n        style={preStyle}\n      >\n        <code\n          className={cn(\n            \"font-mono text-sm\",\n            showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\"\n          )}\n        >\n          {keyedLines.map((keyedLine) => (\n            <LineSpan\n              key={keyedLine.key}\n              keyedLine={keyedLine}\n              showLineNumbers={showLineNumbers}\n            />\n          ))}\n        </code>\n      </pre>\n    )\n  },\n  (prevProps, nextProps) =>\n    prevProps.tokenized === nextProps.tokenized &&\n    prevProps.showLineNumbers === nextProps.showLineNumbers &&\n    prevProps.className === nextProps.className\n)\n\nCodeBlockBody.displayName = \"CodeBlockBody\"\n\nexport const CodeBlockContainer = ({\n  className,\n  language,\n  style,\n  ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n  <div\n    className={cn(\n      \"group bg-background text-foreground relative w-full overflow-hidden rounded-md border\",\n      className\n    )}\n    data-language={language}\n    style={{\n      containIntrinsicSize: \"auto 200px\",\n      contentVisibility: \"auto\",\n      ...style,\n    }}\n    {...props}\n  />\n)\n\nexport const CodeBlockHeader = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      \"bg-muted/80 text-muted-foreground flex items-center justify-between border-b px-3 py-2 text-xs\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport const CodeBlockTitle = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport const CodeBlockFilename = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n  <span className={cn(\"font-mono\", className)} {...props}>\n    {children}\n  </span>\n)\n\nexport const CodeBlockActions = ({\n  children,\n  className,\n  ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport const CodeBlockContent = ({\n  code,\n  language,\n  showLineNumbers = false,\n}: {\n  code: string\n  language: BundledLanguage\n  showLineNumbers?: boolean\n}) => {\n  // Memoized raw tokens for immediate display\n  const rawTokens = useMemo(() => createRawTokens(code), [code])\n\n  // Synchronous cache lookup — avoids setState in effect for cached results\n  const syncTokens = useMemo(\n    () => highlightCode(code, language) ?? rawTokens,\n    [code, language, rawTokens]\n  )\n\n  // Async highlighting result (populated after shiki loads)\n  const [asyncTokens, setAsyncTokens] = useState<TokenizedCode | null>(null)\n  const asyncKeyRef = useRef({ code, language })\n\n  // Invalidate stale async tokens synchronously during render\n  if (\n    asyncKeyRef.current.code !== code ||\n    asyncKeyRef.current.language !== language\n  ) {\n    asyncKeyRef.current = { code, language }\n    setAsyncTokens(null)\n  }\n\n  useEffect(() => {\n    let cancelled = false\n\n    highlightCode(code, language, (result) => {\n      if (!cancelled) {\n        setAsyncTokens(result)\n      }\n    })\n\n    return () => {\n      cancelled = true\n    }\n  }, [code, language])\n\n  const tokenized = asyncTokens ?? syncTokens\n\n  return (\n    <div className=\"relative overflow-auto\">\n      <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n    </div>\n  )\n}\n\nexport const CodeBlock = ({\n  code,\n  language,\n  showLineNumbers = false,\n  className,\n  children,\n  ...props\n}: CodeBlockProps) => {\n  const contextValue = useMemo(() => ({ code }), [code])\n\n  return (\n    <CodeBlockContext.Provider value={contextValue}>\n      <CodeBlockContainer className={className} language={language} {...props}>\n        {children}\n        <CodeBlockContent\n          code={code}\n          language={language}\n          showLineNumbers={showLineNumbers}\n        />\n      </CodeBlockContainer>\n    </CodeBlockContext.Provider>\n  )\n}\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n  onCopy?: () => void\n  onError?: (error: Error) => void\n  timeout?: number\n}\n\nexport const CodeBlockCopyButton = ({\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  className,\n  ...props\n}: CodeBlockCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false)\n  const timeoutRef = useRef<number>(0)\n  const { code } = useContext(CodeBlockContext)\n\n  const copyToClipboard = useCallback(async () => {\n    if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n      onError?.(new Error(\"Clipboard API not available\"))\n      return\n    }\n\n    try {\n      if (!isCopied) {\n        await navigator.clipboard.writeText(code)\n        setIsCopied(true)\n        onCopy?.()\n        timeoutRef.current = window.setTimeout(\n          () => setIsCopied(false),\n          timeout\n        )\n      }\n    } catch (error) {\n      onError?.(error as Error)\n    }\n  }, [code, onCopy, onError, timeout, isCopied])\n\n  useEffect(\n    () => () => {\n      window.clearTimeout(timeoutRef.current)\n    },\n    []\n  )\n\n  const Icon = isCopied ? CheckIcon : CopyIcon\n\n  return (\n    <Button\n      className={cn(\"shrink-0\", className)}\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? <Icon size={14} />}\n    </Button>\n  )\n}\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>\n\nexport const CodeBlockLanguageSelector = (\n  props: CodeBlockLanguageSelectorProps\n) => <Select {...props} />\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<\n  typeof SelectTrigger\n>\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n  className,\n  ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n  <SelectTrigger\n    className={cn(\n      \"h-7 border-none bg-transparent px-2 text-xs shadow-none\",\n      className\n    )}\n    size=\"sm\"\n    {...props}\n  />\n)\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<\n  typeof SelectValue\n>\n\nexport const CodeBlockLanguageSelectorValue = (\n  props: CodeBlockLanguageSelectorValueProps\n) => <SelectValue {...props} />\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<\n  typeof SelectContent\n>\n\nexport const CodeBlockLanguageSelectorContent = ({\n  align = \"end\",\n  ...props\n}: CodeBlockLanguageSelectorContentProps) => (\n  <SelectContent align={align} {...props} />\n)\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<\n  typeof SelectItem\n>\n\nexport const CodeBlockLanguageSelectorItem = (\n  props: CodeBlockLanguageSelectorItemProps\n) => <SelectItem {...props} />\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "components/ai-elements/_ui/select.tsx",
          "target": "@components/ai-elements/_ui/select.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Select({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"popper\",\n  align = \"center\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        align={align}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"flex cursor-default items-center justify-center py-1\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-toolbar",
      "type": "registry:block",
      "title": "Ai Elements Toolbar",
      "description": "toolbar",
      "dependencies": [
        "@xyflow/react@12.10.0",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/toolbar.tsx",
          "target": "@components/ai-elements/toolbar.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { NodeToolbar, Position } from \"@xyflow/react\"\nimport type { ComponentProps } from \"react\"\n\ntype ToolbarProps = ComponentProps<typeof NodeToolbar>\n\nexport const Toolbar = ({ className, ...props }: ToolbarProps) => (\n  <NodeToolbar\n    className={cn(\n      \"bg-background flex items-center gap-1 rounded-sm border p-1.5\",\n      className\n    )}\n    position={Position.Bottom}\n    {...props}\n  />\n)\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-transcription",
      "type": "registry:block",
      "title": "Ai Elements Transcription",
      "description": "transcription",
      "dependencies": [
        "@radix-ui/react-use-controllable-state@1.2.2",
        "ai@6.0.280",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/transcription.tsx",
          "target": "@components/ai-elements/transcription.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\"\nimport type { Experimental_TranscriptionResult as TranscriptionResult } from \"ai\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport { createContext, useCallback, useContext, useMemo } from \"react\"\n\ntype TranscriptionSegment = TranscriptionResult[\"segments\"][number]\n\ninterface TranscriptionContextValue {\n  segments: TranscriptionSegment[]\n  currentTime: number\n  onTimeUpdate: (time: number) => void\n  onSeek?: (time: number) => void\n}\n\nconst TranscriptionContext = createContext<TranscriptionContextValue | null>(\n  null\n)\n\nconst useTranscription = () => {\n  const context = useContext(TranscriptionContext)\n  if (!context) {\n    throw new Error(\n      \"Transcription components must be used within Transcription\"\n    )\n  }\n  return context\n}\n\nexport type TranscriptionProps = Omit<ComponentProps<\"div\">, \"children\"> & {\n  segments: TranscriptionSegment[]\n  currentTime?: number\n  onSeek?: (time: number) => void\n  children: (segment: TranscriptionSegment, index: number) => ReactNode\n}\n\nexport const Transcription = ({\n  segments,\n  currentTime: externalCurrentTime,\n  onSeek,\n  className,\n  children,\n  ...props\n}: TranscriptionProps) => {\n  const [currentTime, setCurrentTime] = useControllableState({\n    defaultProp: 0,\n    onChange: onSeek,\n    prop: externalCurrentTime,\n  })\n\n  const contextValue = useMemo(\n    () => ({ currentTime, onSeek, onTimeUpdate: setCurrentTime, segments }),\n    [currentTime, onSeek, setCurrentTime, segments]\n  )\n\n  return (\n    <TranscriptionContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"flex flex-wrap gap-1 text-sm leading-relaxed\",\n          className\n        )}\n        data-slot=\"transcription\"\n        {...props}\n      >\n        {segments\n          .filter((segment) => segment.text.trim())\n          .map((segment, index) => children(segment, index))}\n      </div>\n    </TranscriptionContext.Provider>\n  )\n}\n\nexport type TranscriptionSegmentProps = ComponentProps<\"button\"> & {\n  segment: TranscriptionSegment\n  index: number\n}\n\nexport const TranscriptionSegment = ({\n  segment,\n  index,\n  className,\n  onClick,\n  ...props\n}: TranscriptionSegmentProps) => {\n  const { currentTime, onSeek } = useTranscription()\n\n  const isActive =\n    currentTime >= segment.startSecond && currentTime < segment.endSecond\n  const isPast = currentTime >= segment.endSecond\n\n  const handleClick = useCallback(\n    (event: React.MouseEvent<HTMLButtonElement>) => {\n      if (onSeek) {\n        onSeek(segment.startSecond)\n      }\n      onClick?.(event)\n    },\n    [onSeek, segment.startSecond, onClick]\n  )\n\n  return (\n    <button\n      className={cn(\n        \"inline text-left\",\n        isActive && \"text-primary\",\n        isPast && \"text-muted-foreground\",\n        !(isActive || isPast) && \"text-muted-foreground/60\",\n        onSeek && \"hover:text-foreground cursor-pointer\",\n        !onSeek && \"cursor-default\",\n        className\n      )}\n      data-active={isActive}\n      data-index={index}\n      data-slot=\"transcription-segment\"\n      onClick={handleClick}\n      type=\"button\"\n      {...props}\n    >\n      {segment.text}\n    </button>\n  )\n}\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-voice-selector",
      "type": "registry:block",
      "title": "Ai Elements Voice Selector",
      "description": "voice selector",
      "dependencies": [
        "@radix-ui/react-use-controllable-state@1.2.2",
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "cmdk@1.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/voice-selector.tsx",
          "target": "@components/ai-elements/voice-selector.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Command,\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n} from \"@/components/ai-elements/_ui/command\"\nimport {\n  Dialog,\n  DialogContent,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ai-elements/_ui/dialog\"\nimport { Spinner } from \"@/components/ai-elements/_ui/spinner\"\nimport { cn } from \"@/lib/utils\"\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\"\nimport {\n  CircleSmallIcon,\n  MarsIcon,\n  MarsStrokeIcon,\n  NonBinaryIcon,\n  PauseIcon,\n  PlayIcon,\n  TransgenderIcon,\n  VenusAndMarsIcon,\n  VenusIcon,\n} from \"lucide-react\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport { createContext, useCallback, useContext, useMemo } from \"react\"\n\ninterface VoiceSelectorContextValue {\n  value: string | undefined\n  setValue: (value: string | undefined) => void\n  open: boolean\n  setOpen: (open: boolean) => void\n}\n\nconst VoiceSelectorContext = createContext<VoiceSelectorContextValue | null>(\n  null\n)\n\nexport const useVoiceSelector = () => {\n  const context = useContext(VoiceSelectorContext)\n  if (!context) {\n    throw new Error(\n      \"VoiceSelector components must be used within VoiceSelector\"\n    )\n  }\n  return context\n}\n\nexport type VoiceSelectorProps = ComponentProps<typeof Dialog> & {\n  value?: string\n  defaultValue?: string\n  onValueChange?: (value: string | undefined) => void\n}\n\nexport const VoiceSelector = ({\n  value: valueProp,\n  defaultValue,\n  onValueChange,\n  open: openProp,\n  defaultOpen = false,\n  onOpenChange,\n  children,\n  ...props\n}: VoiceSelectorProps) => {\n  const [value, setValue] = useControllableState({\n    defaultProp: defaultValue,\n    onChange: onValueChange,\n    prop: valueProp,\n  })\n\n  const [open, setOpen] = useControllableState({\n    defaultProp: defaultOpen,\n    onChange: onOpenChange,\n    prop: openProp,\n  })\n\n  const voiceSelectorContext = useMemo(\n    () => ({ open, setOpen, setValue, value }),\n    [value, setValue, open, setOpen]\n  )\n\n  return (\n    <VoiceSelectorContext.Provider value={voiceSelectorContext}>\n      <Dialog onOpenChange={setOpen} open={open} {...props}>\n        {children}\n      </Dialog>\n    </VoiceSelectorContext.Provider>\n  )\n}\n\nexport type VoiceSelectorTriggerProps = ComponentProps<typeof DialogTrigger>\n\nexport const VoiceSelectorTrigger = (props: VoiceSelectorTriggerProps) => (\n  <DialogTrigger {...props} />\n)\n\nexport type VoiceSelectorContentProps = ComponentProps<typeof DialogContent> & {\n  title?: ReactNode\n}\n\nexport const VoiceSelectorContent = ({\n  className,\n  children,\n  title = \"Voice Selector\",\n  ...props\n}: VoiceSelectorContentProps) => (\n  <DialogContent\n    aria-describedby={undefined}\n    className={cn(\"p-0\", className)}\n    {...props}\n  >\n    <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n    <Command className=\"**:data-[slot=command-input-wrapper]:h-auto\">\n      {children}\n    </Command>\n  </DialogContent>\n)\n\nexport type VoiceSelectorDialogProps = ComponentProps<typeof CommandDialog>\n\nexport const VoiceSelectorDialog = (props: VoiceSelectorDialogProps) => (\n  <CommandDialog {...props} />\n)\n\nexport type VoiceSelectorInputProps = ComponentProps<typeof CommandInput>\n\nexport const VoiceSelectorInput = ({\n  className,\n  ...props\n}: VoiceSelectorInputProps) => (\n  <CommandInput className={cn(\"h-auto py-3.5\", className)} {...props} />\n)\n\nexport type VoiceSelectorListProps = ComponentProps<typeof CommandList>\n\nexport const VoiceSelectorList = (props: VoiceSelectorListProps) => (\n  <CommandList {...props} />\n)\n\nexport type VoiceSelectorEmptyProps = ComponentProps<typeof CommandEmpty>\n\nexport const VoiceSelectorEmpty = (props: VoiceSelectorEmptyProps) => (\n  <CommandEmpty {...props} />\n)\n\nexport type VoiceSelectorGroupProps = ComponentProps<typeof CommandGroup>\n\nexport const VoiceSelectorGroup = (props: VoiceSelectorGroupProps) => (\n  <CommandGroup {...props} />\n)\n\nexport type VoiceSelectorItemProps = ComponentProps<typeof CommandItem>\n\nexport const VoiceSelectorItem = ({\n  className,\n  ...props\n}: VoiceSelectorItemProps) => (\n  <CommandItem className={cn(\"px-4 py-2\", className)} {...props} />\n)\n\nexport type VoiceSelectorShortcutProps = ComponentProps<typeof CommandShortcut>\n\nexport const VoiceSelectorShortcut = (props: VoiceSelectorShortcutProps) => (\n  <CommandShortcut {...props} />\n)\n\nexport type VoiceSelectorSeparatorProps = ComponentProps<\n  typeof CommandSeparator\n>\n\nexport const VoiceSelectorSeparator = (props: VoiceSelectorSeparatorProps) => (\n  <CommandSeparator {...props} />\n)\n\nexport type VoiceSelectorGenderProps = ComponentProps<\"span\"> & {\n  value?:\n    | \"male\"\n    | \"female\"\n    | \"transgender\"\n    | \"androgyne\"\n    | \"non-binary\"\n    | \"intersex\"\n}\n\nexport const VoiceSelectorGender = ({\n  className,\n  value,\n  children,\n  ...props\n}: VoiceSelectorGenderProps) => {\n  let icon: ReactNode | null = null\n\n  switch (value) {\n    case \"male\": {\n      icon = <MarsIcon className=\"size-4\" />\n      break\n    }\n    case \"female\": {\n      icon = <VenusIcon className=\"size-4\" />\n      break\n    }\n    case \"transgender\": {\n      icon = <TransgenderIcon className=\"size-4\" />\n      break\n    }\n    case \"androgyne\": {\n      icon = <MarsStrokeIcon className=\"size-4\" />\n      break\n    }\n    case \"non-binary\": {\n      icon = <NonBinaryIcon className=\"size-4\" />\n      break\n    }\n    case \"intersex\": {\n      icon = <VenusAndMarsIcon className=\"size-4\" />\n      break\n    }\n    default: {\n      icon = <CircleSmallIcon className=\"size-4\" />\n    }\n  }\n\n  return (\n    <span className={cn(\"text-muted-foreground text-xs\", className)} {...props}>\n      {children ?? icon}\n    </span>\n  )\n}\n\nexport type VoiceSelectorAccentProps = ComponentProps<\"span\"> & {\n  value?:\n    | \"american\"\n    | \"british\"\n    | \"australian\"\n    | \"canadian\"\n    | \"irish\"\n    | \"scottish\"\n    | \"indian\"\n    | \"south-african\"\n    | \"new-zealand\"\n    | \"spanish\"\n    | \"french\"\n    | \"german\"\n    | \"italian\"\n    | \"portuguese\"\n    | \"brazilian\"\n    | \"mexican\"\n    | \"argentinian\"\n    | \"japanese\"\n    | \"chinese\"\n    | \"korean\"\n    | \"russian\"\n    | \"arabic\"\n    | \"dutch\"\n    | \"swedish\"\n    | \"norwegian\"\n    | \"danish\"\n    | \"finnish\"\n    | \"polish\"\n    | \"turkish\"\n    | \"greek\"\n    | string\n}\n\nexport const VoiceSelectorAccent = ({\n  className,\n  value,\n  children,\n  ...props\n}: VoiceSelectorAccentProps) => {\n  let emoji: string | null = null\n\n  switch (value) {\n    case \"american\": {\n      emoji = \"🇺🇸\"\n      break\n    }\n    case \"british\": {\n      emoji = \"🇬🇧\"\n      break\n    }\n    case \"australian\": {\n      emoji = \"🇦🇺\"\n      break\n    }\n    case \"canadian\": {\n      emoji = \"🇨🇦\"\n      break\n    }\n    case \"irish\": {\n      emoji = \"🇮🇪\"\n      break\n    }\n    case \"scottish\": {\n      emoji = \"🏴󠁧󠁢󠁳󠁣󠁴󠁿\"\n      break\n    }\n    case \"indian\": {\n      emoji = \"🇮🇳\"\n      break\n    }\n    case \"south-african\": {\n      emoji = \"🇿🇦\"\n      break\n    }\n    case \"new-zealand\": {\n      emoji = \"🇳🇿\"\n      break\n    }\n    case \"spanish\": {\n      emoji = \"🇪🇸\"\n      break\n    }\n    case \"french\": {\n      emoji = \"🇫🇷\"\n      break\n    }\n    case \"german\": {\n      emoji = \"🇩🇪\"\n      break\n    }\n    case \"italian\": {\n      emoji = \"🇮🇹\"\n      break\n    }\n    case \"portuguese\": {\n      emoji = \"🇵🇹\"\n      break\n    }\n    case \"brazilian\": {\n      emoji = \"🇧🇷\"\n      break\n    }\n    case \"mexican\": {\n      emoji = \"🇲🇽\"\n      break\n    }\n    case \"argentinian\": {\n      emoji = \"🇦🇷\"\n      break\n    }\n    case \"japanese\": {\n      emoji = \"🇯🇵\"\n      break\n    }\n    case \"chinese\": {\n      emoji = \"🇨🇳\"\n      break\n    }\n    case \"korean\": {\n      emoji = \"🇰🇷\"\n      break\n    }\n    case \"russian\": {\n      emoji = \"🇷🇺\"\n      break\n    }\n    case \"arabic\": {\n      emoji = \"🇸🇦\"\n      break\n    }\n    case \"dutch\": {\n      emoji = \"🇳🇱\"\n      break\n    }\n    case \"swedish\": {\n      emoji = \"🇸🇪\"\n      break\n    }\n    case \"norwegian\": {\n      emoji = \"🇳🇴\"\n      break\n    }\n    case \"danish\": {\n      emoji = \"🇩🇰\"\n      break\n    }\n    case \"finnish\": {\n      emoji = \"🇫🇮\"\n      break\n    }\n    case \"polish\": {\n      emoji = \"🇵🇱\"\n      break\n    }\n    case \"turkish\": {\n      emoji = \"🇹🇷\"\n      break\n    }\n    case \"greek\": {\n      emoji = \"🇬🇷\"\n      break\n    }\n    default: {\n      emoji = null\n    }\n  }\n\n  return (\n    <span className={cn(\"text-muted-foreground text-xs\", className)} {...props}>\n      {children ?? emoji}\n    </span>\n  )\n}\n\nexport type VoiceSelectorAgeProps = ComponentProps<\"span\">\n\nexport const VoiceSelectorAge = ({\n  className,\n  ...props\n}: VoiceSelectorAgeProps) => (\n  <span\n    className={cn(\"text-muted-foreground text-xs tabular-nums\", className)}\n    {...props}\n  />\n)\n\nexport type VoiceSelectorNameProps = ComponentProps<\"span\">\n\nexport const VoiceSelectorName = ({\n  className,\n  ...props\n}: VoiceSelectorNameProps) => (\n  <span\n    className={cn(\"flex-1 truncate text-left font-medium\", className)}\n    {...props}\n  />\n)\n\nexport type VoiceSelectorDescriptionProps = ComponentProps<\"span\">\n\nexport const VoiceSelectorDescription = ({\n  className,\n  ...props\n}: VoiceSelectorDescriptionProps) => (\n  <span className={cn(\"text-muted-foreground text-xs\", className)} {...props} />\n)\n\nexport type VoiceSelectorAttributesProps = ComponentProps<\"div\">\n\nexport const VoiceSelectorAttributes = ({\n  className,\n  children,\n  ...props\n}: VoiceSelectorAttributesProps) => (\n  <div className={cn(\"flex items-center text-xs\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type VoiceSelectorBulletProps = ComponentProps<\"span\">\n\nexport const VoiceSelectorBullet = ({\n  className,\n  ...props\n}: VoiceSelectorBulletProps) => (\n  <span\n    aria-hidden=\"true\"\n    className={cn(\"text-border select-none\", className)}\n    {...props}\n  >\n    &bull;\n  </span>\n)\n\nexport type VoiceSelectorPreviewProps = Omit<\n  ComponentProps<\"button\">,\n  \"children\"\n> & {\n  playing?: boolean\n  loading?: boolean\n  onPlay?: () => void\n}\n\nexport const VoiceSelectorPreview = ({\n  className,\n  playing,\n  loading,\n  onPlay,\n  onClick,\n  ...props\n}: VoiceSelectorPreviewProps) => {\n  const handleClick = useCallback(\n    (event: React.MouseEvent<HTMLButtonElement>) => {\n      event.stopPropagation()\n      onClick?.(event)\n      onPlay?.()\n    },\n    [onClick, onPlay]\n  )\n\n  let icon = <PlayIcon className=\"size-3\" />\n\n  if (loading) {\n    icon = <Spinner className=\"size-3\" />\n  } else if (playing) {\n    icon = <PauseIcon className=\"size-3\" />\n  }\n\n  return (\n    <Button\n      aria-label={playing ? \"Pause preview\" : \"Play preview\"}\n      className={cn(\"size-6\", className)}\n      disabled={loading}\n      onClick={handleClick}\n      size=\"icon-sm\"\n      type=\"button\"\n      variant=\"outline\"\n      {...props}\n    >\n      {icon}\n    </Button>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/command.tsx",
          "target": "@components/ai-elements/_ui/command.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ai-elements/_ui/dialog\"\nimport { cn } from \"@/lib/utils\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\nimport * as React from \"react\"\n\nfunction Command({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\n        \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandDialog({\n  title = \"Command Palette\",\n  description = \"Search for a command to run...\",\n  children,\n  className,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string\n  description?: string\n  className?: string\n  showCloseButton?: boolean\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent\n        className={cn(\"overflow-hidden p-0\", className)}\n        showCloseButton={showCloseButton}\n      >\n        <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction CommandInput({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div\n      data-slot=\"command-input-wrapper\"\n      className=\"flex h-9 items-center gap-2 border-b px-3\"\n    >\n      <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n      <CommandPrimitive.Input\n        data-slot=\"command-input\"\n        className={cn(\n          \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n          className\n        )}\n        {...props}\n      />\n    </div>\n  )\n}\n\nfunction CommandList({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(\n        \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandEmpty({\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return (\n    <CommandPrimitive.Empty\n      data-slot=\"command-empty\"\n      className=\"py-6 text-center text-sm\"\n      {...props}\n    />\n  )\n}\n\nfunction CommandGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(\"bg-border -mx-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandItem({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"command-shortcut\"\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandInput,\n  CommandList,\n  CommandEmpty,\n  CommandGroup,\n  CommandItem,\n  CommandShortcut,\n  CommandSeparator,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/dialog.tsx",
          "target": "@components/ai-elements/_ui/dialog.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as DialogPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction Dialog({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n  showCloseButton?: boolean\n}) {\n  return (\n    <DialogPortal data-slot=\"dialog-portal\">\n      <DialogOverlay />\n      <DialogPrimitive.Content\n        data-slot=\"dialog-content\"\n        className={cn(\n          \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <DialogPrimitive.Close\n            data-slot=\"dialog-close\"\n            className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n          >\n            <XIcon />\n            <span className=\"sr-only\">Close</span>\n          </DialogPrimitive.Close>\n        )}\n      </DialogPrimitive.Content>\n    </DialogPortal>\n  )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"text-lg leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/spinner.tsx",
          "target": "@components/ai-elements/_ui/spinner.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { Loader2Icon } from \"lucide-react\"\n\nfunction Spinner({ className, ...props }: React.ComponentProps<\"svg\">) {\n  return (\n    <Loader2Icon\n      role=\"status\"\n      aria-label=\"Loading\"\n      className={cn(\"size-4 animate-spin\", className)}\n      {...props}\n    />\n  )\n}\n\nexport { Spinner }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "ai-elements-web-preview",
      "type": "registry:block",
      "title": "Ai Elements Web Preview",
      "description": "web preview",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "radix-ui@1.6.7",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/ai-elements/web-preview.tsx",
          "target": "@components/ai-elements/web-preview.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Button } from \"@/components/ai-elements/_ui/button\"\nimport {\n  Collapsible,\n  CollapsibleContent,\n  CollapsibleTrigger,\n} from \"@/components/ai-elements/_ui/collapsible\"\nimport { Input } from \"@/components/ai-elements/_ui/input\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ai-elements/_ui/tooltip\"\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport type { ComponentProps, ReactNode } from \"react\"\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useMemo,\n  useState,\n} from \"react\"\n\nexport interface WebPreviewContextValue {\n  url: string\n  setUrl: (url: string) => void\n  consoleOpen: boolean\n  setConsoleOpen: (open: boolean) => void\n}\n\nconst WebPreviewContext = createContext<WebPreviewContextValue | null>(null)\n\nconst useWebPreview = () => {\n  const context = useContext(WebPreviewContext)\n  if (!context) {\n    throw new Error(\"WebPreview components must be used within a WebPreview\")\n  }\n  return context\n}\n\nexport type WebPreviewProps = ComponentProps<\"div\"> & {\n  defaultUrl?: string\n  onUrlChange?: (url: string) => void\n}\n\nexport const WebPreview = ({\n  className,\n  children,\n  defaultUrl = \"\",\n  onUrlChange,\n  ...props\n}: WebPreviewProps) => {\n  const [url, setUrl] = useState(defaultUrl)\n  const [consoleOpen, setConsoleOpen] = useState(false)\n\n  const handleUrlChange = useCallback(\n    (newUrl: string) => {\n      setUrl(newUrl)\n      onUrlChange?.(newUrl)\n    },\n    [onUrlChange]\n  )\n\n  const contextValue = useMemo<WebPreviewContextValue>(\n    () => ({\n      consoleOpen,\n      setConsoleOpen,\n      setUrl: handleUrlChange,\n      url,\n    }),\n    [consoleOpen, handleUrlChange, url]\n  )\n\n  return (\n    <WebPreviewContext.Provider value={contextValue}>\n      <div\n        className={cn(\n          \"bg-card flex size-full flex-col rounded-lg border\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n      </div>\n    </WebPreviewContext.Provider>\n  )\n}\n\nexport type WebPreviewNavigationProps = ComponentProps<\"div\">\n\nexport const WebPreviewNavigation = ({\n  className,\n  children,\n  ...props\n}: WebPreviewNavigationProps) => (\n  <div\n    className={cn(\"flex items-center gap-1 border-b p-2\", className)}\n    {...props}\n  >\n    {children}\n  </div>\n)\n\nexport type WebPreviewNavigationButtonProps = ComponentProps<typeof Button> & {\n  tooltip?: string\n}\n\nexport const WebPreviewNavigationButton = ({\n  onClick,\n  disabled,\n  tooltip,\n  children,\n  ...props\n}: WebPreviewNavigationButtonProps) => (\n  <TooltipProvider>\n    <Tooltip>\n      <TooltipTrigger asChild>\n        <Button\n          className=\"hover:text-foreground h-8 w-8 p-0\"\n          disabled={disabled}\n          onClick={onClick}\n          size=\"sm\"\n          variant=\"ghost\"\n          {...props}\n        >\n          {children}\n        </Button>\n      </TooltipTrigger>\n      <TooltipContent>\n        <p>{tooltip}</p>\n      </TooltipContent>\n    </Tooltip>\n  </TooltipProvider>\n)\n\nexport type WebPreviewUrlProps = ComponentProps<typeof Input>\n\nexport const WebPreviewUrl = ({\n  value,\n  onChange,\n  onKeyDown,\n  ...props\n}: WebPreviewUrlProps) => {\n  const { url, setUrl } = useWebPreview()\n  const [prevUrl, setPrevUrl] = useState(url)\n  const [inputValue, setInputValue] = useState(url)\n\n  // Sync input value with context URL when it changes externally (derived state pattern)\n  if (url !== prevUrl) {\n    setPrevUrl(url)\n    setInputValue(url)\n  }\n\n  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n    setInputValue(event.target.value)\n    onChange?.(event)\n  }\n\n  const handleKeyDown = useCallback(\n    (event: React.KeyboardEvent<HTMLInputElement>) => {\n      if (event.key === \"Enter\") {\n        const target = event.target as HTMLInputElement\n        setUrl(target.value)\n      }\n      onKeyDown?.(event)\n    },\n    [setUrl, onKeyDown]\n  )\n\n  return (\n    <Input\n      className=\"h-8 flex-1 text-sm\"\n      onChange={onChange ?? handleChange}\n      onKeyDown={handleKeyDown}\n      placeholder=\"Enter URL...\"\n      value={value ?? inputValue}\n      {...props}\n    />\n  )\n}\n\nexport type WebPreviewBodyProps = ComponentProps<\"iframe\"> & {\n  loading?: ReactNode\n}\n\nexport const WebPreviewBody = ({\n  className,\n  loading,\n  src,\n  ...props\n}: WebPreviewBodyProps) => {\n  const { url } = useWebPreview()\n\n  return (\n    <div className=\"flex-1\">\n      <iframe\n        className={cn(\"size-full\", className)}\n        // oxlint-disable-next-line eslint-plugin-react(iframe-missing-sandbox)\n        sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-presentation\"\n        src={(src ?? url) || undefined}\n        title=\"Preview\"\n        {...props}\n      />\n      {loading}\n    </div>\n  )\n}\n\nexport type WebPreviewConsoleProps = ComponentProps<\"div\"> & {\n  logs?: {\n    level: \"log\" | \"warn\" | \"error\"\n    message: string\n    timestamp: Date\n  }[]\n}\n\nexport const WebPreviewConsole = ({\n  className,\n  logs = [],\n  children,\n  ...props\n}: WebPreviewConsoleProps) => {\n  const { consoleOpen, setConsoleOpen } = useWebPreview()\n\n  return (\n    <Collapsible\n      className={cn(\"bg-muted/50 border-t font-mono text-sm\", className)}\n      onOpenChange={setConsoleOpen}\n      open={consoleOpen}\n      {...props}\n    >\n      <CollapsibleTrigger asChild>\n        <Button\n          className=\"hover:bg-muted/50 flex w-full items-center justify-between p-4 text-left font-medium\"\n          variant=\"ghost\"\n        >\n          Console\n          <ChevronDownIcon\n            className={cn(\n              \"h-4 w-4 transition-transform duration-200\",\n              consoleOpen && \"rotate-180\"\n            )}\n          />\n        </Button>\n      </CollapsibleTrigger>\n      <CollapsibleContent\n        className={cn(\n          \"px-4 pb-4\",\n          \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=open]:animate-in outline-none\"\n        )}\n      >\n        <div className=\"max-h-48 space-y-1 overflow-y-auto\">\n          {logs.length === 0 ? (\n            <p className=\"text-muted-foreground\">No console output</p>\n          ) : (\n            logs.map((log) => (\n              <div\n                className={cn(\n                  \"text-xs\",\n                  log.level === \"error\" && \"text-destructive\",\n                  log.level === \"warn\" && \"text-yellow-600\",\n                  log.level === \"log\" && \"text-foreground\"\n                )}\n                key={`${log.timestamp.getTime()}-${log.level}-${log.message}`}\n              >\n                <span className=\"text-muted-foreground\">\n                  {log.timestamp.toLocaleTimeString()}\n                </span>{\" \"}\n                {log.message}\n              </div>\n            ))\n          )}\n          {children}\n        </div>\n      </CollapsibleContent>\n    </Collapsible>\n  )\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/button.tsx",
          "target": "@components/ai-elements/_ui/button.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot as SlotPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n        ghost:\n          \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n        \"icon-sm\": \"size-8\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? SlotPrimitive.Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"
        },
        {
          "path": "lib/utils.ts",
          "target": "@lib/utils.ts",
          "type": "registry:lib",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getSitePathname(\n  pathname: string,\n  basePath = process.env.NEXT_PUBLIC_BASE_PATH || \"\"\n) {\n  const base = basePath.replace(/\\/+$/, \"\")\n  const path =\n    pathname === base || pathname.startsWith(`${base}/`)\n      ? pathname.slice(base.length)\n      : pathname\n  return path.replace(/\\/+$/, \"\") || \"/\"\n}\n\n/**\n * Get the base URL depending on the current environment\n */\nexport function getBaseUrl() {\n  const basePath = (process.env.NEXT_PUBLIC_BASE_PATH || \"\").replace(/\\/$/, \"\")\n  const withBasePath = (url: string) => {\n    const base = url.replace(/\\/$/, \"\")\n    return basePath && !base.endsWith(basePath) ? `${base}${basePath}` : base\n  }\n  // For server-side rendering, we need to use environment variables\n  if (typeof window === \"undefined\") {\n    // Check for Vercel-specific environment variables\n    // Production URL takes precedence if available (works in all environments)\n    if (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`\n      )\n    }\n\n    // For branch deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {\n      return withBasePath(\n        `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`\n      )\n    }\n\n    // For regular deployments\n    if (process.env.NEXT_PUBLIC_VERCEL_URL) {\n      return withBasePath(`https://${process.env.NEXT_PUBLIC_VERCEL_URL}`)\n    }\n\n    // Legacy support\n    if (process.env.VERCEL_URL) {\n      return withBasePath(`https://${process.env.VERCEL_URL}`)\n    }\n\n    // Fall back to explicitly set environment variables\n    if (process.env.NEXT_PUBLIC_BASE_URL) {\n      return withBasePath(process.env.NEXT_PUBLIC_BASE_URL)\n    }\n\n    // Default for development - check PORT env var first\n    const port = process.env.PORT || 3000\n    return withBasePath(\n      process.env.NODE_ENV === \"development\" ? `http://localhost:${port}` : \"\"\n    )\n  }\n\n  // For client-side, we can just use the browser's location\n  return withBasePath(window.location.origin)\n}\n"
        },
        {
          "path": "components/ai-elements/_ui/collapsible.tsx",
          "target": "@components/ai-elements/_ui/collapsible.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\n\nfunction Collapsible({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleTrigger\n      data-slot=\"collapsible-trigger\"\n      {...props}\n    />\n  )\n}\n\nfunction CollapsibleContent({\n  ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n  return (\n    <CollapsiblePrimitive.CollapsibleContent\n      data-slot=\"collapsible-content\"\n      {...props}\n    />\n  )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
        },
        {
          "path": "components/ai-elements/_ui/input.tsx",
          "target": "@components/ai-elements/_ui/input.tsx",
          "type": "registry:component",
          "content": "import { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      className={cn(\n        \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n        \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n        \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Input }\n"
        },
        {
          "path": "components/ai-elements/_ui/tooltip.tsx",
          "target": "@components/ai-elements/_ui/tooltip.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\"\nimport * as React from \"react\"\n\nfunction TooltipProvider({\n  delayDuration = 0,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return (\n    <TooltipPrimitive.Provider\n      data-slot=\"tooltip-provider\"\n      delayDuration={delayDuration}\n      {...props}\n    />\n  )\n}\n\nfunction Tooltip({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 0,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          \"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/ai-elements/LICENSE",
          "target": "@components/ai-elements/LICENSE",
          "type": "registry:file",
          "content": "Copyright 2023 Vercel, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
        },
        {
          "path": "components/ai-elements/SOURCE.json",
          "target": "@components/ai-elements/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Vercel AI Elements\",\n  \"repository\": \"https://github.com/vercel/ai-elements\",\n  \"commit\": \"6a9d5b1822ffb10bba4bd97175f01edd7d8651cd\",\n  \"license\": \"Apache-2.0\",\n  \"sourceDirectories\": [\n    \"packages/elements/src\",\n    \"packages/examples/src\",\n    \"packages/shadcn-ui/components/ui\"\n  ],\n  \"changes\": [\n    \"Rewritten local import paths\",\n    \"Constrained the Plan and Environment Variables gallery examples to the available preview width\",\n    \"Allowed Environment Variables values and audio ranges to shrink on narrow screens\",\n    \"Replaced the remote Web Preview example page with an equivalent local srcDoc fixture\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/ai-elements/_ui/LICENSE",
          "target": "@components/ai-elements/_ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2023 shadcn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/ai-elements/_ui/NOTICE.md",
          "target": "@components/ai-elements/_ui/NOTICE.md",
          "type": "registry:file",
          "content": "# shadcn/ui primitives\n\nThese local primitives are derived from shadcn/ui and retain its MIT license.\nThey were copied from the Vercel AI Elements pinned source tree so its public\ncomponents keep their documented variants, states, and styling.\n\nSource: https://github.com/shadcn-ui/ui\n"
        }
      ],
      "categories": [
        "AI Elements"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "boardui-agent-thinking",
      "type": "registry:block",
      "title": "Boardui Agent Thinking",
      "description": "agent thinking",
      "dependencies": [
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/boardui/application/agent-thinking/agent-thinking.tsx",
          "target": "@components/boardui/application/agent-thinking/agent-thinking.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Agent Thinking — the agent \"thinking\" state that sits above a chat composer\n * while a response is being worked on.\n *\n * Four curated variants:\n * - `wave`     dot grid with a diagonal wavefront gliding top-left → bottom-right\n * - `spin`     dot grid with a bright head orbiting the grid clockwise\n * - `stars`    sparkles twinkling in and out with a stagger\n * - `infinity` a comet trail sweeping a figure-eight\n *\n * Every variant pairs the indicator with a shimmering label and an elapsed\n * timer that starts when the loader mounts. Shimmer and CSS animations fall\n * back to static rendering under `prefers-reduced-motion` (see globals.css).\n */\n\nexport type AgentThinkingVariant = \"wave\" | \"spin\" | \"stars\" | \"infinity\";\nexport type AgentThinkingTone = \"subtle\" | \"default\" | \"primary\" | \"accent\";\n\nexport interface AgentThinkingProps {\n  variant?: AgentThinkingVariant;\n  /** Status label, e.g. \"Thinking\" or \"Searching the docs\". */\n  label?: string;\n  /** Tone of the indicator + label. Defaults per variant (`stars` is subtle). */\n  tone?: AgentThinkingTone;\n  /** Animated highlight traveling across the label. */\n  shimmer?: boolean;\n  /** Elapsed seconds since mount, rendered after the label. */\n  showTimer?: boolean;\n  className?: string;\n}\nconst TONE_COLORS: Record<AgentThinkingTone, string> = {\n  subtle: \"var(--color-text-tertiary)\",\n  default: \"var(--color-text-secondary)\",\n  primary: \"var(--color-text-primary)\",\n  accent: \"var(--color-blue-500)\",\n};\n\nconst VARIANT_TONE: Record<AgentThinkingVariant, AgentThinkingTone> = {\n  wave: \"default\",\n  spin: \"default\",\n  stars: \"subtle\",\n  infinity: \"default\",\n};\n\n/* ------------------------------------------------------------------- dots */\n\nconst DOTS_GRID = 3;\nconst DOTS_SIZE = 4;\nconst DOTS_GAP = 2;\nconst DOTS_TICK_MS = 80;\nconst DOTS_FADE_MS = 220;\nconst DOTS_TRAIL = 0.3;\nconst DOTS_MIN_OPACITY = 0.12;\nconst DOTS_PHASE_STEP = 1 / 8;\n\n// Static first frame: identical on server and client, and the resting state\n// under prefers-reduced-motion.\nconst DOTS_SEED = [0.55, 0.3, 0.15, 0.85, 0.55, 0.3, 1, 0.85, 0.55];\n\n/**\n * How far along the pattern's travel direction each cell sits, in [0, 1).\n * The wave scalar is compressed below 1 so the phase wrap reads as the front\n * leaving the grid and re-entering; the spin angle is naturally cyclic.\n */\nfunction dotScalar(variant: \"wave\" | \"spin\", col: number, row: number) {\n  const m = DOTS_GRID - 1;\n  if (variant === \"wave\") {\n    return ((col + row) / (2 * m)) * (DOTS_GRID / (DOTS_GRID + 1));\n  }\n  const center = m / 2;\n  return (Math.atan2(row - center, col - center) / (2 * Math.PI) + 1) % 1;\n}\n\nfunction dotOpacities(variant: \"wave\" | \"spin\", phase: number) {\n  return Array.from({ length: DOTS_GRID * DOTS_GRID }, (_, i) => {\n    const s = dotScalar(variant, i % DOTS_GRID, Math.floor(i / DOTS_GRID));\n    // Comet: bright head at the phase front, tail fading behind it.\n    const behind = (phase - s + 1) % 1;\n    const lit = Math.max(0, 1 - behind / DOTS_TRAIL) ** 1.5;\n    return DOTS_MIN_OPACITY + (1 - DOTS_MIN_OPACITY) * lit;\n  });\n}\n\nfunction DotsIndicator({ variant }: { variant: \"wave\" | \"spin\" }) {\n  const [opacities, setOpacities] = useState<number[]>(DOTS_SEED);\n\n  useEffect(() => {\n    if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n    let phase = 0;\n    const id = window.setInterval(() => {\n      phase = (phase + DOTS_PHASE_STEP) % 1;\n      setOpacities(dotOpacities(variant, phase));\n    }, DOTS_TICK_MS);\n    return () => window.clearInterval(id);\n  }, [variant]);\n\n  return (\n    <span\n      aria-hidden\n      className=\"grid shrink-0\"\n      style={{\n        gridTemplateColumns: `repeat(${DOTS_GRID}, ${DOTS_SIZE}px)`,\n        gap: DOTS_GAP,\n      }}\n    >\n      {opacities.map((opacity, i) => (\n        <span\n          key={i}\n          className=\"rounded-[1px] bg-current\"\n          style={{\n            width: DOTS_SIZE,\n            height: DOTS_SIZE,\n            opacity,\n            transition: `opacity ${DOTS_FADE_MS}ms ease`,\n          }}\n        />\n      ))}\n    </span>\n  );\n}\n\n/* ------------------------------------------------------------------ stars */\n\nconst STAR_PERIOD_S = 1.4;\nconst STAR_SIZE = 14;\nconst STAR_COUNT = 5;\nconst STAR_LAYOUT = [\n  { x: 50, y: 46, scale: 1 },\n  { x: 18, y: 22, scale: 0.55 },\n  { x: 82, y: 26, scale: 0.45 },\n  { x: 78, y: 76, scale: 0.55 },\n  { x: 22, y: 78, scale: 0.4 },\n];\nconst STAR_PATH = \"M12 0C13 7 17 11 24 12C17 13 13 17 12 24C11 17 7 13 0 12C7 11 11 7 12 0Z\";\n\nfunction StarsIndicator() {\n  const box = STAR_SIZE * 1.5;\n  return (\n    <span\n      aria-hidden\n      className=\"bui-agent-thinking-stars relative block shrink-0\"\n      style={{ width: box, height: box }}\n    >\n      {STAR_LAYOUT.slice(0, STAR_COUNT).map((star, i) => {\n        const size = STAR_SIZE * star.scale;\n        return (\n          <svg\n            key={i}\n            viewBox=\"0 0 24 24\"\n            className=\"bui-agent-thinking-star absolute\"\n            style={{\n              width: size,\n              height: size,\n              left: `${star.x}%`,\n              top: `${star.y}%`,\n              marginLeft: -size / 2,\n              marginTop: -size / 2,\n              animationDuration: `${STAR_PERIOD_S}s`,\n              animationDelay: `${(i * STAR_PERIOD_S * 0.7) / STAR_COUNT}s`,\n            }}\n          >\n            <path d={STAR_PATH} fill=\"currentColor\" />\n          </svg>\n        );\n      })}\n    </span>\n  );\n}\n\n/* --------------------------------------------------------------- infinity */\n\nconst INFINITY_WIDTH = 32;\nconst INFINITY_TRAIL = 11;\nconst INFINITY_STROKE = 2.75;\nconst INFINITY_DURATION_S = 1.2;\nconst INFINITY_PATH =\n  \"M28 14C33 5 47 5 47 14C47 23 33 23 28 14C23 5 9 5 9 14C9 23 23 23 28 14Z\";\n\nfunction InfinityIndicator() {\n  return (\n    <svg\n      aria-hidden\n      viewBox=\"0 0 56 28\"\n      className=\"shrink-0\"\n      // The figure-eight spans x 9-47 of the 56-wide viewBox, so the svg box\n      // carries ~4px of dead space per side at this width; pull it back in so\n      // the label sits at the loader's real gap.\n      style={{ width: INFINITY_WIDTH, height: INFINITY_WIDTH / 2, margin: \"0 -4px\" }}\n    >\n      <path\n        d={INFINITY_PATH}\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={INFINITY_STROKE}\n        opacity={0.15}\n      />\n      <path\n        d={INFINITY_PATH}\n        pathLength={100}\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={INFINITY_STROKE}\n        strokeLinecap=\"round\"\n        strokeDasharray={`${INFINITY_TRAIL} ${100 - INFINITY_TRAIL}`}\n        className=\"bui-agent-thinking-comet\"\n        style={{ animationDuration: `${INFINITY_DURATION_S}s` }}\n      />\n    </svg>\n  );\n}\n\n/* ------------------------------------------------------------------ timer */\n\nfunction ElapsedTimer() {\n  const [elapsed, setElapsed] = useState(0);\n\n  useEffect(() => {\n    const started = performance.now();\n    const id = window.setInterval(\n      () => setElapsed((performance.now() - started) / 1000),\n      100,\n    );\n    return () => window.clearInterval(id);\n  }, []);\n\n  return (\n    <span className=\"font-mono text-caption-1-regular text-text-tertiary tabular-nums\">\n      {elapsed.toFixed(1)}s\n    </span>\n  );\n}\n\n/* ----------------------------------------------------------------- loader */\n\nexport function AgentThinking({\n  variant = \"wave\",\n  label = \"Thinking\",\n  tone,\n  shimmer = true,\n  showTimer = true,\n  className,\n}: AgentThinkingProps) {\n  const color = TONE_COLORS[tone ?? VARIANT_TONE[variant]];\n\n  return (\n    <div\n      role=\"status\"\n      className={cx(\"flex items-center gap-2.5\", className)}\n      style={{ color, \"--bui-agent-thinking-tone\": color } as CSSProperties}\n    >\n      {(variant === \"wave\" || variant === \"spin\") && <DotsIndicator variant={variant} />}\n      {variant === \"stars\" && <StarsIndicator />}\n      {variant === \"infinity\" && <InfinityIndicator />}\n      <span\n        aria-label={label}\n        className={cx(\"text-body-medium\", shimmer && \"bui-agent-thinking-label\")}\n      >\n        {label}\n      </span>\n      {showTimer && <ElapsedTimer />}\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "BoardUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "boardui-composer-loader",
      "type": "registry:block",
      "title": "Boardui Composer Loader",
      "description": "composer loader",
      "dependencies": [
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/boardui/application/composer-loader/composer-loader.tsx",
          "target": "@components/boardui/application/composer-loader/composer-loader.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useId, useRef, useState } from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Composer Loader — a loading state that wraps a chat composer while the agent\n * works: an iridescent light band orbiting the pill's rim with a soft bloom\n * bleeding inward.\n *\n * The band is dash segments on an SVG stroke of the pill shape\n * (pathLength-normalized, so it travels at constant speed and bends around\n * the end caps), drawn at three scales — crisp line, tight glow, wide bloom —\n * with the sharp line leading and every soft layer's head pulled back behind\n * the tip.\n *\n * The component paints the pill surface itself and layers the light above\n * it, so the wrapped composer must not paint its own background:\n *\n *   <ComposerLoader active={isWaitingForReply}>\n *     <Composer className=\"bg-transparent shadow-none\" />\n *   </ComposerLoader>\n *\n * `active` fades the whole effect in and out (450ms), so toggling it on\n * send / reply reads as the composer lighting up rather than snapping.\n */\n\nexport interface ComposerLoaderProps {\n  children: ReactNode;\n  /** Show the light. Fades in/out — flip it while awaiting a response. */\n  active?: boolean;\n  /** Four gradient colors, spread across the pill left → right. */\n  colors?: [string, string, string, string];\n  /** Seconds per full lap. */\n  speed?: number;\n  /** Overall light opacity. */\n  intensity?: number;\n  /** How far the bloom bleeds inward from the rim, px. */\n  bloom?: number;\n  /** Bloom layer opacity. */\n  bloomStrength?: number;\n  /** How much of the perimeter the band occupies, degrees (of 360). */\n  arc?: number;\n  /** Reverse the travel direction. */\n  reverse?: boolean;\n  /** Corner radius, px. Defaults to a full pill. */\n  radius?: number;\n  /** Width of the crisp line, px; the tight glow scales with it. */\n  line?: number;\n  /** Draw the wide bloom alone, no line or tight glow: a soft wash for a beam to lead. */\n  bloomOnly?: boolean;\n  /** Paint the pill surface behind the light (on by default). */\n  surface?: boolean;\n  /**\n   * Fade the band's two ends instead of cutting them, 0–1: the fraction of\n   * the band's length that ramps. Each layer is stacked as shorter, centred\n   * copies at a fraction of its opacity; the blur melts the steps together.\n   */\n  taper?: number;\n  /** How the light composites over what's beneath, e.g. `screen` to read as light on a surface. */\n  blend?: CSSProperties[\"mixBlendMode\"];\n  /**\n   * Moves the band forward along the lap, as a fraction of the perimeter\n   * (0–1). Lets two loaders on one pill line up: a short beam with\n   * `offset` equal to the difference of the two arcs (as fractions) leads\n   * a wider glow tip to tip.\n   */\n  offset?: number;\n  className?: string;\n}\nconst DEFAULT_COLORS: [string, string, string, string] = [\n  \"#5eead4\",\n  \"#46baec\",\n  \"#e633a4\",\n  \"#00faa7\",\n];\n\nfunction hexTriplet(hex: string) {\n  return [\n    parseInt(hex.slice(1, 3), 16),\n    parseInt(hex.slice(3, 5), 16),\n    parseInt(hex.slice(5, 7), 16),\n  ];\n}\n\nexport function ComposerLoader({\n  children,\n  active = true,\n  colors = DEFAULT_COLORS,\n  speed = 4.5,\n  intensity = 0.7,\n  bloom = 16,\n  bloomStrength = 0.3,\n  arc = 120,\n  reverse = false,\n  radius,\n  line = 2.5,\n  bloomOnly = false,\n  surface = true,\n  taper = 0,\n  blend,\n  offset = 0,\n  className,\n}: ComposerLoaderProps) {\n  const gradientId = `bui-cl-${useId().replace(/[^a-zA-Z0-9]/g, \"\")}`;\n  const clipRef = useRef<HTMLSpanElement>(null);\n  const [box, setBox] = useState({ w: 640, h: 52 });\n\n  useEffect(() => {\n    const el = clipRef.current;\n    if (!el) return;\n    const observer = new ResizeObserver(() =>\n      setBox({ w: Math.max(1, el.clientWidth), h: Math.max(1, el.clientHeight) }),\n    );\n    observer.observe(el);\n    return () => observer.disconnect();\n  }, []);\n\n  const [c0, c1, c2, c3] = colors;\n  // Gradient center: pure blend of the middle colors, so the band never\n  // washes out to white.\n  const mid = `rgb(${hexTriplet(c1)\n    .map((v, i) => Math.round((v + hexTriplet(c2)[i]) / 2))\n    .join(\",\")})`;\n\n  const band = (arc / 360) * 100;\n  const rx = radius ?? box.h / 2;\n  const cornerRadius = radius ?? 9999;\n  const direction = reverse ? \"reverse\" : \"normal\";\n\n  // Path units per px, for pulling each soft layer's head behind the tip.\n  // Rounded-rect perimeter: straight runs plus the four corner arcs (for the\n  // default pill, rx = h/2 and this reduces to 2(w−h) + πh).\n  const cornerR = Math.min(rx, box.w / 2, box.h / 2);\n  const perimeter = Math.max(1, 2 * (box.w + box.h) - 8 * cornerR + 2 * Math.PI * cornerR);\n  const pxUnits = (px: number) => (px * 100) / perimeter;\n  // A layer's delay is its phase: the larger the phase, the further BACK\n  // along the lap the band sits (a negative delay is a head start). So\n  // moving a band forward, `offset` included, means subtracting.\n  const dashPhase = (len: number, backPx: number) =>\n    (reverse ? pxUnits(backPx) : len - band + pxUnits(backPx)) - offset * 100;\n\n  // Tapering stacks each layer as shorter, centred copies: the ramp at each\n  // end is a staircase with one step per copy, so it takes many copies and\n  // a little blur on the crisp line for the steps to melt into a gradient.\n  const TAPER_STEPS = 14;\n  const CRISP_BLUR = taper > 0 ? Math.max(0.5, line * 0.8) : 0.5;\n  const stroke = (width: number, blur: number, opacity: number, dashLen: number, backPx: number) => {\n    const copies = taper > 0 ? TAPER_STEPS : 1;\n    return Array.from({ length: copies }, (_, index) => {\n      // Copy 0 is the full band; each next one is shorter and moved forward\n      // by half the difference, so all of them share one midpoint and the\n      // ends thin out step by step.\n      const len = dashLen * (1 - (taper * index) / copies);\n      const phase = dashPhase(dashLen, backPx) - (dashLen - len) / 2;\n      return (\n        <rect\n          key={index}\n          x={0}\n          y={0}\n          width={box.w}\n          height={box.h}\n          rx={rx}\n          pathLength={100}\n          fill=\"none\"\n          stroke={`url(#${gradientId})`}\n          strokeWidth={width}\n          strokeLinecap=\"round\"\n          strokeDasharray={`${len} ${100 - len}`}\n          className=\"bui-composer-loader-rect\"\n          // SVG-native blur, not CSS filter: WebKit (iOS Safari and every iPhone\n          // browser) ignores CSS filters on individual SVG elements, which\n          // rendered the whole light razor-sharp on phones.\n          filter={blur > 0 ? `url(#${gradientId}-b${String(blur).replace(\".\", \"_\")})` : undefined}\n          style={{\n            opacity: opacity / copies,\n            animation: `bui-composer-loader-dash ${speed}s linear ${(phase * speed) / 100}s infinite ${direction}`,\n          }}\n        />\n      );\n    });\n  };\n\n  /** One feGaussianBlur per blur radius the layers use. The region is\n   *  widened well past the stroke so the blur never clips at the filter\n   *  bounds. */\n  const blurFilter = (radius: number) => (\n    <filter\n      key={radius}\n      id={`${gradientId}-b${String(radius).replace(\".\", \"_\")}`}\n      x=\"-50%\"\n      y=\"-50%\"\n      width=\"200%\"\n      height=\"200%\"\n    >\n      <feGaussianBlur stdDeviation={radius} />\n    </filter>\n  );\n\n  return (\n    <div className={cx(\"relative\", className)}>\n      {surface && (\n        <span\n          aria-hidden\n          className=\"absolute inset-0 bg-background-primary-default shadow-xs\"\n          style={{ borderRadius: cornerRadius }}\n        />\n      )}\n\n      <span\n        ref={clipRef}\n        aria-hidden\n        className=\"pointer-events-none absolute inset-0 overflow-hidden\"\n        style={{\n          borderRadius: cornerRadius,\n          opacity: active ? 1 : 0,\n          transition: \"opacity 450ms ease\",\n          mixBlendMode: blend,\n        }}\n      >\n        <svg\n          width=\"100%\"\n          height=\"100%\"\n          viewBox={`0 0 ${box.w} ${box.h}`}\n          preserveAspectRatio=\"none\"\n          style={{ opacity: intensity }}\n        >\n          <defs>\n            <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\">\n              <stop offset=\"0%\" stopColor={c0} />\n              <stop offset=\"30%\" stopColor={c1} />\n              <stop offset=\"50%\" stopColor={mid} />\n              <stop offset=\"70%\" stopColor={c2} />\n              <stop offset=\"100%\" stopColor={c3} />\n            </linearGradient>\n            {[14, 6, CRISP_BLUR].map(blurFilter)}\n          </defs>\n          {/* wide bloom bleeding inward (outer half clipped by the pill) */}\n          {bloom > 0 && stroke(bloom * 2, 14, bloomStrength, band * 0.9, bloom + 16)}\n          {/* tight glow */}\n          {!bloomOnly && stroke(line * 3.2, 6, 0.8, band * 0.95, 10)}\n          {/* crisp refraction line, tip leading */}\n          {!bloomOnly && stroke(line, CRISP_BLUR, 1, band, 0)}\n        </svg>\n      </span>\n\n      <div className=\"relative\">{children}</div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "BoardUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "boardui-agent-chat",
      "type": "registry:block",
      "title": "Boardui Agent Chat",
      "description": "agent chat",
      "dependencies": [
        "@ai-sdk/react@3.0.283",
        "@remixicon/react@^4.9.0",
        "ai@6.0.280",
        "motion@12.26.2",
        "react-aria-components@^1.21.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/boardui/application/agent-chat/agent-chat.tsx",
          "target": "@components/boardui/application/agent-chat/agent-chat.tsx",
          "type": "registry:component",
          "content": "\"use client\"\n\nimport { AgentChatActions } from \"@/components/boardui/application/agent-chat/agent-chat-actions\"\nimport {\n  AgentChatHistory,\n  type ChatThreadSummary,\n} from \"@/components/boardui/application/agent-chat/agent-chat-history\"\nimport { AgentMessage } from \"@/components/boardui/application/agent-chat/agent-chat-message\"\nimport { AgentComposer } from \"@/components/boardui/application/agent-chat/agent-composer\"\nimport { DemoTransport } from \"@/components/boardui/application/agent-chat/demo-transport\"\nimport { AgentThinking } from \"@/components/boardui/application/agent-thinking/agent-thinking\"\nimport { cx } from \"@/components/boardui/utils/cx\"\nimport { useChat } from \"@ai-sdk/react\"\nimport { RiHistoryLine } from \"@remixicon/react\"\nimport type { UIMessage } from \"ai\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nconst STORAGE_KEY = \"agents-kit:boardui-chat-threads\"\nconst MAX_THREADS = 30\nconst SUGGESTIONS = [\n  \"Explain what this starter does\",\n  \"Write a product update in three sentences\",\n  \"Give me five names for a scheduling app\",\n]\n\ninterface StoredThread extends ChatThreadSummary {\n  messages: UIMessage[]\n  messageAt: Record<string, number>\n}\n\n/**\n * BoardUI's free chat starter, adapted for the gallery to use its local demo\n * transport only. It keeps the original transcript, composer, history, share,\n * export, rename, unread, delete, speech and motion behavior without requiring\n * an API route or model key.\n */\nexport function AgentChat({ className }: { className?: string }) {\n  const [input, setInput] = useState(\"\")\n  const [threads, setThreads] = useState<StoredThread[]>([])\n  const [activeId, setActiveId] = useState(\"\")\n  const [activeUpdatedAt, setActiveUpdatedAt] = useState(0)\n  const [activeTitle, setActiveTitle] = useState<string | null>(null)\n  const [messageAt, setMessageAt] = useState<Record<string, number>>({})\n  const [restored, setRestored] = useState(false)\n  const [historyOpen, setHistoryOpen] = useState(false)\n  const scrollRef = useRef<HTMLDivElement>(null)\n  const [transport] = useState(() => new DemoTransport())\n  const { messages, sendMessage, setMessages, status, stop, error } = useChat({\n    transport,\n  })\n  const busy = status === \"submitted\" || status === \"streaming\"\n\n  useEffect(() => {\n    setActiveId(newThreadId())\n    setThreads(orderThreads(readThreads()))\n    setRestored(true)\n  }, [])\n\n  useEffect(() => {\n    const unseen = messages.filter(\n      (message) => messageAt[message.id] === undefined\n    )\n    if (unseen.length === 0) return\n    const now = Date.now()\n    setMessageAt((previous) => ({\n      ...previous,\n      ...Object.fromEntries(unseen.map((message) => [message.id, now])),\n    }))\n  }, [messages, messageAt])\n\n  const liveThread = useMemo<StoredThread | null>(\n    () =>\n      activeId && messages.length > 0\n        ? {\n            id: activeId,\n            title: activeTitle ?? deriveTitle(messages),\n            updatedAt: activeUpdatedAt,\n            messages,\n            messageAt,\n          }\n        : null,\n    [activeId, activeTitle, activeUpdatedAt, messageAt, messages]\n  )\n  const allThreads = useMemo(\n    () =>\n      orderThreads(\n        liveThread\n          ? [liveThread, ...threads.filter((thread) => thread.id !== activeId)]\n          : threads\n      ),\n    [activeId, liveThread, threads]\n  )\n\n  useEffect(() => {\n    if (!restored || busy) return\n    writeThreads(allThreads)\n  }, [allThreads, busy, restored])\n\n  useEffect(() => {\n    scrollRef.current?.scrollTo({\n      top: scrollRef.current.scrollHeight,\n      behavior: \"smooth\",\n    })\n  }, [busy, messages])\n\n  useEffect(() => {\n    if (!historyOpen) return\n    const close = (event: KeyboardEvent) => {\n      if (event.key === \"Escape\") setHistoryOpen(false)\n    }\n    window.addEventListener(\"keydown\", close)\n    return () => window.removeEventListener(\"keydown\", close)\n  }, [historyOpen])\n\n  const keepLiveThread = useCallback(() => {\n    if (!liveThread) return\n    setThreads((previous) =>\n      orderThreads([\n        liveThread,\n        ...previous.filter((thread) => thread.id !== liveThread.id),\n      ])\n    )\n  }, [liveThread])\n\n  const submit = (text: string) => {\n    const trimmed = text.trim()\n    if (!trimmed || busy) return\n    setActiveUpdatedAt(Date.now())\n    sendMessage({ text: trimmed })\n    setInput(\"\")\n  }\n\n  const startNewChat = useCallback(() => {\n    if (busy) return\n    keepLiveThread()\n    setActiveId(newThreadId())\n    setActiveUpdatedAt(0)\n    setActiveTitle(null)\n    setMessageAt({})\n    setMessages([])\n    setInput(\"\")\n  }, [busy, keepLiveThread, setMessages])\n\n  const selectThread = useCallback(\n    (id: string) => {\n      if (busy || id === activeId) return\n      const thread = allThreads.find((candidate) => candidate.id === id)\n      if (!thread) return\n      keepLiveThread()\n      setActiveId(id)\n      setActiveUpdatedAt(thread.updatedAt)\n      setActiveTitle(thread.title)\n      setMessageAt(thread.messageAt ?? {})\n      setMessages(thread.messages)\n      setInput(\"\")\n      setHistoryOpen(false)\n      if (thread.unread) {\n        setThreads((previous) =>\n          previous.map((item) =>\n            item.id === id ? { ...item, unread: false } : item\n          )\n        )\n      }\n    },\n    [activeId, allThreads, busy, keepLiveThread, setMessages]\n  )\n\n  const renameThread = (id: string, title: string) => {\n    if (id === activeId) setActiveTitle(title)\n    setThreads((previous) =>\n      previous.map((thread) =>\n        thread.id === id ? { ...thread, title } : thread\n      )\n    )\n  }\n  const toggleUnread = (id: string) =>\n    setThreads((previous) =>\n      previous.map((thread) =>\n        thread.id === id ? { ...thread, unread: !thread.unread } : thread\n      )\n    )\n  const deleteThread = (id: string) => {\n    setThreads((previous) => previous.filter((thread) => thread.id !== id))\n    if (id !== activeId) return\n    setActiveId(newThreadId())\n    setActiveUpdatedAt(0)\n    setActiveTitle(null)\n    setMessageAt({})\n    setMessages([])\n    setInput(\"\")\n  }\n  const exportThreads = () => {\n    if (allThreads.length === 0) return\n    const url = URL.createObjectURL(\n      new Blob([JSON.stringify(allThreads, null, 2)], {\n        type: \"application/json\",\n      })\n    )\n    const link = document.createElement(\"a\")\n    link.href = url\n    link.download = \"boardui-chats.json\"\n    document.body.appendChild(link)\n    link.click()\n    link.remove()\n    setTimeout(() => URL.revokeObjectURL(url), 0)\n  }\n\n  const streamedText = messageText(messages.at(-1))\n  const transcript = messages\n    .map(\n      (message) =>\n        `${message.role === \"user\" ? \"You\" : \"Assistant\"}: ${messageText(message)}`\n    )\n    .filter((line) => !line.endsWith(\": \"))\n    .join(\"\\n\\n\")\n\n  return (\n    <div\n      className={cx(\n        \"bg-background-full relative flex h-[620px] min-w-0 gap-3 overflow-hidden rounded-3xl p-3\",\n        className\n      )}\n    >\n      <div className=\"bg-background-secondary-default relative flex min-w-0 flex-1 flex-col overflow-hidden rounded-3xl\">\n        <header className=\"border-separator-border flex h-12 shrink-0 items-center border-b px-4\">\n          <span className=\"text-headline-medium text-text-primary min-w-0 truncate\">\n            {allThreads.find((thread) => thread.id === activeId)?.title ??\n              \"New chat\"}\n          </span>\n          {!historyOpen ? (\n            <button\n              type=\"button\"\n              aria-label=\"Open chat history\"\n              onClick={() => setHistoryOpen(true)}\n              className=\"text-foreground-icon-secondary hover:bg-background-primary-hover focus-visible:ring-border-focus-ring ml-auto flex size-7 shrink-0 items-center justify-center rounded-md transition-colors focus-visible:ring-2 focus-visible:outline-none xl:hidden\"\n            >\n              <RiHistoryLine className=\"size-[18px]\" aria-hidden />\n            </button>\n          ) : null}\n          <AgentChatActions\n            className=\"ml-0.5 xl:ml-auto\"\n            transcript={transcript}\n            onExport={exportThreads}\n            onToggleUnread={() => toggleUnread(activeId)}\n            onDelete={() => deleteThread(activeId)}\n            disabled={messages.length === 0}\n          />\n        </header>\n        <div ref={scrollRef} className=\"min-h-0 flex-1 overflow-y-auto\">\n          <div\n            className={cx(\n              \"mx-auto flex min-h-full w-full max-w-3xl flex-col gap-5 px-4 py-6\",\n              messages.length === 0 && \"justify-center\"\n            )}\n          >\n            {messages.length === 0 ? (\n              <div className=\"flex flex-col items-center gap-4 text-center\">\n                <div>\n                  <h2 className=\"text-title-2-medium text-text-primary\">\n                    What can I help with?\n                  </h2>\n                  <p className=\"text-body-regular text-text-secondary\">\n                    Local demo answers stream without an API key.\n                  </p>\n                </div>\n                <div className=\"flex flex-wrap justify-center gap-2\">\n                  {SUGGESTIONS.map((suggestion) => (\n                    <button\n                      key={suggestion}\n                      type=\"button\"\n                      onClick={() => submit(suggestion)}\n                      className=\"bg-background-primary-default text-body-regular text-text-secondary hover:bg-background-primary-hover rounded-full px-3.5 py-2 shadow-xs transition-colors\"\n                    >\n                      {suggestion}\n                    </button>\n                  ))}\n                </div>\n              </div>\n            ) : (\n              messages.map((message, index) => (\n                <AgentMessage\n                  key={message.id}\n                  role={message.role}\n                  text={messageText(message)}\n                  streaming={busy && index === messages.length - 1}\n                  at={messageAt[message.id]}\n                />\n              ))\n            )}\n            {busy && streamedText.length === 0 ? (\n              <AgentThinking variant=\"wave\" label=\"Thinking\" className=\"px-1\" />\n            ) : null}\n            {error ? (\n              <p\n                role=\"alert\"\n                className=\"text-body-regular text-text-tertiary px-1\"\n              >\n                The local demo was interrupted. Try again.\n              </p>\n            ) : null}\n          </div>\n        </div>\n        <div className=\"shrink-0 px-3 pb-3\">\n          <div className=\"mx-auto w-full max-w-3xl\">\n            <AgentComposer\n              value={input}\n              onValueChange={setInput}\n              onSubmit={() => submit(input)}\n              onStop={stop}\n              busy={busy}\n              provider=\"Demo mode\"\n              messageCount={messages.length}\n            />\n          </div>\n        </div>\n      </div>\n      {historyOpen ? (\n        <button\n          type=\"button\"\n          aria-label=\"Close chat history\"\n          onClick={() => setHistoryOpen(false)}\n          className=\"focus-visible:ring-border-focus-ring absolute inset-y-0 right-[272px] left-0 z-20 bg-black/30 focus-visible:ring-2 focus-visible:outline-none xl:hidden\"\n        />\n      ) : null}\n      <AgentChatHistory\n        threads={allThreads}\n        activeId={activeId}\n        onSelect={selectThread}\n        onNewChat={startNewChat}\n        onRename={renameThread}\n        onToggleUnread={toggleUnread}\n        onDelete={deleteThread}\n        onExport={exportThreads}\n        disabled={busy}\n        className={cx(\n          \"z-30 xl:static xl:flex\",\n          historyOpen\n            ? \"absolute inset-y-3 right-3 flex max-w-[calc(100%-1.5rem)] shadow-lg\"\n            : \"hidden\"\n        )}\n      />\n    </div>\n  )\n}\n\nfunction messageText(message?: UIMessage) {\n  return (\n    message?.parts\n      .filter((part) => part.type === \"text\")\n      .map((part) => part.text)\n      .join(\"\") ?? \"\"\n  )\n}\n\nfunction deriveTitle(messages: UIMessage[]) {\n  const first = messages.find((message) => message.role === \"user\")\n  const text = messageText(first).trim()\n  return text.length > 42\n    ? `${text.slice(0, 39).trimEnd()}…`\n    : text || \"New chat\"\n}\n\nfunction newThreadId() {\n  return globalThis.crypto?.randomUUID?.() ?? `chat-${Date.now()}`\n}\n\nfunction orderThreads(threads: StoredThread[]) {\n  return [...threads]\n    .sort((a, b) => b.updatedAt - a.updatedAt)\n    .slice(0, MAX_THREADS)\n}\n\nfunction readThreads(): StoredThread[] {\n  try {\n    const parsed: unknown = JSON.parse(\n      window.localStorage.getItem(STORAGE_KEY) ?? \"[]\"\n    )\n    return Array.isArray(parsed) ? parsed.filter(isStoredThread) : []\n  } catch {\n    return []\n  }\n}\n\nfunction writeThreads(threads: StoredThread[]) {\n  try {\n    window.localStorage.setItem(STORAGE_KEY, JSON.stringify(threads))\n  } catch {\n    // Storage may be disabled; the live thread still works.\n  }\n}\n\nfunction isStoredThread(value: unknown): value is StoredThread {\n  if (!value || typeof value !== \"object\") return false\n  const thread = value as Partial<StoredThread>\n  return (\n    typeof thread.id === \"string\" &&\n    typeof thread.title === \"string\" &&\n    typeof thread.updatedAt === \"number\" &&\n    Array.isArray(thread.messages)\n  )\n}\n"
        },
        {
          "path": "components/boardui/application/agent-chat/agent-chat-actions.tsx",
          "target": "@components/boardui/application/agent-chat/agent-chat-actions.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { RiCheckLine, RiMoreFill, RiUploadLine } from \"@remixicon/react\";\nimport { useEffect, useState } from \"react\";\n\nimport {\n  Dropdown,\n  DropdownGroup,\n  DropdownItem,\n  DropdownPopover,\n  DropdownTrigger,\n} from \"@/components/boardui/base/dropdown/dropdown\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * The controls in the top right of the chat surface: share the open chat, and\n * a menu of the actions that apply to it.\n *\n * Every entry does something the starter can actually do — copy, download,\n * mark, delete. Nothing here is a placeholder waiting on a backend, because a\n * control that looks live and does nothing is worse than no control.\n */\n\nexport interface AgentChatActionsProps {\n  /** Plain-text transcript of the open chat, for share and copy. */\n  transcript: string;\n  onExport: () => void;\n  onToggleUnread: () => void;\n  onDelete: () => void;\n  /** No chat open yet, so there is nothing to act on. */\n  disabled?: boolean;\n  className?: string;\n}\n\nexport function AgentChatActions({\n  transcript,\n  onExport,\n  onToggleUnread,\n  onDelete,\n  disabled = false,\n  className,\n}: AgentChatActionsProps) {\n  const [menuOpen, setMenuOpen] = useState(false);\n  const [shared, setShared] = useState(false);\n\n  useEffect(() => {\n    if (!shared) return;\n    const timer = setTimeout(() => setShared(false), 1600);\n    return () => clearTimeout(timer);\n  }, [shared]);\n\n  const share = async () => {\n    if (!transcript) return;\n    // The Web Share sheet where the browser has one, the clipboard everywhere\n    // else. Both leave the transcript on the device.\n    try {\n      if (navigator.share) {\n        await navigator.share({ text: transcript });\n        return;\n      }\n      await navigator.clipboard.writeText(transcript);\n      setShared(true);\n    } catch {\n      // A dismissed share sheet and a refused clipboard both land here, and\n      // neither is worth interrupting the reader over.\n    }\n  };\n\n  const choose = (action: () => void) => () => {\n    setMenuOpen(false);\n    action();\n  };\n\n  return (\n    <div className={cx(\"flex shrink-0 items-center gap-0.5\", className)}>\n      <button\n        type=\"button\"\n        onClick={share}\n        disabled={disabled}\n        aria-label={shared ? \"Transcript copied\" : \"Share chat\"}\n        title={shared ? \"Transcript copied\" : \"Share chat\"}\n        className={ACTION_BUTTON}\n      >\n        {shared ? (\n          <RiCheckLine className=\"size-[18px] shrink-0\" aria-hidden />\n        ) : (\n          <RiUploadLine className=\"size-[18px] shrink-0\" aria-hidden />\n        )}\n      </button>\n\n      <Dropdown isOpen={menuOpen} onOpenChange={setMenuOpen}>\n        <DropdownTrigger\n          aria-label=\"More actions for this chat\"\n          isDisabled={disabled}\n          className={cx(ACTION_BUTTON, menuOpen && \"bg-background-primary-hover text-text-primary\")}\n        >\n          <RiMoreFill className=\"size-[18px] shrink-0\" aria-hidden />\n        </DropdownTrigger>\n\n        <DropdownPopover\n          aria-label=\"More actions for this chat\"\n          placement=\"bottom end\"\n          className=\"w-[190px] p-2\"\n        >\n          <DropdownGroup>\n            <DropdownItem onSelect={choose(onExport)} className=\"px-2 py-1.5\">\n              <span className=\"truncate text-body-medium whitespace-nowrap text-text-primary\">\n                Export chats\n              </span>\n            </DropdownItem>\n            <DropdownItem onSelect={choose(onToggleUnread)} className=\"px-2 py-1.5\">\n              <span className=\"truncate text-body-medium whitespace-nowrap text-text-primary\">\n                Mark as unread\n              </span>\n            </DropdownItem>\n            <DropdownItem onSelect={choose(onDelete)} className=\"px-2 py-1.5\">\n              <span className=\"truncate text-body-medium whitespace-nowrap text-text-error-primary\">\n                Delete chat\n              </span>\n            </DropdownItem>\n          </DropdownGroup>\n        </DropdownPopover>\n      </Dropdown>\n    </div>\n  );\n}\n\n/** DropdownTrigger is itself a button, so both controls share plain classes\n *  rather than wrapping an IconButton (which would nest one button in another). */\nconst ACTION_BUTTON = cx(\n  \"inline-flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-md\",\n  \"text-foreground-icon-secondary transition-colors duration-150 ease\",\n  \"hover:bg-background-primary-hover hover:text-foreground-icon-primary\",\n  \"disabled:cursor-not-allowed disabled:opacity-40\",\n);\n"
        },
        {
          "path": "components/boardui/base/dropdown/dropdown.tsx",
          "target": "@components/boardui/base/dropdown/dropdown.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { createContext, useContext, useRef, useState, type ComponentProps, type ReactNode, type RefObject } from \"react\";\nimport {\n  Button as AriaButton,\n  Dialog as AriaDialog,\n  DialogTrigger as AriaDialogTrigger,\n  Popover as AriaPopover,\n} from \"react-aria-components\";\nimport {\n  MENU_ITEM,\n  MENU_ITEM_ACTIVE,\n  MENU_ITEM_INTERACTIVE,\n  MENU_POPOVER_SURFACE,\n  MENU_POPOVER_WIDTH,\n} from \"@/components/boardui/base/dropdown/menu-styles\";\nimport { cx } from \"@/components/boardui/utils/cx\";\nimport { useDismissOnOutsidePress, useTriggerToggle } from \"@/components/boardui/utils/use-dismiss-on-outside-press\";\n\n/**\n * Dropdown - the BoardUI popover-menu recipe as composable primitives, built\n * on React Aria's DialogTrigger/Popover. Unlike Select (which picks a value\n * into a trigger), Dropdown is a free-form menu surface: grouped rows of\n * actions, headers, footers, whatever the panel needs.\n *\n * The same recipe powers the dashboard sidebar's team/account menus and the\n * AI chat template's add/model/folder menus:\n *\n * - Panel: white, 1px border/button/default, radius 16, p 10, shadow/dropdown.\n * - Appear animation: 150ms fade + scale-95 + 2px blur in and out.\n * - Rows: rounded-2lg, background/secondary/hover on hover and on the selected\n *   row, body-medium labels, 4px apart (the panel's flex column carries a\n *   gap-1, the same rhythm as the Select listbox).\n *\n * Composition:\n *\n * ```tsx\n * <Dropdown isOpen={isOpen} onOpenChange={setIsOpen}>\n *   <DropdownTrigger>Open</DropdownTrigger>\n *   <DropdownPopover aria-label=\"Actions\" placement=\"bottom start\">\n *     <DropdownGroup label=\"Add\">\n *       <DropdownItem onSelect={close}>…row content…</DropdownItem>\n *     </DropdownGroup>\n *     <DropdownDivider />\n *     <DropdownGroup label=\"Plugins\">…</DropdownGroup>\n *   </DropdownPopover>\n * </Dropdown>\n * ```\n *\n * State can be uncontrolled (omit isOpen/onOpenChange) - control it when the\n * trigger needs to react to the open state (e.g. rotating a chevron).\n */\n\n/* ------------------------------------------------------------------- shell */\n\ninterface DropdownContextValue {\n  triggerRef: RefObject<HTMLButtonElement | null>;\n  popoverRef: RefObject<HTMLElement | null>;\n}\n\nconst DropdownContext = createContext<DropdownContextValue | null>(null);\n\nexport interface DropdownProps {\n  isOpen?: boolean;\n  onOpenChange?: (isOpen: boolean) => void;\n  /** Trigger (a DropdownTrigger) followed by a DropdownPopover. */\n  children: ReactNode;\n}\n\n/**\n * The popover is `isNonModal`: react-aria's modal scroll lock puts\n * `overflow: hidden` on <html>, which collapses the page scroll position and\n * visibly yanks sticky layout (e.g. the docs sidebar) whenever a menu opens.\n * Non-modal skips the lock, but react-aria hard-couples outside-press\n * dismissal to modality - so open state lives here (bridging any controlled\n * props) and dismissal is restored via useDismissOnOutsidePress, the same\n * fix as Select and the date-picker family.\n */\nexport function Dropdown({ isOpen: controlledOpen, onOpenChange, children }: DropdownProps) {\n  const triggerRef = useRef<HTMLButtonElement>(null);\n  const popoverRef = useRef<HTMLElement>(null);\n  const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n\n  const isOpen = controlledOpen ?? uncontrolledOpen;\n  const setOpen = (next: boolean) => {\n    setUncontrolledOpen(next);\n    onOpenChange?.(next);\n  };\n\n  useDismissOnOutsidePress(isOpen, () => setOpen(false), [triggerRef, popoverRef]);\n  // Pressing the trigger while open closes the menu instead of reopening\n  const allowOpenChange = useTriggerToggle(isOpen, triggerRef);\n\n  return (\n    <DropdownContext.Provider value={{ triggerRef, popoverRef }}>\n      <AriaDialogTrigger isOpen={isOpen} onOpenChange={(o) => allowOpenChange(o) && setOpen(o)}>\n        {children}\n      </AriaDialogTrigger>\n    </DropdownContext.Provider>\n  );\n}\n\n/** The element that opens the menu. Style it entirely via className. */\nexport function DropdownTrigger({ className, ...props }: ComponentProps<typeof AriaButton>) {\n  const context = useContext(DropdownContext);\n  return (\n    <AriaButton\n      ref={context?.triggerRef}\n      {...props}\n      className={cx(\n        \"cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-border-focus-ring\",\n        className as string,\n      )}\n    />\n  );\n}\n\n/* ------------------------------------------------------------------- panel */\n\nexport interface DropdownPopoverProps\n  extends Pick<ComponentProps<typeof AriaPopover>, \"placement\" | \"offset\" | \"crossOffset\"> {\n  \"aria-label\": string;\n  /** Extra classes on the panel - e.g. a width override (default w-[266px]). */\n  className?: string;\n  /** Classes on the inner dialog (the flex column), e.g. gap between groups. */\n  dialogClassName?: string;\n  children: ReactNode;\n}\n\nexport function DropdownPopover({\n  \"aria-label\": ariaLabel,\n  placement = \"bottom start\",\n  offset = 4,\n  crossOffset,\n  className,\n  dialogClassName,\n  children,\n}: DropdownPopoverProps) {\n  const context = useContext(DropdownContext);\n  return (\n    <AriaPopover\n      ref={context?.popoverRef}\n      isNonModal\n      placement={placement}\n      offset={offset}\n      crossOffset={crossOffset}\n      className={cx(\n        MENU_POPOVER_WIDTH,\n        MENU_POPOVER_SURFACE,\n        className,\n      )}\n    >\n      {/* gap-1 keeps bare DropdownItems 4px apart, the same rhythm as the\n          Select listbox; DropdownDivider's margins are sized to absorb it. */}\n      <AriaDialog aria-label={ariaLabel} className={cx(\"flex flex-col gap-1 outline-none\", dialogClassName)}>\n        {children}\n      </AriaDialog>\n    </AriaPopover>\n  );\n}\n\n/* ----------------------------------------------------------------- content */\n\nexport interface DropdownGroupProps {\n  /** Muted body-medium heading above the rows. */\n  label?: string;\n  className?: string;\n  children: ReactNode;\n}\n\nexport function DropdownGroup({ label, className, children }: DropdownGroupProps) {\n  return (\n    // pt-1 is spacing for the group LABEL - a label-less group must not\n    // carry it, or its first row floats 4px lower than the panel padding\n    // implies (visible as extra space above the first item's hover pill).\n    <div className={cx(\"flex w-full flex-col gap-1.5\", label && \"pt-1\", className)}>\n      {label && <span className=\"pl-2 text-body-medium text-text-secondary\">{label}</span>}\n      <div className=\"flex w-full flex-col gap-1\">{children}</div>\n    </div>\n  );\n}\n\nexport interface DropdownItemProps {\n  /** Highlights the row like the hover state (current selection). */\n  selected?: boolean;\n  onSelect?: () => void;\n  /** Row padding defaults to p-2 - override for denser rows (px-2 py-1.5). */\n  className?: string;\n  children: ReactNode;\n}\n\n/**\n * A menu row. Content is free-form - icon + label, avatar + name, label +\n * trailing badge - laid out in a gap-2 flex row.\n */\nexport function DropdownItem({ selected, onSelect, className, children }: DropdownItemProps) {\n  return (\n    <button\n      type=\"button\"\n      aria-pressed={selected}\n      onClick={onSelect}\n      className={cx(\n        MENU_ITEM,\n        selected ? MENU_ITEM_ACTIVE : MENU_ITEM_INTERACTIVE,\n        className,\n      )}\n    >\n      {children}\n    </button>\n  );\n}\n\n/** Full-bleed 1px divider between groups (bleeds through the panel's p-2.5).\n *  my-1.5 + the dialog's gap-1 on both sides = the original 10px breathing room. */\nexport function DropdownDivider({ className }: { className?: string }) {\n  return <div className={cx(\"-mx-2.5 my-1.5 h-px shrink-0 bg-border-button-default\", className)} />;\n}\n"
        },
        {
          "path": "components/boardui/base/dropdown/menu-styles.ts",
          "target": "@components/boardui/base/dropdown/menu-styles.ts",
          "type": "registry:component",
          "content": "/**\n * Shared visual recipe for BoardUI menu surfaces.\n *\n * Select and Dropdown intentionally keep their distinct React Aria semantics\n * (single-value listbox vs. action menu), while consuming the same panel,\n * motion, and row treatments from here.\n */\nexport const MENU_POPOVER_SURFACE = [\n  \"max-w-[calc(100vw-32px)] overflow-y-auto\",\n  \"rounded-2xl border border-border-button-default bg-background-primary-default p-2.5 shadow-dropdown\",\n  \"transition duration-150 ease-out\",\n  \"data-[entering]:opacity-0 data-[entering]:scale-95 data-[entering]:blur-[2px]\",\n  \"data-[exiting]:opacity-0 data-[exiting]:scale-95 data-[exiting]:blur-[2px]\",\n  \"data-[placement=bottom]:origin-top-left data-[placement=top]:origin-bottom-left\",\n  \"data-[placement=left]:origin-right data-[placement=right]:origin-left\",\n].join(\" \");\n\nexport const MENU_POPOVER_WIDTH = \"w-[266px]\";\n\nexport const MENU_ITEMS_CONTAINER = \"flex w-full flex-col gap-1 outline-none\";\n\nexport const MENU_ITEM = [\n  \"flex w-full cursor-pointer items-center gap-2 rounded-2lg p-2 text-left\",\n  \"text-text-primary outline-none transition-colors\",\n].join(\" \");\n\nexport const MENU_ITEM_ACTIVE = \"bg-dropdown-item-hover-background\";\n\nexport const MENU_ITEM_INTERACTIVE =\n  \"hover:bg-dropdown-item-hover-background focus-visible:bg-dropdown-item-hover-background\";\n"
        },
        {
          "path": "components/boardui/utils/cx.ts",
          "target": "@components/boardui/utils/cx.ts",
          "type": "registry:component",
          "content": "import { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * Text-style classes from styles/typography.css.\n *\n * IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,\n * `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which\n * has no view of our Tailwind theme — treats them as text-color utilities and\n * silently drops them when they appear in the same className as a real color\n * (`text-foreground-full`, `text-text-primary`, etc).\n *\n * If you add or rename a text style in typography.css, mirror the change here.\n */\nconst TEXT_FAMILIES = [\n  \"large-title\",\n  \"display-1\",\n  \"display-2\",\n  \"display-3\",\n  \"display-4\",\n  \"title-1\",\n  \"title-2\",\n  \"title-3\",\n  \"headline\",\n  \"body\",\n  \"body-2\",\n  \"caption-1\",\n  \"caption-2\",\n] as const;\n\nconst TEXT_WEIGHTS = [\"regular\", \"medium\", \"semibold\", \"bold\"] as const;\n\nconst TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>\n  TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),\n);\n\nconst twMerge = extendTailwindMerge({\n  extend: {\n    classGroups: {\n      \"font-size\": [{ text: TEXT_STYLE_SUFFIXES }],\n    },\n  },\n});\n\n/**\n * Merge Tailwind classes safely. Last-write-wins on conflicting utilities.\n */\nexport const cx = twMerge;\n\n/**\n * Identity helper that gives the Tailwind IntelliSense extension a hook for\n * sorting classes inside style objects (the extension doesn't sort inside\n * plain object literals otherwise).\n */\nexport function sortCx<\n  T extends Record<\n    string,\n    string | number | Record<string, string | number | Record<string, string | number>>\n  >,\n>(classes: T): T {\n  return classes;\n}\n"
        },
        {
          "path": "components/boardui/utils/use-dismiss-on-outside-press.ts",
          "target": "@components/boardui/utils/use-dismiss-on-outside-press.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport type { RefObject } from \"react\";\n\n/**\n * React Aria's `Popover` couples \"non-modal\" with \"not dismissable on\n * outside interaction\" — `isNonModal` (which we set to avoid the scroll\n * lock / focus trap that comes with a modal popover) also silently disables\n * its built-in outside-click-to-close behavior. This restores just that\n * piece manually: closes when a pointerdown lands outside every given ref\n * (typically the trigger + the popover's own content).\n */\nexport function useDismissOnOutsidePress(\n  isOpen: boolean,\n  onDismiss: () => void,\n  refs: RefObject<HTMLElement | null>[],\n) {\n  useEffect(() => {\n    if (!isOpen) return;\n\n    const handlePointerDown = (event: PointerEvent) => {\n      const target = event.target as Node;\n      if (refs.some((ref) => ref.current?.contains(target))) return;\n      onDismiss();\n    };\n\n    document.addEventListener(\"pointerdown\", handlePointerDown, true);\n    return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n  }, [isOpen, onDismiss, refs]);\n}\n\n/**\n * Companion fix for the same `isNonModal` popovers: pressing the trigger\n * while the popover is open should close it (toggle), but React Aria fires\n * `onOpenChange(false)` immediately followed by `onOpenChange(true)` within\n * the same press, so the popover never actually closes.\n *\n * This watches for a pointerdown on the trigger while open and swallows the\n * spurious reopen that follows. Wire the returned guard into the component's\n * `onOpenChange`:\n *\n *   const allowOpenChange = useTriggerToggle(isOpen, triggerRef);\n *   <AriaSelect onOpenChange={(o) => allowOpenChange(o) && setIsOpen(o)} …\n */\nexport function useTriggerToggle(\n  isOpen: boolean,\n  triggerRef: RefObject<HTMLElement | null>,\n) {\n  const suppressReopenRef = useRef(false);\n\n  useEffect(() => {\n    if (!isOpen) return;\n\n    const handlePointerDown = (event: PointerEvent) => {\n      if (!triggerRef.current?.contains(event.target as Node)) return;\n      suppressReopenRef.current = true;\n      // Safety valve: only the very next open within this click may be\n      // swallowed; never leave a stale suppression behind.\n      setTimeout(() => {\n        suppressReopenRef.current = false;\n      }, 400);\n    };\n\n    document.addEventListener(\"pointerdown\", handlePointerDown, true);\n    return () => document.removeEventListener(\"pointerdown\", handlePointerDown, true);\n  }, [isOpen, triggerRef]);\n\n  return (next: boolean) => {\n    if (next && suppressReopenRef.current) {\n      suppressReopenRef.current = false;\n      return false;\n    }\n    return true;\n  };\n}\n"
        },
        {
          "path": "components/boardui/application/agent-chat/agent-chat-history.tsx",
          "target": "@components/boardui/application/agent-chat/agent-chat-history.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  RiAddLine,\n  RiDownloadLine,\n  RiGlobalLine,\n  RiLogoutBoxRLine,\n  RiMore2Fill,\n  RiSendPlaneLine,\n  RiSettings3Line,\n  RiSpeedUpLine,\n} from \"@remixicon/react\";\nimport { useEffect, useRef, useState, type KeyboardEvent } from \"react\";\n\nimport { Avatar } from \"@/components/boardui/base/avatar/avatar\";\nimport {\n  Dropdown,\n  DropdownGroup,\n  DropdownDivider,\n  DropdownItem,\n  DropdownPopover,\n  DropdownTrigger,\n} from \"@/components/boardui/base/dropdown/dropdown\";\nimport { ChevronDownSmall } from \"@/components/boardui/foundations/icons/chevrons\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * The chat-history rail, a card of its own beside the chat.\n *\n * It mirrors the structure of the app sidebar — an action at the top, a\n * section label, then a list of items with a relative-time badge — so the two\n * rails read as the same system from opposite sides of the workspace.\n *\n * Threads are held by the parent and kept in the visitor's own browser. That\n * is the honest ceiling for a starter with no database: hosted history across\n * devices is what a backend buys you, and this is the free version of it.\n */\n\nexport interface ChatThreadSummary {\n  id: string;\n  title: string;\n  updatedAt: number;\n  unread?: boolean;\n}\nexport interface AgentChatHistoryProps {\n  threads: ChatThreadSummary[];\n  activeId: string;\n  onSelect: (id: string) => void;\n  onNewChat: () => void;\n  onRename: (id: string, title: string) => void;\n  onToggleUnread: (id: string) => void;\n  onDelete: (id: string) => void;\n  /** Downloads the stored chats as JSON. */\n  onExport: () => void;\n  /** Disables switching mid-stream, which would strand the running response. */\n  disabled?: boolean;\n  className?: string;\n}\n\nexport function AgentChatHistory({\n  threads,\n  activeId,\n  onSelect,\n  onNewChat,\n  onRename,\n  onToggleUnread,\n  onDelete,\n  onExport,\n  disabled = false,\n  className,\n}: AgentChatHistoryProps) {\n  return (\n    <aside\n      aria-label=\"Chat history\"\n      className={cx(\n        // A card of its own beside the chat rather than a panel within it, the\n        // way the Pro template seats its code panel: same surface and radius as\n        // the chat card, separated by the workspace gap. Full height, and its\n        // own padding, since it no longer borrows the chat card's.\n        \"flex h-full w-[260px] shrink-0 flex-col gap-6 overflow-hidden rounded-3xl bg-background-secondary-default p-3\",\n        className,\n      )}\n    >\n      <button\n        type=\"button\"\n        onClick={onNewChat}\n        disabled={disabled}\n        className=\"flex w-full cursor-pointer items-center gap-2 rounded-2lg px-2 py-2 text-body-medium text-text-primary transition-colors hover:bg-background-secondary-hover disabled:cursor-not-allowed disabled:opacity-50\"\n      >\n        <RiAddLine className=\"size-5 shrink-0 text-foreground-icon-secondary\" aria-hidden />\n        New chat\n      </button>\n\n      <div className=\"flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto [scrollbar-width:none]\">\n        <p className=\"px-2 pb-1 text-body-2-medium text-text-tertiary\">Recent</p>\n\n        {threads.length === 0 ? (\n          <p className=\"px-2 text-body-2-regular text-text-tertiary\">\n            Chats you start show up here.\n          </p>\n        ) : (\n          threads.map((thread) => (\n            <ThreadRow\n              key={thread.id}\n              thread={thread}\n              active={thread.id === activeId}\n              disabled={disabled}\n              onSelect={onSelect}\n              onRename={onRename}\n              onToggleUnread={onToggleUnread}\n              onDelete={onDelete}\n            />\n          ))\n        )}\n      </div>\n\n      <RailFooter threads={threads} onExport={onExport} />\n    </aside>\n  );\n}\n\n/**\n * The account strip along the bottom of the rail.\n *\n * The trailing control downloads the stored chats as JSON. It does something\n * real on purpose — this rail's whole premise is that history lives in the\n * visitor's own browser, and the one thing that premise owes them is a way to\n * take it with them.\n */\nfunction RailFooter({\n  threads,\n  onExport,\n}: {\n  threads: ChatThreadSummary[];\n  onExport: () => void;\n}) {\n  const count = threads.length;\n  const label = count === 0 ? \"No chats to export\" : `Export ${count} chats`;\n  return (\n    <div className=\"mt-auto flex items-center gap-1 border-t border-separator-border pt-3 pr-1\">\n      <AccountMenu threads={threads} />\n      <button\n        type=\"button\"\n        onClick={onExport}\n        disabled={count === 0}\n        aria-label={label}\n        title={label}\n        className=\"flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-full bg-button-primary text-white transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40\"\n      >\n        <RiDownloadLine className=\"size-3.5 shrink-0\" aria-hidden />\n      </button>\n    </div>\n  );\n}\n\n/** The rail keeps at most this many chats, which is what makes \"chats\" a real\n *  quota rather than a decorative percentage. Mirrors MAX_THREADS in the shell. */\nconst THREAD_CAPACITY = 30;\n/** localStorage is about 5MB in practice; enough to make the number mean something. */\nconst STORAGE_BUDGET_BYTES = 5 * 1024 * 1024;\n\n/**\n * The account switcher at the foot of the rail: avatar, name, chevron, and a\n * grouped menu built from the same pieces as the app sidebar's team card, so\n * the two read as one system.\n *\n * \"Usage left\" expands in place. Its numbers are the starter's actual\n * limits — how many of the retained chats are used, and how much of the\n * browser's storage they occupy — rather than invented percentages, so the row\n * still means something once this ships inside someone else's app.\n */\nfunction AccountMenu({ threads }: { threads: ChatThreadSummary[] }) {\n  const [isOpen, setIsOpen] = useState(false);\n  const [usageOpen, setUsageOpen] = useState(false);\n  const [storedBytes, setStoredBytes] = useState(0);\n  const close = () => setIsOpen(false);\n  const logOut = close;\n\n  const chatPercent = Math.min(100, Math.round((threads.length / THREAD_CAPACITY) * 100));\n  const storagePercent = Math.min(100, Math.round((storedBytes / STORAGE_BUDGET_BYTES) * 100));\n\n  const toggleUsage = () => {\n    // Measured when the section opens rather than on every render: it reads\n    // localStorage, which is outside React and not free.\n    if (!usageOpen) setStoredBytes(measureStoredBytes());\n    setUsageOpen((open) => !open);\n  };\n\n  return (\n    <Dropdown\n      isOpen={isOpen}\n      onOpenChange={(open) => {\n        setIsOpen(open);\n        if (!open) setUsageOpen(false);\n      }}\n    >\n      <DropdownTrigger\n        aria-label=\"Mertcan Esmergul account menu\"\n        className={cx(\n          \"flex min-w-0 flex-1 items-center gap-2 rounded-2lg px-1 py-1 text-left\",\n          \"transition-colors hover:bg-background-secondary-hover\",\n          isOpen && \"bg-background-secondary-hover\",\n        )}\n      >\n        <Avatar size=\"sm\" initials=\"M\" color=\"neutral\" alt=\"Mertcan Esmergul\" />\n        <span className=\"min-w-0 flex-1 truncate text-body-2-medium text-text-primary\">\n          Mertcan Esmergul\n        </span>\n      </DropdownTrigger>\n\n      <DropdownPopover\n        aria-label=\"Account menu\"\n        placement=\"top start\"\n        className=\"w-[248px] p-2.5\"\n        dialogClassName=\"gap-[7px]\"\n      >\n        <DropdownGroup>\n          <button\n            type=\"button\"\n            onClick={toggleUsage}\n            aria-expanded={usageOpen}\n            className=\"flex w-full cursor-pointer items-center gap-2 rounded-2lg px-2 py-1.5 text-left transition-colors hover:bg-background-secondary-default\"\n          >\n            <RiSpeedUpLine className=\"size-[18px] shrink-0 text-foreground-icon-secondary\" aria-hidden />\n            <span className=\"flex-1 truncate text-body-medium whitespace-nowrap text-text-primary\">\n              Usage left\n            </span>\n            <ChevronDownSmall\n              className={cx(\n                \"size-4 shrink-0 text-foreground-icon-secondary transition-transform duration-150\",\n                usageOpen && \"rotate-180\",\n              )}\n              aria-hidden\n            />\n          </button>\n\n          {usageOpen && (\n            <div className=\"flex flex-col gap-1 pb-1\">\n              <UsageRow label=\"Chats\" value={`${threads.length} of ${THREAD_CAPACITY}`} percent={chatPercent} />\n              <UsageRow label=\"Storage\" value={formatBytes(storedBytes)} percent={storagePercent} />\n              <button\n                type=\"button\"\n                onClick={close}\n                className=\"flex w-full cursor-pointer items-center gap-2 rounded-2lg py-1 pr-2 pl-9 text-left transition-colors hover:bg-background-secondary-default\"\n              >\n                <span className=\"flex-1 truncate text-body-2-medium whitespace-nowrap text-text-primary\">\n                  Upgrade to Max\n                </span>\n                <RiGlobalLine className=\"size-4 shrink-0 text-foreground-icon-tertiary\" aria-hidden />\n              </button>\n            </div>\n          )}\n\n          <DropdownItem onSelect={close} className=\"px-2 py-1.5\">\n            <RiSendPlaneLine className=\"size-[18px] shrink-0 text-foreground-icon-secondary\" aria-hidden />\n            <span className=\"truncate text-body-medium whitespace-nowrap text-text-primary\">\n              Invite a friend\n            </span>\n          </DropdownItem>\n          <DropdownItem onSelect={close} className=\"px-2 py-1.5\">\n            <RiSettings3Line className=\"size-[18px] shrink-0 text-foreground-icon-secondary\" aria-hidden />\n            <span className=\"truncate text-body-medium whitespace-nowrap text-text-primary\">\n              Settings\n            </span>\n          </DropdownItem>\n        </DropdownGroup>\n\n        <DropdownDivider />\n\n        <DropdownGroup>\n          <DropdownItem onSelect={logOut} className=\"px-2 py-1.5\">\n            <RiLogoutBoxRLine className=\"size-[18px] shrink-0 text-foreground-icon-secondary\" aria-hidden />\n            <span className=\"truncate text-body-medium whitespace-nowrap text-text-primary\">\n              Log out\n            </span>\n          </DropdownItem>\n        </DropdownGroup>\n      </DropdownPopover>\n    </Dropdown>\n  );\n}\n\n/** A measured line under \"Usage left\": what it is, how much, how full. */\nfunction UsageRow({ label, value, percent }: { label: string; value: string; percent: number }) {\n  return (\n    <div className=\"flex items-center gap-2 py-0.5 pr-2 pl-9\">\n      <span className=\"flex-1 truncate text-body-2-medium text-text-primary\">{label}</span>\n      <span className=\"shrink-0 text-body-2-regular text-text-secondary\">{value}</span>\n      <span className=\"w-9 shrink-0 text-right text-body-2-regular text-text-tertiary\">{percent}%</span>\n    </div>\n  );\n}\n\n/** Bytes the stored chats occupy. UTF-16 in storage, so two bytes a character. */\nfunction measureStoredBytes() {\n  try {\n    return (window.localStorage.getItem(\"boardui:agent-chat-threads\")?.length ?? 0) * 2;\n  } catch {\n    return 0;\n  }\n}\n\nfunction formatBytes(bytes: number) {\n  if (bytes < 1024) return `${bytes} B`;\n  if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;\n  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction ThreadRow({\n  thread,\n  active,\n  disabled,\n  onSelect,\n  onRename,\n  onToggleUnread,\n  onDelete,\n}: {\n  thread: ChatThreadSummary;\n  active: boolean;\n  disabled: boolean;\n  onSelect: (id: string) => void;\n  onRename: (id: string, title: string) => void;\n  onToggleUnread: (id: string) => void;\n  onDelete: (id: string) => void;\n}) {\n  const [menuOpen, setMenuOpen] = useState(false);\n  const [renaming, setRenaming] = useState(false);\n  const [draft, setDraft] = useState(thread.title);\n  const inputRef = useRef<HTMLInputElement>(null);\n\n  useEffect(() => {\n    if (!renaming) return;\n    inputRef.current?.focus();\n    inputRef.current?.select();\n  }, [renaming]);\n\n  const commit = () => {\n    const next = draft.trim();\n    if (next && next !== thread.title) onRename(thread.id, next);\n    setRenaming(false);\n  };\n\n  const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n    if (event.key === \"Enter\") {\n      event.preventDefault();\n      commit();\n    }\n    if (event.key === \"Escape\") {\n      event.preventDefault();\n      setDraft(thread.title);\n      setRenaming(false);\n    }\n  };\n\n  if (renaming) {\n    return (\n      <div className=\"rounded-2lg bg-background-secondary-hover px-2 py-1.5\">\n        <label className=\"sr-only\" htmlFor={`rename-${thread.id}`}>\n          Rename chat\n        </label>\n        <input\n          id={`rename-${thread.id}`}\n          ref={inputRef}\n          value={draft}\n          onChange={(event) => setDraft(event.target.value)}\n          onKeyDown={onKeyDown}\n          onBlur={commit}\n          className=\"w-full bg-transparent text-body-2-regular text-text-primary outline-none\"\n        />\n      </div>\n    );\n  }\n\n  return (\n    <div\n      className={cx(\n        \"group/row relative flex items-center rounded-2lg transition-colors\",\n        // Stepped off the rail's own surface. The rail moved to `secondary`\n        // when it became a card of its own, and `primary-hover` resolves to\n        // exactly that colour in light — selection would have been invisible.\n        // Selection and hover share the fill, so hovering previews selecting.\n        active || menuOpen\n          ? \"bg-background-secondary-hover\"\n          : \"hover:bg-background-secondary-hover\",\n      )}\n    >\n      <button\n        type=\"button\"\n        onClick={() => onSelect(thread.id)}\n        disabled={disabled}\n        aria-current={active ? \"true\" : undefined}\n        className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1.5 py-1.5 pl-2 text-left disabled:cursor-not-allowed disabled:opacity-50\"\n      >\n        {thread.unread && (\n          <span\n            aria-label=\"Unread\"\n            className=\"size-1.5 shrink-0 rounded-full bg-button-primary\"\n          />\n        )}\n        <span\n          className={cx(\n            \"min-w-0 flex-1 truncate text-body-2-regular\",\n            thread.unread ? \"text-text-primary\" : \"text-text-secondary\",\n          )}\n        >\n          {thread.title}\n        </span>\n      </button>\n\n      {/* The age and the menu share one slot: the age steps aside on hover so\n          the control appears in place rather than shifting the title.\n          The two must never be visible together, so they are driven by one\n          condition each way. `focus-visible` rather than `focus-within` is the\n          load-bearing part: closing the menu with the pointer hands focus back\n          to the trigger, and `focus-within` would keep the icon lit on top of\n          the age that has already returned. */}\n      <span className=\"group/slot relative flex size-7 shrink-0 items-center justify-center pr-1\">\n        <span\n          aria-hidden={menuOpen}\n          className={cx(\n            \"text-caption-1-regular text-text-tertiary transition-opacity\",\n            menuOpen\n              ? \"opacity-0\"\n              : \"opacity-100 group-hover/row:opacity-0 group-has-[:focus-visible]/slot:opacity-0\",\n          )}\n        >\n          {relativeTime(thread.updatedAt)}\n        </span>\n\n        <span\n          className={cx(\n            // Nudged 1px left of the age badge's centre: the glyph reads as\n            // sitting slightly right in its own box, so the optical centre and\n            // the geometric one do not agree.\n            \"absolute inset-0 flex -translate-x-px items-center justify-center transition-opacity\",\n            menuOpen\n              ? \"opacity-100\"\n              : \"opacity-0 group-hover/row:opacity-100 group-has-[:focus-visible]/slot:opacity-100\",\n          )}\n        >\n          <RowMenu\n            title={thread.title}\n            isOpen={menuOpen}\n            onOpenChange={setMenuOpen}\n            onRename={() => {\n              setDraft(thread.title);\n              setRenaming(true);\n            }}\n            onToggleUnread={() => onToggleUnread(thread.id)}\n            onDelete={() => onDelete(thread.id)}\n          />\n        </span>\n      </span>\n    </div>\n  );\n}\n\n/** DropdownTrigger is itself the button, so it is styled directly — putting an\n *  IconButton inside it would nest one button in another. */\nfunction RowMenu({\n  title,\n  isOpen,\n  onOpenChange,\n  onRename,\n  onToggleUnread,\n  onDelete,\n}: {\n  title: string;\n  isOpen: boolean;\n  onOpenChange: (open: boolean) => void;\n  onRename: () => void;\n  onToggleUnread: () => void;\n  onDelete: () => void;\n}) {\n  const choose = (action: () => void) => () => {\n    onOpenChange(false);\n    action();\n  };\n\n  return (\n    <Dropdown isOpen={isOpen} onOpenChange={onOpenChange}>\n      <DropdownTrigger\n        aria-label={`More actions for ${title}`}\n        className={cx(\n          \"inline-flex size-6 shrink-0 items-center justify-center rounded-md\",\n          \"text-foreground-icon-secondary transition-colors duration-150 ease\",\n          \"hover:bg-background-tertiary-default hover:text-foreground-icon-primary\",\n          isOpen && \"bg-background-tertiary-default text-foreground-icon-primary\",\n        )}\n      >\n        <RiMore2Fill className=\"size-4 shrink-0\" aria-hidden />\n      </DropdownTrigger>\n\n      <DropdownPopover\n        aria-label={`More actions for ${title}`}\n        placement=\"bottom end\"\n        className=\"w-[190px] p-2\"\n      >\n        <DropdownGroup>\n          <DropdownItem onSelect={choose(onRename)} className=\"px-2 py-1.5\">\n            <span className=\"truncate text-body-medium whitespace-nowrap text-text-primary\">Rename</span>\n          </DropdownItem>\n          <DropdownItem onSelect={choose(onToggleUnread)} className=\"px-2 py-1.5\">\n            <span className=\"truncate text-body-medium whitespace-nowrap text-text-primary\">\n              Mark as unread\n            </span>\n          </DropdownItem>\n          <DropdownItem onSelect={choose(onDelete)} className=\"px-2 py-1.5\">\n            <span className=\"truncate text-body-medium whitespace-nowrap text-text-error-primary\">Delete</span>\n          </DropdownItem>\n        </DropdownGroup>\n      </DropdownPopover>\n    </Dropdown>\n  );\n}\n\n/** Compact ages for a narrow badge: now, 34m, 5h, 18h, 3d. */\nfunction relativeTime(at: number) {\n  const seconds = Math.max(0, Math.round((Date.now() - at) / 1000));\n  if (seconds < 60) return \"now\";\n  const minutes = Math.round(seconds / 60);\n  if (minutes < 60) return `${minutes}m`;\n  const hours = Math.round(minutes / 60);\n  if (hours < 24) return `${hours}h`;\n  return `${Math.round(hours / 24)}d`;\n}\n"
        },
        {
          "path": "components/boardui/base/avatar/avatar.tsx",
          "target": "@components/boardui/base/avatar/avatar.tsx",
          "type": "registry:component",
          "content": "/* eslint-disable @next/next/no-img-element */\nimport type { HTMLAttributes, Ref } from \"react\";\nimport { cx, sortCx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Figma source: Board UI → Avatar (styles Avatar/1…Avatar/26; used throughout\n * dashboard 1, node 3731:2932).\n *\n * Sizes used in the designs (px):\n *   xs = 20   breadcrumb workspace marks     (initials 10/15 semibold)\n *   sm = 24   table rows                     (initials 12/16 semibold)\n *   md = 32   sidebar workspace / team card  (initials 16/22 semibold)\n *   lg = 36   people cards                   (initials 18/24 semibold)\n *\n * Renders a photo when `src` is given, otherwise centered initials on a\n * tinted disc. Initial tints from Figma:\n *   neutral → bg avatar/neutral/background, text text/secondary\n *   blue    → bg color/blue/300,    text color/blue/900\n *   lime    → bg color/lime/200,    text color/lime/700\n *   pink    → bg color/pink/200,    text color/pink/500\n */\n\ntype AvatarSize = \"xs\" | \"sm\" | \"md\" | \"lg\";\ntype AvatarColor = \"neutral\" | \"blue\" | \"lime\" | \"pink\";\n\nexport interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {\n  size?: AvatarSize;\n  color?: AvatarColor;\n  /** Photo URL. Wins over `initials`. */\n  src?: string;\n  alt?: string;\n  /** Fallback initials, e.g. \"M\". */\n  initials?: string;\n  ref?: Ref<HTMLSpanElement>;\n}\n\nconst styles = sortCx({\n  base: \"inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full text-center align-middle transition-[width,height,font-size] duration-200 ease\",\n  size: {\n    xs: \"size-5 text-[10px] leading-[15px] font-semibold\",\n    sm: \"size-6 text-caption-1-semibold tracking-normal\",\n    md: \"size-8 text-headline-semibold\",\n    lg: \"size-9 text-[18px] leading-6 font-semibold\",\n  },\n  color: {\n    neutral: \"bg-avatar-neutral-background text-text-secondary\",\n    blue: \"bg-blue-300 text-blue-900\",\n    lime: \"bg-lime-200 text-lime-700\",\n    pink: \"bg-pink-200 text-pink-500\",\n  },\n});\n\nexport function Avatar({\n  size = \"md\",\n  color = \"neutral\",\n  src,\n  alt,\n  initials,\n  className,\n  ref,\n  ...props\n}: AvatarProps) {\n  return (\n    <span\n      ref={ref}\n      className={cx(styles.base, styles.size[size], styles.color[color], className)}\n      {...props}\n    >\n      {src ? (\n        <img\n          src={src}\n          alt={alt ?? \"\"}\n          loading=\"lazy\"\n          decoding=\"async\"\n          className=\"size-full object-cover\"\n        />\n      ) : (\n        initials\n      )}\n    </span>\n  );\n}\n"
        },
        {
          "path": "components/boardui/foundations/icons/chevrons.tsx",
          "target": "@components/boardui/foundations/icons/chevrons.tsx",
          "type": "registry:component",
          "content": "import type { SVGProps } from \"react\";\n\n/**\n * Custom chevron glyphs drawn as vectors in the Board UI Figma file (they are\n * not Remix icons). Paths are copied 1:1 from the Figma export.\n *\n * All icons render `currentColor` and size via Tailwind `size-*` utilities,\n * exactly like the Remix icon components.\n */\n\ntype IconProps = SVGProps<SVGSVGElement>;\n\n/** 16×16 rounded 2px-stroke chevron. Select triggers, disclosure affordances. */\nexport function ChevronDownSmall(props: IconProps) {\n  return (\n    <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden {...props}>\n      <path\n        d=\"M4 7L7.29289 10.2929C7.68342 10.6834 8.31658 10.6834 8.70711 10.2929L12 7\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n      />\n    </svg>\n  );\n}\n\n/** 12×12 rounded 1.5px-stroke chevron. Breadcrumb separator. */\nexport function ChevronRightSmall(props: IconProps) {\n  return (\n    <svg viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden {...props}>\n      <path\n        d=\"M4.5 3L7.14645 5.64645C7.34171 5.84171 7.34171 6.15829 7.14645 6.35355L4.5 9\"\n        stroke=\"currentColor\"\n        strokeWidth=\"1.5\"\n        strokeLinecap=\"round\"\n      />\n    </svg>\n  );\n}\n\n/** 16×16 stacked up/down chevrons. Workspace / account switchers. */\nexport function ChevronUpDownSmall(props: IconProps) {\n  return (\n    <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden {...props}>\n      <g transform=\"translate(4.25 2.56)\">\n        <path\n          d=\"M0.75 7.43934L3.21967 9.90901C3.51256 10.2019 3.98744 10.2019 4.28033 9.90901L6.75 7.43934\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.5\"\n          strokeLinecap=\"round\"\n        />\n        <path\n          d=\"M0.75 3.43934L3.21967 0.96967C3.51256 0.676777 3.98744 0.676777 4.28033 0.96967L6.75 3.43934\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.5\"\n          strokeLinecap=\"round\"\n        />\n      </g>\n    </svg>\n  );\n}\n\n/** 24×24 filled rounded triangle chevron. Table column sort indicator. */\nexport function ChevronSortDown(props: IconProps) {\n  return (\n    <svg viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden {...props}>\n      <path\n        d=\"M12.7071 15.2929C12.3166 15.6834 11.6834 15.6834 11.2929 15.2929L7.70711 11.7071C7.07714 11.0771 7.52331 10 8.41421 10H15.5858C16.4767 10 16.9229 11.0771 16.2929 11.7071L12.7071 15.2929Z\"\n        fill=\"currentColor\"\n      />\n    </svg>\n  );\n}\n"
        },
        {
          "path": "components/boardui/application/agent-chat/agent-chat-message.tsx",
          "target": "@components/boardui/application/agent-chat/agent-chat-message.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { RiCheckLine, RiFileCopyLine, RiVolumeMuteLine, RiVolumeUpLine } from \"@remixicon/react\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { memo, useEffect, useMemo, useState, type ReactNode } from \"react\";\n\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * One turn in the transcript.\n *\n * Assistant replies arrive a paragraph at a time, each softening in out of a\n * blur as it first appears and then only growing, so nothing already on screen\n * ever re-animates.\n *\n * The action row is deliberately mounted at all times and revealed on hover or\n * focus. Rendering it only on hover would make it unreachable by keyboard and\n * would shift the layout as the pointer moves across the transcript.\n */\n\nexport interface AgentMessageProps {\n  role: string;\n  text: string;\n  /** True while this message is still being streamed. */\n  streaming?: boolean;\n  /** When the message first appeared, for the hover timestamp. */\n  at?: number;\n}\nexport function AgentMessage({ role, text, streaming = false, at }: AgentMessageProps) {\n  if (!text) return null;\n\n  if (role === \"user\") {\n    return (\n      <p className=\"ml-auto flex w-fit max-w-[75%] flex-col rounded-2xl bg-background-primary-default px-3 py-[11px] text-left text-body-regular break-words whitespace-pre-wrap text-text-primary shadow-card\">\n        {text}\n      </p>\n    );\n  }\n\n  return (\n    <div className=\"group/message flex flex-col gap-1 px-1\">\n      <StreamedText text={text} />\n      <MessageActions text={text} at={at} hidden={streaming} />\n    </div>\n  );\n}\n\n/**\n * Paragraphs, each softening in once as it first appears.\n *\n * The animation deliberately lives at the line level rather than the word\n * level. Animating words looks worse in practice: a token arrives as a\n * fragment, the blur-in plays on that fragment, and then the fragment mutates\n * to the finished word with no transition — which reads as a stutter. It also\n * forces a swap from animated spans back to plain text when the stream ends,\n * and everything mid-flight snaps at once.\n *\n * A line mounts exactly once and then only grows, so nothing ever restarts or\n * snaps. Evenness of the text itself comes from the server, which releases\n * whole words on a steady tick (see `smoothStream` in the route).\n */\nfunction StreamedText({ text }: { text: string }) {\n  const reduceMotion = useReducedMotion();\n  const lines = useMemo(() => text.split(\"\\n\").filter((line) => line.trim() !== \"\"), [text]);\n\n  return (\n    <div className=\"flex flex-col gap-3\">\n      {lines.map((line, index) => (\n        <Line key={index} text={line} animate={!reduceMotion} />\n      ))}\n    </div>\n  );\n}\n\n/**\n * At module scope so their identity is stable. A line re-renders on every\n * token of the reply — dozens of times a second — and handing Motion a fresh\n * object literal each time invites it to re-evaluate a target that has not\n * actually changed.\n */\nconst LINE_HIDDEN = { opacity: 0, filter: \"blur(5px)\", y: 4 };\nconst LINE_SHOWN = { opacity: 1, filter: \"blur(0px)\", y: 0 };\nconst LINE_TRANSITION = { duration: 0.42, ease: [0.22, 0.61, 0.36, 1] } as const;\n\n/**\n * A settled line keeps `filter: blur(0px)` rather than losing the filter\n * altogether — Motion owns that property once it animates it, and a `style`\n * override does not win it back. At one filtered element per paragraph the\n * cost is invisible; it was only a problem when every word carried its own.\n *\n * memo matters here: without it every paragraph re-renders on each token of\n * the reply, which is wasted work for the lines that are already finished.\n */\nconst Line = memo(function Line({ text, animate }: { text: string; animate: boolean }) {\n  return (\n    <motion.p\n      initial={animate ? LINE_HIDDEN : false}\n      animate={LINE_SHOWN}\n      transition={LINE_TRANSITION}\n      className=\"text-body-regular break-words text-text-primary\"\n    >\n      {text}\n    </motion.p>\n  );\n});\n\nfunction MessageActions({ text, at, hidden }: { text: string; at?: number; hidden: boolean }) {\n  const [copied, setCopied] = useState(false);\n  const [speaking, setSpeaking] = useState(false);\n\n  useEffect(() => {\n    if (!copied) return;\n    const timer = setTimeout(() => setCopied(false), 1600);\n    return () => clearTimeout(timer);\n  }, [copied]);\n\n  // Speech keeps running if the component goes away mid-sentence, so it is\n  // cancelled on unmount rather than left talking over the next screen.\n  useEffect(() => {\n    return () => {\n      if (typeof window !== \"undefined\") window.speechSynthesis?.cancel();\n    };\n  }, []);\n\n  const copy = async () => {\n    try {\n      await navigator.clipboard.writeText(text);\n      setCopied(true);\n    } catch {\n      // Clipboard access can be refused (insecure origin, denied permission).\n      // Silently leaving the icon unchanged is better than a thrown error.\n    }\n  };\n\n  const toggleSpeech = () => {\n    const synth = typeof window === \"undefined\" ? undefined : window.speechSynthesis;\n    if (!synth) return;\n    if (speaking) {\n      synth.cancel();\n      setSpeaking(false);\n      return;\n    }\n    const utterance = new SpeechSynthesisUtterance(text);\n    utterance.onend = () => setSpeaking(false);\n    utterance.onerror = () => setSpeaking(false);\n    synth.cancel();\n    synth.speak(utterance);\n    setSpeaking(true);\n  };\n\n  return (\n    <div\n      className={cx(\n        \"flex items-center gap-1 transition-opacity duration-150\",\n        // Revealed on hover, and whenever a control inside has keyboard focus.\n        hidden\n          ? \"pointer-events-none opacity-0\"\n          : \"opacity-0 group-hover/message:opacity-100 focus-within:opacity-100\",\n      )}\n    >\n      <ActionButton label={copied ? \"Copied\" : \"Copy message\"} onClick={copy}>\n        {copied ? <RiCheckLine className=\"size-4\" aria-hidden /> : <RiFileCopyLine className=\"size-4\" aria-hidden />}\n      </ActionButton>\n\n      <ActionButton label={speaking ? \"Stop reading aloud\" : \"Read aloud\"} onClick={toggleSpeech}>\n        {speaking ? (\n          <RiVolumeMuteLine className=\"size-4\" aria-hidden />\n        ) : (\n          <RiVolumeUpLine className=\"size-4\" aria-hidden />\n        )}\n      </ActionButton>\n\n      {at ? (\n        <time dateTime={new Date(at).toISOString()} className=\"ml-1 text-caption-1-regular text-text-tertiary\">\n          {formatAgo(at)}\n        </time>\n      ) : null}\n    </div>\n  );\n}\n\nfunction ActionButton({\n  label,\n  onClick,\n  children,\n}: {\n  label: string;\n  onClick: () => void;\n  children: ReactNode;\n}) {\n  return (\n    <button\n      type=\"button\"\n      onClick={onClick}\n      aria-label={label}\n      title={label}\n      className=\"flex size-7 cursor-pointer items-center justify-center rounded-md text-foreground-icon-tertiary transition-colors hover:bg-background-primary-default hover:text-foreground-icon-secondary focus-visible:ring-2 focus-visible:ring-border-focus-ring focus-visible:outline-none\"\n    >\n      {children}\n    </button>\n  );\n}\n\n/** \"just now\", \"3 minutes ago\", \"2 hours ago\" — matching how the rail reads. */\nfunction formatAgo(at: number) {\n  const seconds = Math.max(0, Math.round((Date.now() - at) / 1000));\n  if (seconds < 45) return \"just now\";\n  const minutes = Math.round(seconds / 60);\n  if (minutes < 60) return `${minutes} minute${minutes === 1 ? \"\" : \"s\"} ago`;\n  const hours = Math.round(minutes / 60);\n  if (hours < 24) return `${hours} hour${hours === 1 ? \"\" : \"s\"} ago`;\n  const days = Math.round(hours / 24);\n  return `${days} day${days === 1 ? \"\" : \"s\"} ago`;\n}\n"
        },
        {
          "path": "components/boardui/application/agent-chat/agent-composer.tsx",
          "target": "@components/boardui/application/agent-chat/agent-composer.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  RiArrowUpLine,\n  RiAttachment2,\n  RiInfinityLine,\n  RiSparklingLine,\n  RiStopFill,\n} from \"@remixicon/react\";\nimport { useRef, type FormEvent, type KeyboardEvent } from \"react\";\n\nimport { ComposerLoader } from \"@/components/boardui/application/composer-loader/composer-loader\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * The free composer: a 52px pill with a text field and circular controls,\n * plus the thin status row beneath it.\n *\n * It matches the proportions of the Pro composer on purpose, so a starter\n * looks like it belongs to the same product — the fixed-height pill, 8px\n * padding with 36px circles sitting flush inside it, and the 10px gap rhythm\n * across the row. What it deliberately does NOT carry is the paid work in\n * `composer`: the liquid-glass surfaces behind the controls, the model and\n * effort menus, the attachment plugin panel, and the voice equalizer. Those\n * are the reason someone buys that component, so this one leaves the slots\n * present but plain.\n *\n * The status row shows what is actually true of the running app — which\n * provider answered, which model, how many messages are in the thread —\n * rather than decorative chrome, so it stays honest in a deployed starter.\n */\n\nexport interface AgentComposerProps {\n  value: string;\n  onValueChange: (value: string) => void;\n  onSubmit: () => void;\n  onStop: () => void;\n  busy: boolean;\n  /** Model id reported by the runtime, e.g. \"openai/gpt-5-nano\". */\n  model?: string | null;\n  provider?: string | null;\n  messageCount: number;\n  className?: string;\n}\nexport function AgentComposer({\n  value,\n  onValueChange,\n  onSubmit,\n  onStop,\n  busy,\n  model,\n  provider,\n  messageCount,\n  className,\n}: AgentComposerProps) {\n  const inputRef = useRef<HTMLInputElement>(null);\n\n  const submit = (event: FormEvent) => {\n    event.preventDefault();\n    onSubmit();\n  };\n\n  const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n    if (event.key === \"Enter\" && !event.shiftKey) {\n      event.preventDefault();\n      onSubmit();\n    }\n  };\n\n  return (\n    <div className={cx(\"flex w-full flex-col gap-2.5\", className)}>\n      {/* radius omitted: ComposerLoader defaults to a full pill, matching the form. */}\n      <ComposerLoader active={busy}>\n        {/* The pill sits one step lighter than the chat surface behind it in\n            both themes (white on neutral-100 in light, neutral-800 on\n            neutral-900 in dark), so a single token works without a dark\n            override. Its controls then step back down to secondary. */}\n        <form\n          onSubmit={submit}\n          className={cx(\n            \"flex h-[52px] w-full items-center gap-2.5 rounded-full p-2\",\n            // ComposerLoader paints its own pill surface and runs the light\n            // behind its children, so an opaque form would cover the light\n            // entirely. While busy the form steps aside and lets it show.\n            busy ? \"bg-transparent\" : \"bg-background-primary-default shadow-xs\",\n          )}\n        >\n          {/* Attachment slot. Plain on purpose — the plugin panel behind this\n              button in the Pro composer is part of what that component sells. */}\n          {/* Shares the Pro composer's add-button tokens so the two read as the\n              same control. They resolve one step lighter than the pill in dark\n              and one step darker in light, which is why a single pair works for\n              both themes without a dark: override. */}\n          <button\n            type=\"button\"\n            aria-label=\"Add attachment\"\n            className=\"flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-full bg-ai-chat-composer-add-background text-foreground-icon-primary transition-colors duration-150 ease hover:bg-ai-chat-composer-add-hover-background\"\n          >\n            <RiAttachment2 className=\"size-5\" aria-hidden />\n          </button>\n\n          <label className=\"sr-only\" htmlFor=\"agent-composer-input\">\n            Message\n          </label>\n          <input\n            id=\"agent-composer-input\"\n            ref={inputRef}\n            type=\"text\"\n            value={value}\n            onChange={(event) => onValueChange(event.target.value)}\n            onKeyDown={onKeyDown}\n            placeholder=\"Ask me anything\"\n            autoComplete=\"off\"\n            className=\"h-5 min-w-0 flex-1 bg-transparent text-body-regular text-text-primary caret-text-primary outline-none placeholder:text-text-tertiary\"\n          />\n\n          {model ? (\n            <span\n              // Static where the Pro composer puts its model picker: the model\n              // is set by an env var, so there is nothing to switch at runtime.\n              className=\"flex h-8 shrink-0 items-center gap-1 rounded-xl py-1.5 pr-2 pl-2 text-body-2-medium text-text-secondary\"\n              title={`Answering with ${model}`}\n            >\n              <RiSparklingLine className=\"size-4 shrink-0 text-foreground-icon-secondary\" aria-hidden />\n              <span className=\"hidden max-w-[13ch] truncate sm:inline\">{shortModel(model)}</span>\n            </span>\n          ) : null}\n\n          <div className=\"flex shrink-0 items-center gap-2 pl-1.5\">\n            {busy ? (\n              <button\n                type=\"button\"\n                onClick={onStop}\n                aria-label=\"Stop generating\"\n                className=\"flex size-9 cursor-pointer items-center justify-center rounded-full bg-background-secondary-default text-foreground-icon-secondary transition-colors hover:bg-background-secondary-hover\"\n              >\n                <RiStopFill className=\"size-5\" aria-hidden />\n              </button>\n            ) : (\n              <button\n                type=\"submit\"\n                aria-label=\"Send message\"\n                disabled={value.trim().length === 0}\n                className=\"flex size-9 cursor-pointer items-center justify-center rounded-full bg-button-primary text-white transition-opacity disabled:cursor-not-allowed disabled:opacity-40\"\n              >\n                <RiArrowUpLine className=\"size-5\" aria-hidden />\n              </button>\n            )}\n          </div>\n        </form>\n      </ComposerLoader>\n\n      <div className=\"flex h-[26px] w-full items-center justify-between\">\n        <div className=\"flex items-center gap-3\">\n          <StatusItem icon={RiInfinityLine} label={provider ?? \"Not configured\"} />\n        </div>\n        <div className=\"flex items-center gap-3\">\n          <StatusItem\n            icon={RiSparklingLine}\n            label={messageCount === 0 ? \"New chat\" : `${messageCount} messages`}\n          />\n        </div>\n      </div>\n    </div>\n  );\n}\n\nfunction StatusItem({\n  icon: Icon,\n  label,\n}: {\n  icon: typeof RiInfinityLine;\n  label: string;\n}) {\n  return (\n    <span className=\"flex items-center gap-1\">\n      <Icon className=\"size-4 shrink-0 text-foreground-icon-secondary\" aria-hidden />\n      <span className=\"whitespace-nowrap text-body-2-medium text-text-secondary\">{label}</span>\n    </span>\n  );\n}\n\n/** \"openai/gpt-5-nano\" reads better in a 13ch slot as \"gpt-5-nano\". */\nfunction shortModel(model: string) {\n  const slash = model.lastIndexOf(\"/\");\n  return slash === -1 ? model : model.slice(slash + 1);\n}\n"
        },
        {
          "path": "components/boardui/application/composer-loader/composer-loader.tsx",
          "target": "@components/boardui/application/composer-loader/composer-loader.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useId, useRef, useState } from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Composer Loader — a loading state that wraps a chat composer while the agent\n * works: an iridescent light band orbiting the pill's rim with a soft bloom\n * bleeding inward.\n *\n * The band is dash segments on an SVG stroke of the pill shape\n * (pathLength-normalized, so it travels at constant speed and bends around\n * the end caps), drawn at three scales — crisp line, tight glow, wide bloom —\n * with the sharp line leading and every soft layer's head pulled back behind\n * the tip.\n *\n * The component paints the pill surface itself and layers the light above\n * it, so the wrapped composer must not paint its own background:\n *\n *   <ComposerLoader active={isWaitingForReply}>\n *     <Composer className=\"bg-transparent shadow-none\" />\n *   </ComposerLoader>\n *\n * `active` fades the whole effect in and out (450ms), so toggling it on\n * send / reply reads as the composer lighting up rather than snapping.\n */\n\nexport interface ComposerLoaderProps {\n  children: ReactNode;\n  /** Show the light. Fades in/out — flip it while awaiting a response. */\n  active?: boolean;\n  /** Four gradient colors, spread across the pill left → right. */\n  colors?: [string, string, string, string];\n  /** Seconds per full lap. */\n  speed?: number;\n  /** Overall light opacity. */\n  intensity?: number;\n  /** How far the bloom bleeds inward from the rim, px. */\n  bloom?: number;\n  /** Bloom layer opacity. */\n  bloomStrength?: number;\n  /** How much of the perimeter the band occupies, degrees (of 360). */\n  arc?: number;\n  /** Reverse the travel direction. */\n  reverse?: boolean;\n  /** Corner radius, px. Defaults to a full pill. */\n  radius?: number;\n  /** Width of the crisp line, px; the tight glow scales with it. */\n  line?: number;\n  /** Draw the wide bloom alone, no line or tight glow: a soft wash for a beam to lead. */\n  bloomOnly?: boolean;\n  /** Paint the pill surface behind the light (on by default). */\n  surface?: boolean;\n  /**\n   * Fade the band's two ends instead of cutting them, 0–1: the fraction of\n   * the band's length that ramps. Each layer is stacked as shorter, centred\n   * copies at a fraction of its opacity; the blur melts the steps together.\n   */\n  taper?: number;\n  /** How the light composites over what's beneath, e.g. `screen` to read as light on a surface. */\n  blend?: CSSProperties[\"mixBlendMode\"];\n  /**\n   * Moves the band forward along the lap, as a fraction of the perimeter\n   * (0–1). Lets two loaders on one pill line up: a short beam with\n   * `offset` equal to the difference of the two arcs (as fractions) leads\n   * a wider glow tip to tip.\n   */\n  offset?: number;\n  className?: string;\n}\nconst DEFAULT_COLORS: [string, string, string, string] = [\n  \"#5eead4\",\n  \"#46baec\",\n  \"#e633a4\",\n  \"#00faa7\",\n];\n\nfunction hexTriplet(hex: string) {\n  return [\n    parseInt(hex.slice(1, 3), 16),\n    parseInt(hex.slice(3, 5), 16),\n    parseInt(hex.slice(5, 7), 16),\n  ];\n}\n\nexport function ComposerLoader({\n  children,\n  active = true,\n  colors = DEFAULT_COLORS,\n  speed = 4.5,\n  intensity = 0.7,\n  bloom = 16,\n  bloomStrength = 0.3,\n  arc = 120,\n  reverse = false,\n  radius,\n  line = 2.5,\n  bloomOnly = false,\n  surface = true,\n  taper = 0,\n  blend,\n  offset = 0,\n  className,\n}: ComposerLoaderProps) {\n  const gradientId = `bui-cl-${useId().replace(/[^a-zA-Z0-9]/g, \"\")}`;\n  const clipRef = useRef<HTMLSpanElement>(null);\n  const [box, setBox] = useState({ w: 640, h: 52 });\n\n  useEffect(() => {\n    const el = clipRef.current;\n    if (!el) return;\n    const observer = new ResizeObserver(() =>\n      setBox({ w: Math.max(1, el.clientWidth), h: Math.max(1, el.clientHeight) }),\n    );\n    observer.observe(el);\n    return () => observer.disconnect();\n  }, []);\n\n  const [c0, c1, c2, c3] = colors;\n  // Gradient center: pure blend of the middle colors, so the band never\n  // washes out to white.\n  const mid = `rgb(${hexTriplet(c1)\n    .map((v, i) => Math.round((v + hexTriplet(c2)[i]) / 2))\n    .join(\",\")})`;\n\n  const band = (arc / 360) * 100;\n  const rx = radius ?? box.h / 2;\n  const cornerRadius = radius ?? 9999;\n  const direction = reverse ? \"reverse\" : \"normal\";\n\n  // Path units per px, for pulling each soft layer's head behind the tip.\n  // Rounded-rect perimeter: straight runs plus the four corner arcs (for the\n  // default pill, rx = h/2 and this reduces to 2(w−h) + πh).\n  const cornerR = Math.min(rx, box.w / 2, box.h / 2);\n  const perimeter = Math.max(1, 2 * (box.w + box.h) - 8 * cornerR + 2 * Math.PI * cornerR);\n  const pxUnits = (px: number) => (px * 100) / perimeter;\n  // A layer's delay is its phase: the larger the phase, the further BACK\n  // along the lap the band sits (a negative delay is a head start). So\n  // moving a band forward, `offset` included, means subtracting.\n  const dashPhase = (len: number, backPx: number) =>\n    (reverse ? pxUnits(backPx) : len - band + pxUnits(backPx)) - offset * 100;\n\n  // Tapering stacks each layer as shorter, centred copies: the ramp at each\n  // end is a staircase with one step per copy, so it takes many copies and\n  // a little blur on the crisp line for the steps to melt into a gradient.\n  const TAPER_STEPS = 14;\n  const CRISP_BLUR = taper > 0 ? Math.max(0.5, line * 0.8) : 0.5;\n  const stroke = (width: number, blur: number, opacity: number, dashLen: number, backPx: number) => {\n    const copies = taper > 0 ? TAPER_STEPS : 1;\n    return Array.from({ length: copies }, (_, index) => {\n      // Copy 0 is the full band; each next one is shorter and moved forward\n      // by half the difference, so all of them share one midpoint and the\n      // ends thin out step by step.\n      const len = dashLen * (1 - (taper * index) / copies);\n      const phase = dashPhase(dashLen, backPx) - (dashLen - len) / 2;\n      return (\n        <rect\n          key={index}\n          x={0}\n          y={0}\n          width={box.w}\n          height={box.h}\n          rx={rx}\n          pathLength={100}\n          fill=\"none\"\n          stroke={`url(#${gradientId})`}\n          strokeWidth={width}\n          strokeLinecap=\"round\"\n          strokeDasharray={`${len} ${100 - len}`}\n          className=\"bui-composer-loader-rect\"\n          // SVG-native blur, not CSS filter: WebKit (iOS Safari and every iPhone\n          // browser) ignores CSS filters on individual SVG elements, which\n          // rendered the whole light razor-sharp on phones.\n          filter={blur > 0 ? `url(#${gradientId}-b${String(blur).replace(\".\", \"_\")})` : undefined}\n          style={{\n            opacity: opacity / copies,\n            animation: `bui-composer-loader-dash ${speed}s linear ${(phase * speed) / 100}s infinite ${direction}`,\n          }}\n        />\n      );\n    });\n  };\n\n  /** One feGaussianBlur per blur radius the layers use. The region is\n   *  widened well past the stroke so the blur never clips at the filter\n   *  bounds. */\n  const blurFilter = (radius: number) => (\n    <filter\n      key={radius}\n      id={`${gradientId}-b${String(radius).replace(\".\", \"_\")}`}\n      x=\"-50%\"\n      y=\"-50%\"\n      width=\"200%\"\n      height=\"200%\"\n    >\n      <feGaussianBlur stdDeviation={radius} />\n    </filter>\n  );\n\n  return (\n    <div className={cx(\"relative\", className)}>\n      {surface && (\n        <span\n          aria-hidden\n          className=\"absolute inset-0 bg-background-primary-default shadow-xs\"\n          style={{ borderRadius: cornerRadius }}\n        />\n      )}\n\n      <span\n        ref={clipRef}\n        aria-hidden\n        className=\"pointer-events-none absolute inset-0 overflow-hidden\"\n        style={{\n          borderRadius: cornerRadius,\n          opacity: active ? 1 : 0,\n          transition: \"opacity 450ms ease\",\n          mixBlendMode: blend,\n        }}\n      >\n        <svg\n          width=\"100%\"\n          height=\"100%\"\n          viewBox={`0 0 ${box.w} ${box.h}`}\n          preserveAspectRatio=\"none\"\n          style={{ opacity: intensity }}\n        >\n          <defs>\n            <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\">\n              <stop offset=\"0%\" stopColor={c0} />\n              <stop offset=\"30%\" stopColor={c1} />\n              <stop offset=\"50%\" stopColor={mid} />\n              <stop offset=\"70%\" stopColor={c2} />\n              <stop offset=\"100%\" stopColor={c3} />\n            </linearGradient>\n            {[14, 6, CRISP_BLUR].map(blurFilter)}\n          </defs>\n          {/* wide bloom bleeding inward (outer half clipped by the pill) */}\n          {bloom > 0 && stroke(bloom * 2, 14, bloomStrength, band * 0.9, bloom + 16)}\n          {/* tight glow */}\n          {!bloomOnly && stroke(line * 3.2, 6, 0.8, band * 0.95, 10)}\n          {/* crisp refraction line, tip leading */}\n          {!bloomOnly && stroke(line, CRISP_BLUR, 1, band, 0)}\n        </svg>\n      </span>\n\n      <div className=\"relative\">{children}</div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/boardui/application/agent-chat/demo-transport.ts",
          "target": "@components/boardui/application/agent-chat/demo-transport.ts",
          "type": "registry:component",
          "content": "import type { ChatTransport, UIMessage, UIMessageChunk } from \"ai\";\n\nimport { pickDemoAnswer } from \"@/components/boardui/application/agent-chat/demo-answers\";\n\n/** A beat before the first word, so the thinking indicator reads as thinking. */\nconst THINK_MS = 700;\n/** Per word. Slightly faster than a model, since there is nothing to wait for. */\nconst WORD_MS = 28;\n\nconst wait = (ms: number, signal?: AbortSignal) =>\n  new Promise<void>((resolve, reject) => {\n    const timer = setTimeout(resolve, ms);\n    signal?.addEventListener(\"abort\", () => {\n      clearTimeout(timer);\n      reject(new DOMException(\"Aborted\", \"AbortError\"));\n    });\n  });\n\nfunction lastUserText(messages: UIMessage[]): string {\n  const last = [...messages].reverse().find((message) => message.role === \"user\");\n  return (\n    last?.parts\n      .filter((part): part is { type: \"text\"; text: string } => part.type === \"text\")\n      .map((part) => part.text)\n      .join(\"\\n\") ?? \"\"\n  );\n}\n/**\n * The chat transport for a deploy that has no model key yet. It speaks the\n * same UI-message stream the real route does, so `useChat` cannot tell the\n * difference: the words arrive one at a time, Stop works, and the thread is\n * saved like any other. Only the words are scripted.\n */\nexport class DemoTransport implements ChatTransport<UIMessage> {\n  async sendMessages({\n    messages,\n    abortSignal,\n  }: {\n    messages: UIMessage[];\n    abortSignal: AbortSignal | undefined;\n  }): Promise<ReadableStream<UIMessageChunk>> {\n    const reply = pickDemoAnswer(lastUserText(messages));\n    const id = `demo-${Date.now()}`;\n    return new ReadableStream<UIMessageChunk>({\n      async start(controller) {\n        try {\n          controller.enqueue({ type: \"start\" });\n          controller.enqueue({ type: \"start-step\" });\n          await wait(THINK_MS, abortSignal);\n          controller.enqueue({ type: \"text-start\", id });\n          const words = reply.split(/(?<=\\s)/);\n          for (const word of words) {\n            await wait(WORD_MS, abortSignal);\n            controller.enqueue({ type: \"text-delta\", id, delta: word });\n          }\n          controller.enqueue({ type: \"text-end\", id });\n          controller.enqueue({ type: \"finish-step\" });\n          controller.enqueue({ type: \"finish\" });\n        } catch {\n          controller.enqueue({ type: \"abort\" });\n        } finally {\n          controller.close();\n        }\n      },\n    });\n  }\n\n  async reconnectToStream(): Promise<ReadableStream<UIMessageChunk> | null> {\n    return null;\n  }\n}\n\n/**\n * Holds both transports and answers per request: a send carrying\n * `body.demo` goes to the script, anything else to the real route. Nothing is\n * mutated after construction, so `useChat` keeps one instance for good.\n */\nexport class SwitchingTransport implements ChatTransport<UIMessage> {\n  constructor(\n    private readonly live: ChatTransport<UIMessage>,\n    private readonly canned: ChatTransport<UIMessage>,\n  ) {}\n\n  sendMessages: ChatTransport<UIMessage>[\"sendMessages\"] = (options) => {\n    const demo = Boolean((options.body as { demo?: boolean } | undefined)?.demo);\n    return (demo ? this.canned : this.live).sendMessages(options);\n  };\n\n  reconnectToStream: ChatTransport<UIMessage>[\"reconnectToStream\"] = (options) =>\n    this.live.reconnectToStream(options);\n}\n"
        },
        {
          "path": "components/boardui/application/agent-chat/demo-answers.ts",
          "target": "@components/boardui/application/agent-chat/demo-answers.ts",
          "type": "registry:component",
          "content": "/**\n * What the chat says when there is no model behind it.\n *\n * Demo mode exists so the gallery can be tried without a model or secret: the\n * screen, the streaming, the history all behave as they do with a model, and\n * only the words are canned. Each answer says so, quietly, so nobody mistakes\n * it for a model's.\n */\n\ntype DemoAnswer = { match: RegExp; reply: string };\n\nconst ANSWERS: DemoAnswer[] = [\n  {\n    match: /starter|what (is|does) this|about this app|boardui/i,\n    reply:\n      \"This is BoardUI's free chat starter inside Agents Kit: streaming messages, local history, transcript actions, and the animated composer are installed as source you own. This gallery answer is canned and stays entirely in your browser.\",\n  },\n  {\n    match: /product update|announcement|release notes|changelog/i,\n    reply:\n      \"Here's a product update in three sentences. This release adds BoardUI's free streaming chat, four thinking indicators, and the animated composer loader to Agents Kit. Every component installs as source, including the local demo transport. This answer is canned so the preview never calls an external API.\",\n  },\n  {\n    match: /names?\\b.*\\b(app|product|scheduling|startup|company)|name ideas|suggest.*names/i,\n    reply:\n      \"Five names for a scheduling app: Slotwise, Tidemark, Cadence, Dayline, and Meridian. Slotwise says what it does, while Cadence and Meridian carry a rhythm. This is a canned local demo answer.\",\n  },\n  {\n    match: /key|api|openrouter|openai|anthropic|provider|model/i,\n    reply:\n      \"This gallery preview intentionally has no provider, model, secret, or API route. Its bundled transport emits the same UI message stream from a short local script.\",\n  },\n  {\n    match: /hello|hi\\b|hey|good (morning|afternoon|evening)/i,\n    reply:\n      \"Hello. I'm the starter's local demo assistant. Try asking what this starter does or request a short product update.\",\n  },\n];\n\nconst FALLBACK =\n  \"I'm a local scripted preview, and that question is not in the demo set. Try asking what this starter does or request a short product update.\";\n\nexport function pickDemoAnswer(prompt: string): string {\n  return ANSWERS.find((answer) => answer.match.test(prompt))?.reply ?? FALLBACK;\n}\n"
        },
        {
          "path": "components/boardui/application/agent-thinking/agent-thinking.tsx",
          "target": "@components/boardui/application/agent-thinking/agent-thinking.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport { cx } from \"@/components/boardui/utils/cx\";\n\n/**\n * Agent Thinking — the agent \"thinking\" state that sits above a chat composer\n * while a response is being worked on.\n *\n * Four curated variants:\n * - `wave`     dot grid with a diagonal wavefront gliding top-left → bottom-right\n * - `spin`     dot grid with a bright head orbiting the grid clockwise\n * - `stars`    sparkles twinkling in and out with a stagger\n * - `infinity` a comet trail sweeping a figure-eight\n *\n * Every variant pairs the indicator with a shimmering label and an elapsed\n * timer that starts when the loader mounts. Shimmer and CSS animations fall\n * back to static rendering under `prefers-reduced-motion` (see globals.css).\n */\n\nexport type AgentThinkingVariant = \"wave\" | \"spin\" | \"stars\" | \"infinity\";\nexport type AgentThinkingTone = \"subtle\" | \"default\" | \"primary\" | \"accent\";\n\nexport interface AgentThinkingProps {\n  variant?: AgentThinkingVariant;\n  /** Status label, e.g. \"Thinking\" or \"Searching the docs\". */\n  label?: string;\n  /** Tone of the indicator + label. Defaults per variant (`stars` is subtle). */\n  tone?: AgentThinkingTone;\n  /** Animated highlight traveling across the label. */\n  shimmer?: boolean;\n  /** Elapsed seconds since mount, rendered after the label. */\n  showTimer?: boolean;\n  className?: string;\n}\nconst TONE_COLORS: Record<AgentThinkingTone, string> = {\n  subtle: \"var(--color-text-tertiary)\",\n  default: \"var(--color-text-secondary)\",\n  primary: \"var(--color-text-primary)\",\n  accent: \"var(--color-blue-500)\",\n};\n\nconst VARIANT_TONE: Record<AgentThinkingVariant, AgentThinkingTone> = {\n  wave: \"default\",\n  spin: \"default\",\n  stars: \"subtle\",\n  infinity: \"default\",\n};\n\n/* ------------------------------------------------------------------- dots */\n\nconst DOTS_GRID = 3;\nconst DOTS_SIZE = 4;\nconst DOTS_GAP = 2;\nconst DOTS_TICK_MS = 80;\nconst DOTS_FADE_MS = 220;\nconst DOTS_TRAIL = 0.3;\nconst DOTS_MIN_OPACITY = 0.12;\nconst DOTS_PHASE_STEP = 1 / 8;\n\n// Static first frame: identical on server and client, and the resting state\n// under prefers-reduced-motion.\nconst DOTS_SEED = [0.55, 0.3, 0.15, 0.85, 0.55, 0.3, 1, 0.85, 0.55];\n\n/**\n * How far along the pattern's travel direction each cell sits, in [0, 1).\n * The wave scalar is compressed below 1 so the phase wrap reads as the front\n * leaving the grid and re-entering; the spin angle is naturally cyclic.\n */\nfunction dotScalar(variant: \"wave\" | \"spin\", col: number, row: number) {\n  const m = DOTS_GRID - 1;\n  if (variant === \"wave\") {\n    return ((col + row) / (2 * m)) * (DOTS_GRID / (DOTS_GRID + 1));\n  }\n  const center = m / 2;\n  return (Math.atan2(row - center, col - center) / (2 * Math.PI) + 1) % 1;\n}\n\nfunction dotOpacities(variant: \"wave\" | \"spin\", phase: number) {\n  return Array.from({ length: DOTS_GRID * DOTS_GRID }, (_, i) => {\n    const s = dotScalar(variant, i % DOTS_GRID, Math.floor(i / DOTS_GRID));\n    // Comet: bright head at the phase front, tail fading behind it.\n    const behind = (phase - s + 1) % 1;\n    const lit = Math.max(0, 1 - behind / DOTS_TRAIL) ** 1.5;\n    return DOTS_MIN_OPACITY + (1 - DOTS_MIN_OPACITY) * lit;\n  });\n}\n\nfunction DotsIndicator({ variant }: { variant: \"wave\" | \"spin\" }) {\n  const [opacities, setOpacities] = useState<number[]>(DOTS_SEED);\n\n  useEffect(() => {\n    if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n    let phase = 0;\n    const id = window.setInterval(() => {\n      phase = (phase + DOTS_PHASE_STEP) % 1;\n      setOpacities(dotOpacities(variant, phase));\n    }, DOTS_TICK_MS);\n    return () => window.clearInterval(id);\n  }, [variant]);\n\n  return (\n    <span\n      aria-hidden\n      className=\"grid shrink-0\"\n      style={{\n        gridTemplateColumns: `repeat(${DOTS_GRID}, ${DOTS_SIZE}px)`,\n        gap: DOTS_GAP,\n      }}\n    >\n      {opacities.map((opacity, i) => (\n        <span\n          key={i}\n          className=\"rounded-[1px] bg-current\"\n          style={{\n            width: DOTS_SIZE,\n            height: DOTS_SIZE,\n            opacity,\n            transition: `opacity ${DOTS_FADE_MS}ms ease`,\n          }}\n        />\n      ))}\n    </span>\n  );\n}\n\n/* ------------------------------------------------------------------ stars */\n\nconst STAR_PERIOD_S = 1.4;\nconst STAR_SIZE = 14;\nconst STAR_COUNT = 5;\nconst STAR_LAYOUT = [\n  { x: 50, y: 46, scale: 1 },\n  { x: 18, y: 22, scale: 0.55 },\n  { x: 82, y: 26, scale: 0.45 },\n  { x: 78, y: 76, scale: 0.55 },\n  { x: 22, y: 78, scale: 0.4 },\n];\nconst STAR_PATH = \"M12 0C13 7 17 11 24 12C17 13 13 17 12 24C11 17 7 13 0 12C7 11 11 7 12 0Z\";\n\nfunction StarsIndicator() {\n  const box = STAR_SIZE * 1.5;\n  return (\n    <span\n      aria-hidden\n      className=\"bui-agent-thinking-stars relative block shrink-0\"\n      style={{ width: box, height: box }}\n    >\n      {STAR_LAYOUT.slice(0, STAR_COUNT).map((star, i) => {\n        const size = STAR_SIZE * star.scale;\n        return (\n          <svg\n            key={i}\n            viewBox=\"0 0 24 24\"\n            className=\"bui-agent-thinking-star absolute\"\n            style={{\n              width: size,\n              height: size,\n              left: `${star.x}%`,\n              top: `${star.y}%`,\n              marginLeft: -size / 2,\n              marginTop: -size / 2,\n              animationDuration: `${STAR_PERIOD_S}s`,\n              animationDelay: `${(i * STAR_PERIOD_S * 0.7) / STAR_COUNT}s`,\n            }}\n          >\n            <path d={STAR_PATH} fill=\"currentColor\" />\n          </svg>\n        );\n      })}\n    </span>\n  );\n}\n\n/* --------------------------------------------------------------- infinity */\n\nconst INFINITY_WIDTH = 32;\nconst INFINITY_TRAIL = 11;\nconst INFINITY_STROKE = 2.75;\nconst INFINITY_DURATION_S = 1.2;\nconst INFINITY_PATH =\n  \"M28 14C33 5 47 5 47 14C47 23 33 23 28 14C23 5 9 5 9 14C9 23 23 23 28 14Z\";\n\nfunction InfinityIndicator() {\n  return (\n    <svg\n      aria-hidden\n      viewBox=\"0 0 56 28\"\n      className=\"shrink-0\"\n      // The figure-eight spans x 9-47 of the 56-wide viewBox, so the svg box\n      // carries ~4px of dead space per side at this width; pull it back in so\n      // the label sits at the loader's real gap.\n      style={{ width: INFINITY_WIDTH, height: INFINITY_WIDTH / 2, margin: \"0 -4px\" }}\n    >\n      <path\n        d={INFINITY_PATH}\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={INFINITY_STROKE}\n        opacity={0.15}\n      />\n      <path\n        d={INFINITY_PATH}\n        pathLength={100}\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={INFINITY_STROKE}\n        strokeLinecap=\"round\"\n        strokeDasharray={`${INFINITY_TRAIL} ${100 - INFINITY_TRAIL}`}\n        className=\"bui-agent-thinking-comet\"\n        style={{ animationDuration: `${INFINITY_DURATION_S}s` }}\n      />\n    </svg>\n  );\n}\n\n/* ------------------------------------------------------------------ timer */\n\nfunction ElapsedTimer() {\n  const [elapsed, setElapsed] = useState(0);\n\n  useEffect(() => {\n    const started = performance.now();\n    const id = window.setInterval(\n      () => setElapsed((performance.now() - started) / 1000),\n      100,\n    );\n    return () => window.clearInterval(id);\n  }, []);\n\n  return (\n    <span className=\"font-mono text-caption-1-regular text-text-tertiary tabular-nums\">\n      {elapsed.toFixed(1)}s\n    </span>\n  );\n}\n\n/* ----------------------------------------------------------------- loader */\n\nexport function AgentThinking({\n  variant = \"wave\",\n  label = \"Thinking\",\n  tone,\n  shimmer = true,\n  showTimer = true,\n  className,\n}: AgentThinkingProps) {\n  const color = TONE_COLORS[tone ?? VARIANT_TONE[variant]];\n\n  return (\n    <div\n      role=\"status\"\n      className={cx(\"flex items-center gap-2.5\", className)}\n      style={{ color, \"--bui-agent-thinking-tone\": color } as CSSProperties}\n    >\n      {(variant === \"wave\" || variant === \"spin\") && <DotsIndicator variant={variant} />}\n      {variant === \"stars\" && <StarsIndicator />}\n      {variant === \"infinity\" && <InfinityIndicator />}\n      <span\n        aria-label={label}\n        className={cx(\"text-body-medium\", shimmer && \"bui-agent-thinking-label\")}\n      >\n        {label}\n      </span>\n      {showTimer && <ElapsedTimer />}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        }
      ],
      "categories": [
        "BoardUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-agent-screen",
      "type": "registry:block",
      "title": "Beautiful Original Agent Screen",
      "description": "Original Beautiful UI AgentScreen",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/AgentScreen.tsx",
          "target": "@components/beautiful-ui/original/primitives/AgentScreen.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Button } from \"../atoms/Button\";\n\n/* ─────────────────────────────────────────────────────────\n * AGENT SCREEN (live viewer)\n * Watch an agent work. The resting card is a framed capture of\n * the agent's screen; hover reveals an \"Open\" pill (the blue\n * accent Button). Open expands to a full-width viewer where you\n * can \"Teach a task\" — which starts recording — collapse\n * (recording keeps running, the card shows a red REC badge), and\n * end it.\n *\n * The screen is a placeholder image by default; pass a `streamSrc`\n * (image or video URL) to pipe in a real stream.\n * ───────────────────────────────────────────────────────── */\n\nconst PLACEHOLDER: string | undefined = undefined;\n\n/* aspect ratio of the placeholder capture (2964×1856) — used so the collapsed\n * card shows the whole desktop with no crop */\nconst SCREEN_ASPECT = \"aspect-[2964/1856]\";\n\nfunction Ico({ path, size = 15, sw = 2 }: { path: React.ReactNode; size?: number; sw?: number }) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={sw} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n      {path}\n    </svg>\n  );\n}\n\n/* minimize-2 — two arrows converging to the middle (collapse) */\nconst collapseIcon = (\n  <>\n    <polyline points=\"4 14 10 14 10 20\" />\n    <polyline points=\"20 10 14 10 14 4\" />\n    <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\" />\n    <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n  </>\n);\n\n/* maximize-2 — two arrows out to opposite corners (open) */\nconst openIcon = (\n  <>\n    <polyline points=\"15 3 21 3 21 9\" />\n    <polyline points=\"9 21 3 21 3 15\" />\n    <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\n    <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n  </>\n);\n\nfunction fmt(total: number) {\n  const m = Math.floor(total / 60);\n  const s = total % 60;\n  return `${String(m).padStart(2, \"0\")}:${String(s).padStart(2, \"0\")}`;\n}\n\n/* macOS-style pointer */\nfunction CursorSvg({ className, style }: { className?: string; style?: React.CSSProperties }) {\n  return (\n    <svg className={className} style={style} width=\"30\" height=\"30\" viewBox=\"0 0 24 24\" fill=\"#111318\" stroke=\"#fff\" strokeWidth=\"1.4\" strokeLinejoin=\"round\" aria-hidden>\n      <path d=\"M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z\" />\n    </svg>\n  );\n}\n\n/* collapsed card: a static decorative cursor sitting on the capture */\nfunction DriftCursor() {\n  return <CursorSvg className=\"agent-cursor\" style={{ left: \"42%\", top: \"53%\" }} />;\n}\n\n/* the agent's screen — a real stream via streamSrc, else a faux window.\n * Media is absolutely positioned so it always fills its (relative) parent —\n * an h-full chain through an aspect-ratio box can collapse and leak the bg. */\nfunction Screen({ streamSrc, cursor = true }: { streamSrc?: string; cursor?: boolean }) {\n  return (\n    <div className=\"absolute inset-0 overflow-hidden bg-inset\">\n      {streamSrc ? (\n        /\\.(mp4|webm|mov|m4v)(\\?|$)/i.test(streamSrc) ? (\n          <video src={streamSrc} autoPlay muted loop playsInline className=\"absolute inset-0 h-full w-full object-cover\" />\n        ) : (\n          // eslint-disable-next-line @next/next/no-img-element\n          <img src={streamSrc} alt=\"\" className=\"absolute inset-0 h-full w-full object-cover\" />\n        )\n      ) : (\n        <FauxWindow />\n      )}\n      {cursor && <DriftCursor />}\n    </div>\n  );\n}\n\n/* expanded viewer media — the image sizes itself within the viewport (bounded\n * by width and height) so the whole screen always fits with no crop */\nfunction MediaSizer({ src }: { src: string }) {\n  const style = { maxHeight: \"calc(100vh - 150px)\", maxWidth: \"min(960px, 90vw)\" } as const;\n  const cls = \"block h-auto w-auto object-contain\";\n  return /\\.(mp4|webm|mov|m4v)(\\?|$)/i.test(src) ? (\n    <video src={src} autoPlay muted loop playsInline className={cls} style={style} />\n  ) : (\n    // eslint-disable-next-line @next/next/no-img-element\n    <img src={src} alt=\"\" className={cls} style={style} />\n  );\n}\n\n/* connecting state — spinner on black, same ring as Task Rows */\nfunction LoadingScreen() {\n  const size = 26,\n    stroke = 2,\n    r = (size - stroke) / 2,\n    c = 2 * Math.PI * r;\n  return (\n    <div className=\"absolute inset-0 bg-black\">\n      {/* spinner dead-center; wrapper carries the centering so the beautiful-spin\n          transform on the svg doesn't override it */}\n      <span className=\"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2\">\n        <svg width={size} height={size} className=\"block\" style={{ animation: \"beautiful-spin 1.1s linear infinite\" }} aria-hidden>\n          <circle cx={size / 2} cy={size / 2} r={r} fill=\"none\" stroke=\"rgba(255,255,255,0.18)\" strokeWidth={stroke} />\n          <circle cx={size / 2} cy={size / 2} r={r} fill=\"none\" stroke=\"#fff\" strokeWidth={stroke} strokeLinecap=\"round\" strokeDasharray={`${c * 0.28} ${c * 0.72}`} />\n        </svg>\n      </span>\n      <span\n        className=\"absolute inset-x-0 text-center text-[12.5px] font-medium text-white/70\"\n        style={{ top: \"calc(50% + 28px)\" }}\n      >\n        Connecting to agent&apos;s screen\n      </span>\n    </div>\n  );\n}\n\nfunction FauxWindow() {\n  return (\n    <div className=\"flex h-full w-full flex-col bg-surface\">\n      <div className=\"flex shrink-0 items-center gap-1.5 border-b border-line bg-inset px-2.5 py-1.5\">\n        <span className=\"flex items-center gap-1\">\n          <span className=\"size-2 rounded-full bg-red\" />\n          <span className=\"size-2 rounded-full bg-orange\" />\n          <span className=\"size-2 rounded-full bg-green\" />\n        </span>\n        <span className=\"ml-1 flex min-w-0 items-center gap-1.5 rounded-t-[6px] bg-surface px-2 py-1 shadow-[0_-1px_0_var(--line)]\">\n          <span className=\"size-2 shrink-0 rounded-[3px] bg-accent-tint\" />\n          <span className=\"h-1.5 w-14 rounded-full bg-line-strong\" />\n        </span>\n      </div>\n      <div className=\"flex shrink-0 items-center gap-2 border-b border-line px-2.5 py-1.5 text-ink-3\">\n        <Ico size={12} path={<path d=\"M15 18l-6-6 6-6\" />} />\n        <Ico size={12} path={<path d=\"M9 6l6 6-6 6\" />} />\n        <span className=\"min-w-0 flex-1 truncate rounded-full bg-field px-2.5 py-[3px] font-mono text-[9px] text-ink-3\">\n          hunter.io/try/search/ugly.cash\n        </span>\n      </div>\n      <div className=\"flex flex-1 flex-col gap-2.5 overflow-hidden p-3\">\n        <div className=\"flex items-center gap-2\">\n          <span className=\"grid size-4 place-items-center rounded-[4px] bg-accent-tint text-[8px] font-bold text-accent\">h</span>\n          <span className=\"h-1.5 w-12 rounded-full bg-line-strong\" />\n          <span className=\"ml-auto h-4 w-12 rounded-full bg-inset shadow-btn\" />\n        </div>\n        <div className=\"flex items-center gap-2 rounded-[8px] bg-inset p-2\">\n          <span className=\"h-3 flex-1 rounded-full bg-surface shadow-hairline\" />\n          <span className=\"h-3 w-9 rounded-full bg-accent\" />\n        </div>\n        {[\"w-2/5\", \"w-1/2\", \"w-1/3\", \"w-2/5\"].map((w, i) => (\n          <div key={i} className=\"flex items-center gap-2.5\">\n            <span className=\"size-6 shrink-0 rounded-full bg-accent-tint\" />\n            <span className=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n              <span className={`h-1.5 rounded-full bg-line-strong ${w}`} />\n              <span className=\"h-1.5 w-3/5 rounded-full bg-line\" />\n            </span>\n          </div>\n        ))}\n      </div>\n    </div>\n  );\n}\n\nexport default function AgentScreen({\n  agentName = \"Agent\",\n  streamSrc = PLACEHOLDER,\n  variant,\n}: {\n  agentName?: string;\n  streamSrc?: string;\n  variant?: string;\n} = {}) {\n  const loading = variant === \"Loading\";\n  const [open, setOpen] = useState(false);\n  const [recording, setRecording] = useState(false);\n  const [secs, setSecs] = useState(0);\n  const [mounted, setMounted] = useState(false);\n  const [cursorPos, setCursorPos] = useState<{ x: number; y: number } | null>(null);\n\n  useEffect(() => setMounted(true), []);\n\n  // tick while recording — survives collapse (state lives here, not the overlay)\n  useEffect(() => {\n    if (!recording) return;\n    const id = setInterval(() => setSecs((s) => s + 1), 1000);\n    return () => clearInterval(id);\n  }, [recording]);\n\n  // lock scroll + Esc-to-collapse while the viewer is open\n  useEffect(() => {\n    if (!open) return;\n    const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && setOpen(false);\n    document.addEventListener(\"keydown\", onKey);\n    document.body.style.overflow = \"hidden\";\n    return () => {\n      document.removeEventListener(\"keydown\", onKey);\n      document.body.style.overflow = \"\";\n    };\n  }, [open]);\n\n  const startRecording = () => {\n    setSecs(0);\n    setRecording(true);\n  };\n  const endRecording = () => {\n    setRecording(false);\n    setSecs(0);\n  };\n\n  const controls = (\n    <div className=\"flex shrink-0 items-center gap-1.5\">\n      {recording ? (\n        <button\n          type=\"button\"\n          onClick={endRecording}\n          className=\"inline-flex h-[27px] items-center gap-1.5 rounded-full bg-red pl-2.5 pr-3 text-[13px] font-medium leading-none text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.14)] transition-[transform,filter] duration-150 ease-out hover:brightness-95 active:scale-[0.96]\"\n        >\n          <span className=\"size-2.5 rounded-[2px] bg-white\" />\n          End\n        </button>\n      ) : (\n        <Button variant=\"secondary\" size=\"sm\" className=\"gap-1 pl-1.5\" onClick={startRecording}>\n          <Ico size={15} path={<><circle cx=\"12\" cy=\"12\" r=\"9\" /><circle cx=\"12\" cy=\"12\" r=\"3.5\" fill=\"currentColor\" stroke=\"none\" /></>} />\n          Teach a task\n        </Button>\n      )}\n      <button\n        type=\"button\"\n        aria-label=\"Collapse\"\n        onClick={() => setOpen(false)}\n        className=\"primitive-icon-button text-ink-3 transition-colors duration-100 hover:bg-hover hover:text-ink\"\n      >\n        <Ico size={15} path={collapseIcon} />\n      </button>\n    </div>\n  );\n\n  return (\n    <div className=\"w-full max-w-[340px]\">\n      {/* ── resting card — hover/click scoped to the Mac window only ── */}\n      <div\n        className={`group/screen relative ${SCREEN_ASPECT} overflow-hidden rounded-window bg-inset shadow-card transition-shadow duration-150 ${\n          loading ? \"\" : \"cursor-pointer hover:shadow-raised\"\n        }`}\n        onClick={loading ? undefined : () => setOpen(true)}\n        style={{ animation: \"beautiful-fade-up 380ms cubic-bezier(0.23,1,0.32,1) both\" }}\n      >\n        {loading ? (\n          <LoadingScreen />\n        ) : (\n          <>\n            <Screen streamSrc={streamSrc} />\n\n            {/* hover reveal — scoped to this frame's named group, not the gallery section */}\n            <div className=\"absolute inset-0 flex items-center justify-center bg-[rgba(17,19,24,0)] transition-colors duration-150 group-hover/screen:bg-[rgba(17,19,24,0.18)]\">\n              <span className=\"translate-y-1 opacity-0 transition duration-150 group-hover/screen:translate-y-0 group-hover/screen:opacity-100\">\n                <Button\n                  variant=\"accent\"\n                  size=\"sm\"\n                  onClick={(e) => {\n                    e.stopPropagation();\n                    setOpen(true);\n                  }}\n                >\n                  <Ico size={14} path={openIcon} />\n                  Open\n                </Button>\n              </span>\n            </div>\n          </>\n        )}\n      </div>\n\n      <div className=\"mt-2.5 truncate px-0.5 text-[13px] font-medium text-ink\">{agentName}&apos;s screen</div>\n\n      {/* ── expanded viewer — portaled to <body> so it takes over the whole page ── */}\n      {open &&\n        mounted &&\n        createPortal(\n          <div\n            className=\"beautiful-ui-scope fixed inset-0 z-[100] flex items-center justify-center p-4 text-ink sm:p-6\"\n            role=\"dialog\"\n            aria-modal=\"true\"\n            aria-label={`${agentName}'s screen`}\n          >\n            <div\n              className=\"absolute inset-0 bg-black/60 dark:bg-black/75\"\n              style={{ animation: \"beautiful-fade-in 180ms ease-out both\" }}\n              onClick={() => setOpen(false)}\n            />\n            <div\n              className=\"relative flex max-h-full flex-col overflow-hidden rounded-[16px] bg-surface p-2 pt-0 shadow-overlay\"\n              style={{ animation: \"beautiful-pop-in 240ms cubic-bezier(0.23,1,0.32,1) both\" }}\n            >\n              {/* title bar — agent name far left, controls right */}\n              <div className=\"flex h-11 shrink-0 items-center justify-between gap-3 px-1.5\">\n                <div className=\"flex min-w-0 items-center gap-2\">\n                  <span className=\"truncate text-[13px] font-semibold text-ink\">{agentName}</span>\n                  {recording && (\n                    <span className=\"inline-flex shrink-0 items-center gap-1.5 rounded-full bg-red-tint py-0.5 pl-1.5 pr-2 text-[11.5px] font-medium tabular-nums text-red\">\n                      <span className=\"size-2 rounded-full bg-red\" style={{ animation: \"beautiful-records-pulse 1.1s ease-in-out infinite\" }} />\n                      {fmt(secs)}\n                    </span>\n                  )}\n                </div>\n                {controls}\n              </div>\n\n              {/* the screen — inset with a little padding (the crop framing);\n                  the image sizes the window so the whole screen fits */}\n              <div\n                className=\"relative min-h-0 overflow-hidden rounded-[8px] bg-inset [cursor:none]\"\n                onMouseMove={(e) => {\n                  const r = e.currentTarget.getBoundingClientRect();\n                  setCursorPos({ x: e.clientX - r.left, y: e.clientY - r.top });\n                }}\n                onMouseLeave={() => setCursorPos(null)}\n              >\n                {loading ? (\n                  <div className={SCREEN_ASPECT} style={{ width: \"min(960px, 90vw)\" }}>\n                    <LoadingScreen />\n                  </div>\n                ) : streamSrc ? (\n                  <MediaSizer src={streamSrc} />\n                ) : (\n                  <div className={SCREEN_ASPECT} style={{ width: \"min(960px, 90vw)\" }}>\n                    <FauxWindow />\n                  </div>\n                )}\n                {!loading && cursorPos && (\n                  <CursorSvg\n                    className=\"pointer-events-none absolute z-10\"\n                    style={{ left: cursorPos.x, top: cursorPos.y, filter: \"drop-shadow(0 1px 1.5px rgba(0,0,0,0.35))\" }}\n                  />\n                )}\n              </div>\n            </div>\n          </div>,\n          document.body,\n        )}\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/Button.tsx",
          "target": "@components/beautiful-ui/original/atoms/Button.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { ButtonHTMLAttributes } from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../utils\";\n\nconst filledShadow = \"shadow-[inset_0_1px_0_rgba(255,255,255,0.14)]\";\n\n/* Pill-shaped by default — the app's core button style. Explicit symmetric\n * padding (not a fixed height) so the top/bottom spacing is always equal. */\nexport const buttonVariants = cva(\n  `inline-flex items-center justify-center font-medium select-none\n   transition-[transform,background-color,opacity] duration-150 ease-out\n   active:scale-[0.96] disabled:opacity-50 disabled:pointer-events-none`,\n  {\n    variants: {\n      variant: {\n        primary: `bg-ink text-canvas hover:opacity-90 dark:bg-ink dark:text-canvas ${filledShadow}`,\n        secondary: \"bg-surface text-ink shadow-btn hover:bg-inset aria-expanded:bg-hover\",\n        ghost: \"bg-hover-2 text-ink hover:bg-line-strong\",\n        accent: `bg-accent text-white hover:bg-accent-ink ${filledShadow}`,\n        success: `bg-green text-white hover:brightness-95 ${filledShadow}`,\n        /* transparent until hovered — for dense toolbars/action rows */\n        quiet: \"text-ink hover:bg-hover\",\n      },\n      size: {\n        /* compact toolbar pill — fixed height, lighter weight */\n        xs: \"h-7 rounded-full px-2.5 text-[12px] font-normal leading-none gap-1\",\n        /* canonical action pill — 27px tall, roomy sides */\n        sm: \"h-[27px] px-3 text-[13px] leading-none rounded-full gap-1.5\",\n        md: \"px-4 py-[9px] text-sm leading-none rounded-full gap-2\",\n      },\n    },\n    defaultVariants: { variant: \"secondary\", size: \"md\" },\n  },\n);\n\nexport type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>[\"variant\"]>;\n\nexport function Button({\n  variant,\n  size,\n  className,\n  ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>) {\n  return <button className={cn(buttonVariants({ variant, size }), className)} {...props} />;\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/utils.ts",
          "target": "@components/beautiful-ui/original/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Merge class names, letting later Tailwind classes win over conflicting earlier ones. */\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-approval-card",
      "type": "registry:block",
      "title": "Beautiful Original Approval Card",
      "description": "Original Beautiful UI ApprovalCard",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/ApprovalCard.tsx",
          "target": "@components/beautiful-ui/original/primitives/ApprovalCard.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useRef, useState, type CSSProperties } from \"react\";\nimport { Button } from \"../atoms/Button\";\nimport GlideMenu from \"./GlideMenu\";\n\n/* ─────────────────────────────────────────────────────────\n * APPROVAL CARD (human-in-the-loop)\n * One question at a time. The stack slides vertically as you\n * move between questions (the card's height animates to fit),\n * the step counter rolls like an odometer, and the footer uses\n * pill actions — a quiet Skip and a dark Continue with a ⏎.\n * Single-choice answers auto-advance; multi-select waits.\n * ───────────────────────────────────────────────────────── */\n\nexport type ApprovalQuestion = {\n  q: string;\n  type: \"radio\" | \"check\";\n  options: string[];\n};\n\nconst QUESTIONS: ApprovalQuestion[] = [\n  {\n    q: \"How many flavors should we launch?\",\n    type: \"radio\",\n    options: [\"Three (core line)\", \"Five (full case)\", \"Just one hero\"],\n  },\n  {\n    q: \"Which mix-ins should we stock?\",\n    type: \"check\",\n    options: [\"Chocolate chips\", \"Waffle bits\", \"Sprinkles\"],\n  },\n  {\n    q: \"Which market do we enter first?\",\n    type: \"radio\",\n    options: [\"Food trucks\", \"Grocery freezers\", \"Scoop shops\"],\n  },\n];\n\nexport type ApprovalLabels = {\n  skip: string;\n  continue: string;\n  send: string;\n  customPlaceholder: string;\n  sentMessage: string;\n};\n\nconst DEFAULT_LABELS: ApprovalLabels = {\n  skip: \"Skip\",\n  continue: \"Continue\",\n  send: \"Send\",\n  customPlaceholder: \"Something else…\",\n  sentMessage: \"Answers sent\",\n};\n\nconst ROLL_MS = 400;\nconst SLIDE = \"360ms cubic-bezier(0.22, 1, 0.36, 1)\";\n\n/* odometer digits — each character that changes rolls up (or down) */\nfunction RollingDigits({ value }: { value: string }) {\n  const prevRef = useRef(value);\n  const [oldVal, setOldVal] = useState(value);\n  const [newVal, setNewVal] = useState(value);\n  const [rolling, setRolling] = useState(false);\n  const [shifted, setShifted] = useState(false);\n  const [dir, setDir] = useState<\"up\" | \"down\">(\"up\");\n\n  useEffect(() => {\n    if (prevRef.current === value) return;\n    const from = prevRef.current;\n    prevRef.current = value;\n    const fromN = parseInt(from, 10);\n    const toN = parseInt(value, 10);\n    setDir(Number.isFinite(fromN) && Number.isFinite(toN) && toN < fromN ? \"down\" : \"up\");\n    setOldVal(from);\n    setNewVal(value);\n    setRolling(true);\n    setShifted(false);\n\n    let raf2 = 0;\n    const raf1 = requestAnimationFrame(() => {\n      raf2 = requestAnimationFrame(() => setShifted(true));\n    });\n    const done = setTimeout(() => {\n      setRolling(false);\n      setOldVal(value);\n      setShifted(false);\n    }, ROLL_MS);\n\n    return () => {\n      cancelAnimationFrame(raf1);\n      cancelAnimationFrame(raf2);\n      clearTimeout(done);\n    };\n  }, [value]);\n\n  const chars = rolling ? newVal : oldVal;\n\n  return (\n    <>\n      {Array.from({ length: chars.length }, (_, i) => {\n        const o = oldVal[i] ?? \"\";\n        const n = chars[i] ?? \"\";\n        if (!rolling || o === n) {\n          return <span key={`${i}-${n}`}>{n}</span>;\n        }\n        const top = dir === \"down\" ? n : o;\n        const bottom = dir === \"down\" ? o : n;\n        const restY = dir === \"down\" ? \"0\" : \"-1em\";\n        const startY = dir === \"down\" ? \"-1em\" : \"0\";\n        return (\n          <span\n            key={`${i}-${o}-${n}-${dir}`}\n            style={{ display: \"inline-block\", position: \"relative\", overflow: \"hidden\", height: \"1em\", lineHeight: \"1em\", verticalAlign: \"-0.05em\" }}\n          >\n            <span\n              style={{\n                display: \"flex\",\n                flexDirection: \"column\",\n                transition: \"transform 350ms cubic-bezier(0.4, 0, 0.2, 1)\",\n                transform: `translateY(${shifted ? restY : startY})`,\n              }}\n            >\n              <span style={{ height: \"1em\", lineHeight: \"1em\" }}>{top}</span>\n              <span style={{ height: \"1em\", lineHeight: \"1em\" }}>{bottom}</span>\n            </span>\n          </span>\n        );\n      })}\n    </>\n  );\n}\n\nfunction Ico({ path, size = 14, sw = 2 }: { path: React.ReactNode; size?: number; sw?: number }) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={sw} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n      {path}\n    </svg>\n  );\n}\n\nexport default function ApprovalCard({\n  questions = QUESTIONS,\n  labels,\n  onSubmitted,\n  onAnswerChange,\n  resettable = true,\n}: {\n  questions?: ApprovalQuestion[];\n  labels?: Partial<ApprovalLabels>;\n  onSubmitted?: (answers: Record<number, number[]>) => void;\n  onAnswerChange?: (questionIndex: number, answer: number[]) => void;\n  resettable?: boolean;\n  variant?: string;\n} = {}) {\n  const t = { ...DEFAULT_LABELS, ...labels };\n  const [qi, setQi] = useState(0);\n  const [answers, setAnswers] = useState<Record<number, number[]>>({});\n  const [custom, setCustom] = useState<Record<number, string>>({});\n  const [sent, setSent] = useState(false);\n  const [open, setOpen] = useState(true);\n\n  const advanceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n  const questionRefs = useRef<(HTMLDivElement | null)[]>([]);\n  const measured = useRef(false);\n  const [viewportH, setViewportH] = useState<number | undefined>(undefined);\n  const [trackY, setTrackY] = useState(0);\n  const [animate, setAnimate] = useState(false);\n  // Until the first question is measured, render only the active one so the\n  // initial (and SSR) height is Q1's height — not all questions stacked, which\n  // would flash to full height and then shrink on mount.\n  const [ready, setReady] = useState(false);\n\n  const last = qi === questions.length - 1;\n  const selected = answers[qi] ?? [];\n  const hasAnswer = selected.length > 0 || Boolean(custom[qi]?.trim());\n\n  const sync = (withAnim: boolean) => {\n    const item = questionRefs.current[qi];\n    if (!item) return;\n    const reduce = typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n    setViewportH(item.offsetHeight);\n    setTrackY(item.offsetTop);\n    setAnimate(withAnim && !reduce);\n  };\n\n  useLayoutEffect(() => {\n    const withAnim = measured.current;\n    measured.current = true;\n    sync(withAnim);\n    setReady(true);\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [qi, answers, custom, open, sent]);\n\n  useEffect(() => {\n    const id = requestAnimationFrame(() => sync(measured.current));\n    return () => cancelAnimationFrame(id);\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [qi]);\n\n  useEffect(() => () => { if (advanceTimer.current) clearTimeout(advanceTimer.current); }, []);\n\n  const goTo = (next: number) => {\n    if (advanceTimer.current) clearTimeout(advanceTimer.current);\n    setQi(Math.min(Math.max(next, 0), questions.length - 1));\n  };\n\n  const send = () => {\n    if (advanceTimer.current) clearTimeout(advanceTimer.current);\n    setSent(true);\n    onSubmitted?.(answers);\n  };\n\n  const advance = () => {\n    if (last) send();\n    else goTo(qi + 1);\n  };\n\n  const toggle = (index: number) => {\n    const type = questions[qi].type;\n    setAnswers((current) => {\n      const picked = current[qi] ?? [];\n      const next = type === \"radio\"\n        ? [index]\n        : picked.includes(index)\n          ? picked.filter((item) => item !== index)\n          : [...picked, index];\n      onAnswerChange?.(qi, next);\n      return { ...current, [qi]: next };\n    });\n    if (type === \"radio\") {\n      setCustom((current) => ({ ...current, [qi]: \"\" }));\n      if (advanceTimer.current) clearTimeout(advanceTimer.current);\n      advanceTimer.current = setTimeout(() => {\n        if (last) send();\n        else setQi((current) => Math.min(questions.length - 1, current + 1));\n      }, 480);\n    }\n  };\n\n  const reset = () => {\n    setQi(0);\n    setAnswers({});\n    setCustom({});\n    setSent(false);\n    setOpen(true);\n    measured.current = false;\n  };\n\n  if (!open) {\n    return (\n      <button type=\"button\" onClick={() => setOpen(true)} className=\"rounded-control bg-surface px-3 py-2 text-[12.5px] font-medium text-ink shadow-btn transition-colors duration-150 hover:bg-hover\">\n        Open approval\n      </button>\n    );\n  }\n\n  if (sent) {\n    return (\n      <div className=\"flex w-full max-w-80 items-center gap-3\" style={{ animation: \"beautiful-pop-in 260ms cubic-bezier(0.23,1,0.32,1) both\" }}>\n        <span className=\"inline-flex items-center gap-1.5 rounded-full bg-green-tint py-1 pr-2.5 pl-1 text-[12.5px] font-medium text-green\">\n          <span className=\"flex size-4.5 items-center justify-center rounded-full bg-green text-white\">\n            <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M20 6L9 17l-5-5\" /></svg>\n          </span>\n          {t.sentMessage}\n        </span>\n        {resettable && (\n          <button type=\"button\" onClick={reset} className=\"text-[12px] font-medium text-ink-3 transition-colors duration-150 hover:text-ink\">\n            Start over\n          </button>\n        )}\n      </div>\n    );\n  }\n\n  return (\n    <div className=\"w-full max-w-80\">\n      <div className=\"relative overflow-hidden rounded-card bg-surface shadow-card\" style={{ animation: \"beautiful-fade-up 380ms cubic-bezier(0.23,1,0.32,1) both\" }}>\n        <button\n          type=\"button\"\n          aria-label=\"Dismiss\"\n          onClick={() => setOpen(false)}\n          className=\"primitive-icon-button absolute right-2.5 top-2.5 z-10 text-ink-3 transition-colors duration-100 hover:bg-hover hover:text-ink\"\n        >\n          <Ico size={14} sw={2.2} path={<path d=\"M18 6L6 18M6 6l12 12\" />} />\n        </button>\n        <div className=\"primitive-card-pad\">\n          {/* the question itself is the heading */}\n          <div\n            className=\"overflow-hidden\"\n            style={{ height: viewportH, transition: animate ? `height ${SLIDE}` : undefined }}\n            aria-live=\"polite\"\n          >\n            <div\n              style={{\n                display: \"flex\",\n                flexDirection: \"column\",\n                gap: 26,\n                transform: `translate3d(0, ${-trackY}px, 0)`,\n                transition: animate ? `transform ${SLIDE}` : undefined,\n                willChange: \"transform\",\n              }}\n            >\n              {questions.map((question, qIdx) => {\n                const active = qIdx === qi;\n                // Before the first measure, mount only the active question so the\n                // card opens at its real height instead of flashing to full height.\n                if (!ready && !active) return null;\n                const picked = answers[qIdx] ?? [];\n                const questionStyle: CSSProperties = {\n                  opacity: active ? 1 : 0,\n                  transition: animate ? `opacity ${SLIDE}` : undefined,\n                  pointerEvents: active ? undefined : \"none\",\n                };\n                return (\n                  <div\n                    key={qIdx}\n                    ref={(el) => { questionRefs.current[qIdx] = el; }}\n                    aria-hidden={active ? undefined : true}\n                    style={questionStyle}\n                  >\n                    <div className=\"pr-7 text-[14px] font-medium text-ink\">{question.q}</div>\n                    <GlideMenu className=\"mt-2.5 flex flex-col gap-1\" highlightClassName=\"inset-x-0 rounded-control bg-hover\">\n                      {question.options.map((option, i) => {\n                        const on = picked.includes(i);\n                        return (\n                          <button\n                            key={option}\n                            type=\"button\"\n                            data-menu-row\n                            aria-pressed={on}\n                            tabIndex={active ? 0 : -1}\n                            onClick={() => { if (active) toggle(i); }}\n                            className=\"relative z-10 flex items-center gap-1.5 rounded-control pl-1 pr-2 py-1 text-left transition-colors duration-100\"\n                          >\n                            <span\n                              className={`flex size-4 shrink-0 items-center justify-center transition-colors duration-200\n                                ${question.type === \"radio\" ? \"rounded-full\" : \"rounded-[5px]\"}\n                                ${on ? \"bg-ink text-canvas\" : \"shadow-[inset_0_0_0_1.5px_var(--line-strong)] text-transparent\"}`}\n                            >\n                              {question.type === \"radio\" ? (\n                                <span className=\"size-1.5 rounded-full bg-canvas transition-transform duration-200\" style={{ transform: on ? \"scale(1)\" : \"scale(0)\" }} />\n                              ) : (\n                                <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M20 6L9 17l-5-5\" /></svg>\n                              )}\n                            </span>\n                            <span className={`text-[13px] leading-none transition-colors duration-200 ${on ? \"text-ink\" : \"text-ink-2\"}`}>\n                              {option}\n                            </span>\n                          </button>\n                        );\n                      })}\n                      <label data-menu-row className=\"relative z-10 flex items-center gap-1.5 rounded-control pl-1 pr-2 py-1 transition-colors duration-100\">\n                        <input\n                          value={custom[qIdx] ?? \"\"}\n                          tabIndex={active ? 0 : -1}\n                          onChange={(event) => {\n                            if (!active) return;\n                            setCustom((current) => ({ ...current, [qIdx]: event.target.value }));\n                            if (question.type === \"radio\") setAnswers((current) => ({ ...current, [qIdx]: [] }));\n                          }}\n                          onKeyDown={(event) => {\n                            if (event.key === \"Enter\" && hasAnswer) {\n                              event.preventDefault();\n                              advance();\n                            }\n                          }}\n                          placeholder={t.customPlaceholder}\n                          aria-label=\"Custom answer\"\n                          className=\"min-w-0 flex-1 bg-transparent pl-1.5 text-[13px] text-ink outline-none placeholder:text-ink-3\"\n                        />\n                      </label>\n                    </GlideMenu>\n                  </div>\n                );\n              })}\n            </div>\n          </div>\n        </div>\n\n        {/* footer — step nav (rolling counter) + pill actions */}\n        <div className=\"primitive-card-footer flex items-center justify-between gap-3\">\n          <div className=\"flex items-center gap-1 text-ink-3\">\n            <button\n              type=\"button\"\n              aria-label=\"Previous question\"\n              disabled={qi <= 0}\n              onClick={() => goTo(qi - 1)}\n              className=\"flex size-[18px] items-center justify-center rounded-[5px] transition-colors duration-100 enabled:hover:text-ink disabled:opacity-30\"\n            >\n              <Ico size={14} path={<path d=\"M18 15l-6-6-6 6\" />} />\n            </button>\n            <span className=\"inline-flex items-center text-[12px] font-medium tabular-nums text-ink-3\" style={{ letterSpacing: \"-0.1px\", lineHeight: 1 }}>\n              <RollingDigits value={`${qi + 1} / ${questions.length}`} />\n            </span>\n            <button\n              type=\"button\"\n              aria-label=\"Next question\"\n              disabled={last}\n              onClick={() => goTo(qi + 1)}\n              className=\"flex size-[18px] items-center justify-center rounded-[5px] transition-colors duration-100 enabled:hover:text-ink disabled:opacity-30\"\n            >\n              <Ico size={14} path={<path d=\"M6 9l6 6 6-6\" />} />\n            </button>\n          </div>\n\n          <div className=\"-mr-0.5 flex items-center gap-1.5\">\n            <Button variant=\"ghost\" size=\"sm\" onClick={() => (last ? setOpen(false) : goTo(qi + 1))}>\n              {t.skip}\n            </Button>\n            <Button variant=\"accent\" size=\"sm\" disabled={!hasAnswer} onClick={advance}>\n              {last ? t.send : t.continue}\n            </Button>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/Button.tsx",
          "target": "@components/beautiful-ui/original/atoms/Button.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { ButtonHTMLAttributes } from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../utils\";\n\nconst filledShadow = \"shadow-[inset_0_1px_0_rgba(255,255,255,0.14)]\";\n\n/* Pill-shaped by default — the app's core button style. Explicit symmetric\n * padding (not a fixed height) so the top/bottom spacing is always equal. */\nexport const buttonVariants = cva(\n  `inline-flex items-center justify-center font-medium select-none\n   transition-[transform,background-color,opacity] duration-150 ease-out\n   active:scale-[0.96] disabled:opacity-50 disabled:pointer-events-none`,\n  {\n    variants: {\n      variant: {\n        primary: `bg-ink text-canvas hover:opacity-90 dark:bg-ink dark:text-canvas ${filledShadow}`,\n        secondary: \"bg-surface text-ink shadow-btn hover:bg-inset aria-expanded:bg-hover\",\n        ghost: \"bg-hover-2 text-ink hover:bg-line-strong\",\n        accent: `bg-accent text-white hover:bg-accent-ink ${filledShadow}`,\n        success: `bg-green text-white hover:brightness-95 ${filledShadow}`,\n        /* transparent until hovered — for dense toolbars/action rows */\n        quiet: \"text-ink hover:bg-hover\",\n      },\n      size: {\n        /* compact toolbar pill — fixed height, lighter weight */\n        xs: \"h-7 rounded-full px-2.5 text-[12px] font-normal leading-none gap-1\",\n        /* canonical action pill — 27px tall, roomy sides */\n        sm: \"h-[27px] px-3 text-[13px] leading-none rounded-full gap-1.5\",\n        md: \"px-4 py-[9px] text-sm leading-none rounded-full gap-2\",\n      },\n    },\n    defaultVariants: { variant: \"secondary\", size: \"md\" },\n  },\n);\n\nexport type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>[\"variant\"]>;\n\nexport function Button({\n  variant,\n  size,\n  className,\n  ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>) {\n  return <button className={cn(buttonVariants({ variant, size }), className)} {...props} />;\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/utils.ts",
          "target": "@components/beautiful-ui/original/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Merge class names, letting later Tailwind classes win over conflicting earlier ones. */\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "target": "@components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useRef, useState, type ReactNode } from \"react\";\n\ntype GlideMenuProps = {\n  children: ReactNode;\n  className?: string;\n  highlightClassName?: string;\n  rowSelector?: string;\n};\n\n/** A single hover layer that glides between interactive menu rows. */\nexport default function GlideMenu({\n  children,\n  className = \"\",\n  highlightClassName = \"inset-x-0 rounded-[8px] bg-hover\",\n  rowSelector = \"[data-menu-row]\",\n}: GlideMenuProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const [box, setBox] = useState<{ top: number; height: number } | null>(null);\n  const [visible, setVisible] = useState(false);\n\n  const moveTo = (target: EventTarget | null) => {\n    const container = ref.current;\n    if (!(target instanceof Element) || !container) return;\n    const row = target.closest(rowSelector);\n    if (!(row instanceof HTMLElement) || !container.contains(row)) return;\n    const containerRect = container.getBoundingClientRect();\n    const rowRect = row.getBoundingClientRect();\n    setBox({ top: rowRect.top - containerRect.top, height: rowRect.height });\n    setVisible(true);\n  };\n\n  return (\n    <div\n      ref={ref}\n      onMouseOver={(event) => moveTo(event.target)}\n      onMouseLeave={() => setVisible(false)}\n      onFocusCapture={(event) => moveTo(event.target)}\n      onBlurCapture={(event) => {\n        if (!ref.current?.contains(event.relatedTarget as Node | null)) setVisible(false);\n      }}\n      className={`group/glide-menu relative ${className}`}\n    >\n      <span\n        aria-hidden\n        className={`pointer-events-none absolute ${highlightClassName}`}\n        style={{\n          top: box?.top ?? 0,\n          height: box?.height ?? 0,\n          opacity: box && visible ? 1 : 0,\n          transition:\n            \"top 220ms cubic-bezier(0.23,1,0.32,1), height 220ms cubic-bezier(0.23,1,0.32,1), opacity 150ms ease\",\n        }}\n      />\n      {children}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-chat-composer",
      "type": "registry:block",
      "title": "Beautiful Original Chat Composer",
      "description": "Original Beautiful UI ChatComposer",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/ChatComposer.tsx",
          "target": "@components/beautiful-ui/original/primitives/ChatComposer.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * CHAT — interactive panel with tabs, replies, and composer.\n * The reply sequence begins only after the user sends.\n * ───────────────────────────────────────────────────────── */\n\ntype Phase = \"idle\" | \"sent\" | \"reply1\" | \"reply2\" | \"done\";\n\n/* one scripted agent reply in the thread */\nexport type ChatMessage = {\n  label: string;\n  sub: string;\n  time: string;\n  body: string;\n};\n\nconst MESSAGES: ChatMessage[] = [\n  {\n    label: \"Sales History\",\n    sub: \"Flavor Data\",\n    time: \"4s\",\n    body: \"Pulled 3 summers of mint chip sales for comparison.\",\n  },\n  {\n    label: \"Comparison\",\n    sub: \"Trend Detection\",\n    time: \"2s\",\n    body: \"Mint chip is up 12% with stronger weekend peaks.\",\n  },\n];\n\nconst SUGGESTIONS = [\"Flavors\", \"Suppliers\"];\n\nexport type ChatComposerLabels = {\n  /** the pre-filled prompt shown in the first user bubble */\n  initialPrompt: string;\n  /** composer input placeholder */\n  placeholder: string;\n};\n\nconst DEFAULT_LABELS: ChatComposerLabels = {\n  initialPrompt: \"Compare mint chip to last summer\",\n  placeholder: \"Prompt or tag a flavor with @\",\n};\n\nfunction Section({\n  label,\n  sub,\n  time,\n  body,\n  resolving,\n}: {\n  label: string;\n  sub: string;\n  time: string;\n  body: string;\n  resolving?: boolean;\n}) {\n  return (\n    <div\n      className=\"flex w-full flex-col gap-1.5 transition-[opacity,filter,transform] duration-400\"\n      style={{\n        opacity: resolving ? 0.55 : 1,\n        filter: resolving ? \"blur(0.5px)\" : \"blur(0)\",\n        transform: resolving ? \"scale(0.985)\" : \"scale(1)\",\n        transformOrigin: \"top left\",\n        transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n        animation: \"beautiful-fade-up 400ms cubic-bezier(0.23,1,0.32,1) both\",\n      }}\n    >\n      <div className=\"flex items-center gap-1 text-[12px] leading-[1.3]\">\n        <span className=\"font-medium text-ink\">{label}</span>\n        <span className=\"text-ink-2\">{sub}</span>\n        <span className=\"text-ink\">for {time}</span>\n      </div>\n      <p className=\"text-[13px] leading-normal text-ink\">{body}</p>\n    </div>\n  );\n}\n\nexport default function ChatComposer({\n  messages = MESSAGES,\n  suggestions = SUGGESTIONS,\n  labels,\n  onSend,\n}: {\n  variant?: string;\n  /** scripted agent replies revealed in sequence after the user sends */\n  messages?: ChatMessage[];\n  /** header chips (tabs) for switching context */\n  suggestions?: string[];\n  /** prominent copy strings */\n  labels?: Partial<ChatComposerLabels>;\n  /** fired with the trimmed prompt text when the user sends */\n  onSend?: (text: string) => void;\n} = {}) {\n  const l = { ...DEFAULT_LABELS, ...labels };\n  const [phase, setPhase] = useState<Phase>(\"done\");\n  const [draft, setDraft] = useState(\"\");\n  const [submitted, setSubmitted] = useState(l.initialPrompt);\n  const [tab, setTab] = useState(suggestions[0] ?? \"\");\n  const inputRef = useRef<HTMLInputElement>(null);\n\n  useEffect(() => {\n    let t: ReturnType<typeof setTimeout>;\n    if (phase === \"sent\") t = setTimeout(() => setPhase(\"reply1\"), 500);\n    else if (phase === \"reply1\") t = setTimeout(() => setPhase(\"reply2\"), 1400);\n    else if (phase === \"reply2\") t = setTimeout(() => setPhase(\"done\"), 1200);\n    else return;\n    return () => clearTimeout(t);\n  }, [phase]);\n\n  const sent = phase !== \"idle\";\n  const canSend = draft.trim().length > 0;\n\n  const send = () => {\n    if (!canSend) return;\n    const text = draft.trim();\n    setSubmitted(text);\n    onSend?.(text);\n    setDraft(\"\");\n    setPhase(\"sent\");\n  };\n\n  return (\n    <div className=\"flex h-[288px] w-full max-w-95 flex-col self-start overflow-hidden rounded-[14px] bg-surface shadow-card\">\n      {/* header — tabs + actions */}\n      <div className=\"flex shrink-0 items-center justify-between border-b border-line p-1.5\">\n        <div className=\"flex items-center\">\n          {suggestions.map((item) => (\n            <button\n              key={item}\n              type=\"button\"\n              aria-pressed={tab === item}\n              onClick={() => setTab(item)}\n              className={`rounded-[6px] px-2 py-[3px] text-[13px] text-ink transition-[background-color,opacity] duration-100 ${tab === item ? \"bg-field\" : \"opacity-50 hover:opacity-75\"}`}\n            >\n              {item}\n            </button>\n          ))}\n        </div>\n        <div className=\"flex items-center gap-1\">\n          {[\n            <path key=\"p\" d=\"M12 5v14M5 12h14\" />,\n            <g key=\"h\"><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M12 7v5l3 2\" /></g>,\n            <g key=\"e\" fill=\"currentColor\" stroke=\"none\"><circle cx=\"5\" cy=\"12\" r=\"1.8\" /><circle cx=\"12\" cy=\"12\" r=\"1.8\" /><circle cx=\"19\" cy=\"12\" r=\"1.8\" /></g>,\n          ].map((icon, i) => (\n            <button\n              key={i}\n              type=\"button\"\n              aria-label=\"Action\"\n              className=\"flex size-6 items-center justify-center rounded-[6px] text-ink-3\n                transition-colors duration-100 hover:bg-hover hover:text-ink-2\"\n            >\n              <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n                {icon}\n              </svg>\n            </button>\n          ))}\n        </div>\n      </div>\n\n      {/* conversation — fixed region so the card never changes shape */}\n      <div className=\"flex min-h-0 flex-1 flex-col gap-2.5 overflow-y-auto px-3 pt-2.5 pb-1\">\n        {/* user bubble — right aligned, soft block */}\n        <div className=\"flex justify-end pl-14\">\n          <div\n            className=\"rounded-xl bg-field px-3 py-1.5 text-[13px] leading-[1.4] text-ink\n              transition-[opacity,transform] duration-300\"\n            style={{\n              opacity: sent ? 1 : 0,\n              transform: sent ? \"translateY(0)\" : \"translateY(10px)\",\n              transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n            }}\n          >\n            {submitted}\n          </div>\n        </div>\n\n        {messages[0] && (phase === \"reply1\" || phase === \"reply2\" || phase === \"done\") ? (\n          <Section\n            label={messages[0].label}\n            sub={messages[0].sub}\n            time={messages[0].time}\n            body={messages[0].body}\n          />\n        ) : null}\n        {messages[1] && (phase === \"reply2\" || phase === \"done\") ? (\n          <Section\n            label={messages[1].label}\n            sub={messages[1].sub}\n            time={messages[1].time}\n            body={messages[1].body}\n            resolving={phase === \"reply2\"}\n          />\n        ) : null}\n      </div>\n\n      {/* composer */}\n      <div className=\"mt-auto shrink-0 p-1.5\">\n        <div\n          role=\"presentation\"\n          onClick={() => inputRef.current?.focus()}\n          className=\"flex cursor-text flex-col gap-2 rounded-control border border-line bg-field p-2.5 shadow-[0_1px_2px_rgba(0,0,0,0.035)] transition-[border-color,box-shadow] duration-150 focus-within:border-line-strong focus-within:shadow-[0_1px_2px_rgba(0,0,0,0.025)]\"\n        >\n          <input\n            ref={inputRef}\n            value={draft}\n            onChange={(event) => setDraft(event.target.value)}\n            onKeyDown={(event) => {\n              if (event.key === \"Enter\") send();\n            }}\n            placeholder={l.placeholder}\n            aria-label=\"Chat prompt\"\n            className=\"min-h-4.5 bg-transparent text-[13px] leading-[1.4] text-ink outline-none placeholder:text-ink-3\"\n          />\n          <div className=\"flex items-center justify-end\">\n            <button\n              type=\"button\"\n              aria-label=\"Send\"\n              disabled={!canSend}\n              onClick={send}\n              className=\"flex size-7 items-center justify-center rounded-[8px]\n                transition-[background-color,color,transform] duration-200 enabled:active:scale-[0.96]\"\n              style={{\n                background: canSend ? \"var(--ink)\" : \"var(--line-strong)\",\n                color: canSend ? \"var(--surface)\" : \"var(--ink-2)\",\n              }}\n            >\n              <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n                <path d=\"M12 19V5M5 12l7-7 7 7\" />\n              </svg>\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-code-block",
      "type": "registry:block",
      "title": "Beautiful Original Code Block",
      "description": "Original Beautiful UI CodeBlock",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/CodeBlock.tsx",
          "target": "@components/beautiful-ui/original/primitives/CodeBlock.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useCallback, useState, type ReactNode } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * CODE BLOCK\n * A light editor panel with two versions (switch in the card):\n *   · Code — a line-numbered listing\n *   · Diff — a unified diff: old/new gutters, a green/red accent\n *     bar and row tint, plus word-level add/del highlights.\n * Both share syntax coloring, insets, and wrapping behavior.\n * ───────────────────────────────────────────────────────── */\n\nconst FILE = \"churn.ts\";\n\nconst CODE_LINES = [\n  \"export async function churnBatch() {\",\n  '  const flavor = await getFlavor(\"pistachio\");',\n  \"  const base = await dairy.fetch({ flavor });\",\n  '  await freezer.store(base, { temp: \"-16C\" });',\n  \"  if (!base.approved) return null;\",\n  \"  return base.gallons;\",\n  \"}\",\n];\n\n/* A single run of code within a diff row; `change` tints it as an add/del. */\nexport type CodePiece = { text: string; change?: \"add\" | \"del\" };\n/* One row of a unified diff: old/new line numbers, its kind, and its pieces. */\nexport type DiffRow = {\n  old: number | null;\n  cur: number | null;\n  type: \"ctx\" | \"add\" | \"del\";\n  pieces: CodePiece[];\n};\n/* Prominent copy strings on the code block. */\nexport type CodeBlockLabels = { copy: string; copied: string };\n\n// Back-compat internal aliases for the local component signatures.\ntype Piece = CodePiece;\ntype Row = DiffRow;\n\nconst DIFF: Row[] = [\n  { old: 1, cur: 1, type: \"ctx\", pieces: [{ text: \"export async function churnBatch() {\" }] },\n  { old: 2, cur: 2, type: \"ctx\", pieces: [{ text: '  const flavor = await getFlavor(\"pistachio\");' }] },\n  { old: 3, cur: 3, type: \"ctx\", pieces: [{ text: \"  const base = await dairy.fetch({ flavor });\" }] },\n  { old: 4, cur: null, type: \"del\", pieces: [{ text: \"  await freezer.store(base, { temp: \" }, { text: '\"-14C\"', change: \"del\" }, { text: \" });\" }] },\n  { old: null, cur: 4, type: \"add\", pieces: [{ text: \"  await freezer.store(base, { temp: \" }, { text: '\"-16C\"', change: \"add\" }, { text: \" });\" }] },\n  { old: null, cur: 5, type: \"add\", pieces: [{ text: \"  if (!base.approved) return null;\" }] },\n  { old: 5, cur: 6, type: \"ctx\", pieces: [{ text: \"  return base.gallons;\" }] },\n  { old: 6, cur: 7, type: \"ctx\", pieces: [{ text: \"}\" }] },\n];\n\nconst HATCH = \"repeating-linear-gradient(45deg, var(--red) 0, var(--red) 1.5px, transparent 1.5px, transparent 3px)\";\n\n/* light syntax coloring — keywords/imports/conditionals, functions, strings & numbers */\nconst KEYWORDS = new Set([\"import\", \"from\", \"export\", \"default\", \"async\", \"function\", \"const\", \"let\", \"var\", \"await\", \"return\", \"if\", \"else\", \"for\", \"while\", \"new\", \"throw\", \"try\", \"catch\", \"null\", \"true\", \"false\", \"undefined\"]);\nconst TOKEN = /(\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`[^`]*`|\\b\\d+(?:\\.\\d+)?\\b|\\b(?:import|from|export|default|async|function|const|let|var|await|return|if|else|for|while|new|throw|try|catch|null|true|false|undefined)\\b|[A-Za-z_$][\\w$]*(?=\\s*\\())/g;\n\nfunction highlight(text: string): ReactNode[] {\n  const nodes: ReactNode[] = [];\n  let last = 0;\n  let k = 0;\n  for (const m of text.matchAll(TOKEN)) {\n    const idx = m.index ?? 0;\n    const t = m[0];\n    if (idx > last) nodes.push(<span key={k++}>{text.slice(last, idx)}</span>);\n    let color: string;\n    let weight: number | undefined;\n    if (/^[\"'`]/.test(t) || /^\\d/.test(t)) color = \"var(--orange)\"; // string / number\n    else if (KEYWORDS.has(t)) color = \"var(--accent-ink)\"; // keyword / import / conditional\n    else { color = \"var(--ink)\"; weight = 500; } // function call\n    nodes.push(<span key={k++} style={{ color, fontWeight: weight }}>{t}</span>);\n    last = idx + t.length;\n  }\n  if (last < text.length) nodes.push(<span key={k++}>{text.slice(last)}</span>);\n  return nodes;\n}\n\nfunction Pieces({ pieces }: { pieces: Piece[] }) {\n  return (\n    <>\n      {pieces.map((p, i) => {\n        if (p.change) {\n          const add = p.change === \"add\";\n          return (\n            <span\n              key={i}\n              className=\"rounded-[3px]\"\n              style={{\n                background: `color-mix(in srgb, var(--${add ? \"green\" : \"red\"}) 18%, transparent)`,\n                padding: \"0 2px\",\n                margin: \"0 -1px\",\n                boxDecorationBreak: \"clone\",\n                WebkitBoxDecorationBreak: \"clone\",\n              }}\n            >\n              {highlight(p.text)}\n            </span>\n          );\n        }\n        return <span key={i}>{highlight(p.text)}</span>;\n      })}\n    </>\n  );\n}\n\nfunction FileIcon() {\n  return (\n    <svg aria-hidden width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"shrink-0 text-ink-3\">\n      <path d=\"M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5\" />\n    </svg>\n  );\n}\n\nconst DEFAULT_LABELS: CodeBlockLabels = { copy: \"Copy\", copied: \"Copied\" };\n\nexport type CodeBlockProps = {\n  /** Which view to render — \"Code\" (line-numbered listing) or \"Diff\". */\n  variant?: string;\n  /** The lines shown in the Code view. */\n  lines?: string[];\n  /** Raw text placed on the clipboard by Copy. Defaults to `lines` joined. */\n  code?: string;\n  /** The unified-diff rows shown in the Diff view. */\n  diff?: DiffRow[];\n  /** Filename shown in the header. */\n  filename?: string;\n  /** Prominent copy strings. */\n  labels?: Partial<CodeBlockLabels>;\n  /** Called with the copied text after a successful copy. */\n  onCopy?: (text: string) => void;\n};\n\nexport default function CodeBlock({\n  variant = \"Code\",\n  lines = CODE_LINES,\n  code,\n  diff = DIFF,\n  filename = FILE,\n  labels,\n  onCopy,\n}: CodeBlockProps) {\n  const [copied, setCopied] = useState(false);\n  const isDiff = variant === \"Diff\";\n  const text = { ...DEFAULT_LABELS, ...labels };\n  const raw = code ?? lines.join(\"\\n\");\n\n  const copy = useCallback(() => {\n    navigator.clipboard.writeText(raw).then(() => {\n      setCopied(true);\n      onCopy?.(raw);\n      setTimeout(() => setCopied(false), 1500);\n    });\n  }, [raw, onCopy]);\n\n  const added = diff.filter((r) => r.type === \"add\").length;\n  const removed = diff.filter((r) => r.type === \"del\").length;\n\n  return (\n    <div className=\"w-full max-w-105 overflow-hidden rounded-card bg-surface shadow-card\">\n      {/* header — file · (diff stat | copy) */}\n      <div className=\"flex h-11 items-center gap-2 border-b border-line px-4 text-[12.5px]\">\n        <span className=\"inline-flex min-w-0 items-center gap-[7px]\">\n          <FileIcon />\n          <span className=\"truncate font-mono leading-none text-ink\">{filename}</span>\n        </span>\n\n        {isDiff ? (\n          <span className=\"ml-auto inline-flex items-center gap-2 font-mono text-[12px] leading-none tabular-nums\">\n            <span className=\"text-green\">+{added}</span>\n            <span className=\"text-red\">-{removed}</span>\n          </span>\n        ) : (\n          <button\n            type=\"button\"\n            aria-label=\"Copy code\"\n            onClick={copy}\n            className={`-mr-1 ml-auto flex h-6 items-center gap-1 rounded-[6px] px-1.5 text-[12px]\n              font-medium transition-colors duration-100 hover:bg-hover\n              ${copied ? \"text-green\" : \"text-ink-3 hover:text-ink\"}`}\n          >\n            {copied ? (\n              <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M20 6L9 17l-5-5\" /></svg>\n            ) : (\n              <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"12\" height=\"12\" rx=\"2.5\" /><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" /></svg>\n            )}\n            {copied ? text.copied : text.copy}\n          </button>\n        )}\n      </div>\n\n      {/* body — equal 12px inset on top / left / right; lines wrap */}\n      <div className=\"py-3 font-mono text-[12.5px] leading-[1.65] text-ink-2\">\n        {isDiff ? (\n          <div className=\"relative\">\n            <span className=\"pointer-events-none absolute inset-y-0 left-5 w-px bg-line\" />\n            {diff.map((r, i) => {\n              const add = r.type === \"add\";\n              const del = r.type === \"del\";\n              // one gutter column: removals keep the old number, additions/context show the new one\n              const num = del ? r.old : r.cur;\n              return (\n                <div\n                  key={i}\n                  className={`relative grid grid-cols-[20px_minmax(0,1fr)] items-start\n                    ${add ? \"bg-green-tint\" : del ? \"bg-red-tint\" : \"\"}`}\n                >\n                  {(add || del) && (\n                    <span className=\"absolute inset-y-0 left-0 w-[3px]\" style={{ background: add ? \"var(--green)\" : HATCH }} />\n                  )}\n                  <span className={`select-none text-center text-[11px] ${add ? \"text-green\" : del ? \"text-red\" : \"text-ink-3\"}`}>{num ?? \"\"}</span>\n                  <code className=\"pr-3 pl-1 break-words whitespace-pre-wrap\">\n                    <Pieces pieces={r.pieces} />\n                  </code>\n                </div>\n              );\n            })}\n          </div>\n        ) : (\n          <div className=\"relative\">\n            <span className=\"pointer-events-none absolute inset-y-0 left-5 w-px bg-line\" />\n            {lines.map((line, i) => (\n              <div key={i} className=\"grid grid-cols-[20px_minmax(0,1fr)] items-start\">\n                <span className=\"select-none text-center text-[11px] text-ink-3\">{i + 1}</span>\n                <code className=\"pr-3 pl-1 break-words whitespace-pre-wrap\">{highlight(line)}</code>\n              </div>\n            ))}\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-context-cards",
      "type": "registry:block",
      "title": "Beautiful Original Context Cards",
      "description": "Original Beautiful UI ContextCards",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/ContextCards.tsx",
          "target": "@components/beautiful-ui/original/primitives/ContextCards.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * CONTEXT CARDS\n * Retrieved chunks enter once, then remain available.\n * ───────────────────────────────────────────────────────── */\n\nexport type ContextChunk = {\n  title: string;\n  chars: string;\n  body: string;\n  source: string;\n  badge: string;\n  tone: string;\n};\n\nexport type ContextCardsLabels = {\n  header: string;\n  count: string;\n};\n\nconst DEFAULT_LABELS: ContextCardsLabels = {\n  header: \"All chunks\",\n  count: \"32\",\n};\n\nconst CHUNKS: ContextChunk[] = [\n  {\n    title: \"Vendor onboarding rule\",\n    chars: \"290 characters\",\n    body: \"Cold-chain certification must be verified before a new dairy can be added to the reorder workflow.\",\n    source: \"Dairy Onboarding SOP.pdf\",\n    badge: \"PDF\",\n    tone: \"bg-red\",\n  },\n  {\n    title: \"Seasonal demand row\",\n    chars: \"1,250 characters\",\n    body: \"Q4 velocity table: pistachio +18%, vanilla +6%, rocky road -11%; retire flavors below 40 scoops weekly.\",\n    source: \"Sales Velocity Export.csv\",\n    badge: \"CSV\",\n    tone: \"bg-green\",\n  },\n];\n\nexport default function ContextCards({\n  chunks = CHUNKS,\n  labels,\n  className,\n}: {\n  /** Accepted for gallery/registry parity; ContextCards has no visual variants. */\n  variant?: string;\n  chunks?: ContextChunk[];\n  labels?: Partial<ContextCardsLabels>;\n  className?: string;\n} = {}) {\n  const [chipsShown, setChipsShown] = useState(false);\n  const copy = { ...DEFAULT_LABELS, ...labels };\n\n  useEffect(() => {\n    const chips = setTimeout(() => setChipsShown(true), 700);\n    return () => clearTimeout(chips);\n  }, []);\n\n  return (\n    <div className={`flex w-full max-w-95 flex-col gap-2${className ? ` ${className}` : \"\"}`}>\n      <div\n        className=\"flex items-center gap-2 px-0.5\"\n        style={{ animation: \"beautiful-fade-in 400ms ease-out both\" }}\n      >\n        <span className=\"text-[13px] font-semibold text-ink\">{copy.header}</span>\n        <span className=\"inline-flex h-5 items-center rounded-md bg-inset px-1.5 text-[11.5px] font-medium text-ink-2 shadow-hairline tabular-nums\">\n          {copy.count}\n        </span>\n      </div>\n\n      {chunks.map((chunk, i) => (\n        <div\n          key={chunk.title}\n          className=\"overflow-hidden rounded-card bg-surface shadow-card\"\n          style={{\n            animation: `beautiful-fade-up 400ms cubic-bezier(0.23,1,0.32,1) ${i * 100}ms both`,\n          }}\n        >\n          <div className=\"primitive-card-bar flex items-center gap-2.5 border-b border-line\">\n            <span className=\"flex min-w-0 items-center gap-1.5 text-[13px] font-medium text-ink\">\n              <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\"><path d=\"M4 6h16M4 12h16M4 18h10\" /></svg>\n              <span className=\"truncate\">{chunk.title}</span>\n            </span>\n            <span className=\"ml-auto shrink-0 text-[12px] text-ink-3 tabular-nums\">{chunk.chars}</span>\n          </div>\n          <p className=\"px-3 pt-2 pb-1 text-[12.5px] leading-relaxed text-ink-2\">\n            {chunk.body}\n          </p>\n          <div className=\"px-3 pb-3\">\n            <span\n              className=\"inline-flex h-6 items-center gap-1.5 rounded-full bg-inset px-2\n                text-[12px] font-medium text-ink-2 shadow-btn\n                transition-[opacity,transform,background-color] duration-300 hover:bg-hover\"\n              style={{\n                opacity: chipsShown ? 1 : 0,\n                transform: chipsShown ? \"scale(1)\" : \"scale(0.95)\",\n                transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n                transitionDelay: `${i * 80}ms`,\n              }}\n            >\n              <span className={`flex size-3.5 items-center justify-center rounded-[4px] ${chunk.tone} text-[7px] font-bold text-white`}>\n                {chunk.badge}\n              </span>\n              {chunk.source}\n              <svg width=\"9\" height=\"9\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M7 17L17 7M7 7h10v10\" /></svg>\n            </span>\n          </div>\n        </div>\n      ))}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-diff-table",
      "type": "registry:block",
      "title": "Beautiful Original Diff Table",
      "description": "Original Beautiful UI DiffTable",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/DiffTable.tsx",
          "target": "@components/beautiful-ui/original/primitives/DiffTable.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"../atoms/Button\";\n\n/* ─────────────────────────────────────────────────────────\n * DIFF TABLE\n * The proposed edit plays once and rests on the completed\n * diff. Each changed row is the control: click it to include\n * or exclude that specific addition/removal before applying.\n * ───────────────────────────────────────────────────────── */\n\nfunction useStage(steps: number[]) {\n  const [stage, setStage] = useState(0);\n  useEffect(() => {\n    if (stage >= steps.length) return;\n    const t = setTimeout(() => setStage((s) => s + 1), steps[stage]);\n    return () => clearTimeout(t);\n  }, [stage, steps]);\n  return stage;\n}\n\nconst STAGE_DELAYS = [180, 260];\n\nexport type DiffRow = {\n  key: string;\n  id: string;\n  dept: string;\n  email: string;\n  removed: boolean;\n};\n\nconst ROWS: DiffRow[] = [\n  { key: \"rocky\", id: \"Rocky Road\", dept: \"Classic\", email: \"aurora-scoops\", removed: true },\n  { key: \"bubblegum\", id: \"Bubblegum\", dept: \"Retro\", email: \"kumo-creamery\", removed: true },\n  { key: \"mint\", id: \"Mint Chip\", dept: \"Classic\", email: \"maple-orbit\", removed: false },\n];\n\nconst DOT: Record<string, string> = {\n  Classic: \"bg-accent\",\n  Retro: \"bg-ink-3\",\n  Seasonal: \"bg-orange\",\n  Enterprise: \"bg-accent\",\n  \"Mid-market\": \"bg-orange\",\n};\n\nfunction IncludedMark({ included, tone }: { included: boolean; tone: \"red\" | \"green\" }) {\n  return (\n    <span\n      aria-hidden\n      className={`flex size-4.5 shrink-0 items-center justify-center rounded-[5px] transition-[background-color,color,transform] duration-150 ${\n        included\n          ? tone === \"red\" ? \"bg-red text-white\" : \"bg-green text-white\"\n          : \"bg-inset text-ink-3 shadow-hairline\"\n      }`}\n      style={{ transform: included ? \"scale(1)\" : \"scale(0.92)\" }}\n    >\n      {included ? (\n        <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M20 6L9 17l-5-5\" /></svg>\n      ) : null}\n    </span>\n  );\n}\n\nexport default function DiffTable({\n  rows = ROWS,\n}: {\n  rows?: DiffRow[];\n  variant?: string;\n} = {}) {\n  const stage = useStage(STAGE_DELAYS);\n  // 0 plain · 1 removals · 2 completed diff\n  const tinted = stage >= 1;\n  const settled = stage >= 2;\n  const [accepted, setAccepted] = useState(false);\n  const [edits, setEdits] = useState<Record<string, boolean>>(() => Object.fromEntries(rows.map((row) => [row.key, true])));\n\n  const addedRow = rows.find((row) => !row.removed);\n  const removals = rows.filter((row) => row.removed && edits[row.key]).length;\n  const additions = addedRow && edits[addedRow.key] ? 1 : 0;\n  const showAdded = settled;\n\n  const toggleEdit = (key: string) => setEdits((current) => ({ ...current, [key]: !current[key] }));\n\n  return (\n    <div className=\"w-full max-w-95\">\n      <div className=\"relative overflow-hidden rounded-card bg-surface shadow-card\">\n        <div className=\"primitive-card-bar flex items-center justify-between border-b border-line\">\n          <span className=\"text-[12.5px] font-medium text-ink\">Proposed account update</span>\n          {settled && !accepted && <span className=\"text-[11px] text-ink-3\">Click changed rows to toggle</span>}\n        </div>\n\n        <table className=\"w-full table-fixed border-collapse text-left\">\n          <colgroup>\n            <col className=\"w-[34%]\" />\n            <col className=\"w-[30%]\" />\n            <col className=\"w-[36%]\" />\n          </colgroup>\n          <thead>\n            <tr className=\"border-b border-line\">\n              {[\"Account\", \"Segment\", \"Owner\"].map((h) => (\n                <th key={h} className=\"primitive-table-cell text-[12px] font-medium text-ink-3\">\n                  {h}\n                </th>\n              ))}\n            </tr>\n          </thead>\n          <tbody>\n            {rows.map((row) => {\n              const out = row.removed && tinted && edits[row.key];\n              const interactive = row.removed && settled && !accepted;\n              return (\n                <tr\n                  key={row.key}\n                  tabIndex={interactive ? 0 : undefined}\n                  aria-selected={row.removed ? edits[row.key] : undefined}\n                  onClick={interactive ? () => toggleEdit(row.key) : undefined}\n                  onKeyDown={interactive ? (event) => {\n                    if (event.key === \"Enter\" || event.key === \" \") {\n                      event.preventDefault();\n                      toggleEdit(row.key);\n                    }\n                  } : undefined}\n                  className={`border-b border-line transition-[background-color,filter,opacity] duration-150 last:border-0 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-accent ${\n                    interactive ? \"cursor-pointer hover:brightness-[0.985]\" : \"\"\n                  }`}\n                  style={{ background: out ? \"var(--red-tint)\" : undefined }}\n                >\n                  <td\n                    className=\"primitive-table-cell text-[13px] font-medium tabular-nums transition-colors duration-200\"\n                    style={{ color: out ? \"var(--red)\" : \"var(--ink)\" }}\n                  >\n                    {row.id}\n                  </td>\n                  <td className=\"primitive-table-cell\">\n                    <span\n                      className=\"inline-flex h-5.5 items-center gap-1.5 rounded-full bg-inset px-2 text-[11.5px] font-medium shadow-hairline transition-opacity duration-200\"\n                      style={{ opacity: out ? 0.55 : 1 }}\n                    >\n                      <span className={`size-1.5 rounded-full ${DOT[row.dept]}`} />\n                      <span className=\"text-ink-2\">{row.dept}</span>\n                    </span>\n                  </td>\n                  <td\n                    className=\"primitive-table-cell text-[12.5px] whitespace-nowrap transition-colors duration-200\"\n                    style={{\n                      color: out ? \"var(--red)\" : \"var(--ink-2)\",\n                      textDecorationLine: out ? \"line-through\" : \"none\",\n                      textDecorationColor: \"color-mix(in srgb, var(--red) 50%, transparent)\",\n                    }}\n                  >\n                    <span className=\"flex items-center justify-between gap-2\">\n                      <span className=\"min-w-0 truncate\">{row.email}</span>\n                      {row.removed && settled && <IncludedMark included={edits[row.key]} tone=\"red\" />}\n                    </span>\n                  </td>\n                </tr>\n              );\n            })}\n            {/* added row */}\n            <tr>\n              <td colSpan={3} className=\"p-0\">\n                <div\n                  className=\"grid transition-[grid-template-rows,opacity] duration-200\"\n                  style={{\n                    gridTemplateRows: showAdded ? \"1fr\" : \"0fr\",\n                    opacity: showAdded ? 1 : 0,\n                    transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n                  }}\n                >\n                  <div className=\"overflow-hidden\">\n                    <div\n                      role=\"checkbox\"\n                      tabIndex={accepted ? -1 : 0}\n                      aria-checked={Boolean(addedRow && edits[addedRow.key])}\n                      aria-label={`Include adding ${addedRow?.id ?? \"account\"}`}\n                      onClick={accepted || !addedRow ? undefined : () => toggleEdit(addedRow.key)}\n                      onKeyDown={accepted ? undefined : (event) => {\n                        if (event.key === \"Enter\" || event.key === \" \") {\n                          event.preventDefault();\n                          if (addedRow) toggleEdit(addedRow.key);\n                        }\n                      }}\n                      className={`grid grid-cols-[34%_30%_36%] items-center border-t border-line transition-[background-color,filter,opacity] duration-150 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-accent ${\n                        accepted ? \"\" : \"cursor-pointer hover:brightness-[0.985]\"\n                      }`}\n                      style={{ background: addedRow && edits[addedRow.key] ? \"var(--green-tint)\" : undefined }}\n                    >\n                      <span className=\"primitive-table-cell text-[13px] font-medium tabular-nums transition-colors duration-200\" style={{ color: addedRow && edits[addedRow.key] ? \"var(--green)\" : \"var(--ink-3)\" }}>\n                        {addedRow?.id ?? \"—\"}\n                      </span>\n                      <span className=\"primitive-table-cell\">\n                        <span className=\"inline-flex h-5.5 items-center gap-1.5 rounded-full bg-surface px-2 text-[11.5px] font-medium shadow-hairline\">\n                          <span className=\"size-1.5 rounded-full bg-green\" />\n                          <span className=\"text-ink-2\">{addedRow?.dept ?? \"—\"}</span>\n                        </span>\n                      </span>\n                      <span className=\"primitive-table-cell text-[13px] transition-colors duration-200\" style={{ color: addedRow && edits[addedRow.key] ? \"var(--green)\" : \"var(--ink-3)\" }}>\n                        <span className=\"flex items-center justify-between gap-2\">\n                          <span className=\"min-w-0 truncate\">{addedRow?.email ?? \"—\"}</span>\n                          <IncludedMark included={Boolean(addedRow && edits[addedRow.key])} tone=\"green\" />\n                        </span>\n                      </span>\n                    </div>\n                  </div>\n                </div>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n\n        {/* footer — the summary follows the row-level selection */}\n        {settled && (\n          <div\n            className=\"primitive-card-footer flex min-h-11 items-center justify-between border-t border-line\"\n            style={{ animation: \"beautiful-fade-up 180ms cubic-bezier(0.23,1,0.32,1) both\" }}\n          >\n            {accepted ? (\n              <span\n                className=\"inline-flex items-center gap-1.5 rounded-full bg-green-tint py-1 pr-2.5 pl-1 text-[12.5px] font-medium text-green\"\n                style={{ animation: \"beautiful-pop-in 180ms cubic-bezier(0.23,1,0.32,1) both\" }}\n              >\n                <span className=\"flex size-4.5 items-center justify-center rounded-full bg-green text-white\">\n                  <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M20 6L9 17l-5-5\" /></svg>\n                </span>\n                {removals + additions} {removals + additions === 1 ? \"edit\" : \"edits\"} applied\n              </span>\n            ) : (\n              <>\n                <span className=\"text-[11.5px] tabular-nums text-ink-3\">\n                  {removals} {removals === 1 ? \"removal\" : \"removals\"} · {additions} {additions === 1 ? \"addition\" : \"additions\"}\n                </span>\n                <span className=\"flex items-center gap-1.5\">\n                  <Button\n                    variant=\"accent\"\n                    size=\"sm\"\n                    disabled={removals + additions === 0}\n                    onClick={() => {\n                      setAccepted(true);\n                    }}\n                    className=\"text-[12px]\"\n                  >\n                    Apply {removals + additions} {removals + additions === 1 ? \"change\" : \"changes\"}\n                  </Button>\n                </span>\n              </>\n            )}\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/Button.tsx",
          "target": "@components/beautiful-ui/original/atoms/Button.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { ButtonHTMLAttributes } from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../utils\";\n\nconst filledShadow = \"shadow-[inset_0_1px_0_rgba(255,255,255,0.14)]\";\n\n/* Pill-shaped by default — the app's core button style. Explicit symmetric\n * padding (not a fixed height) so the top/bottom spacing is always equal. */\nexport const buttonVariants = cva(\n  `inline-flex items-center justify-center font-medium select-none\n   transition-[transform,background-color,opacity] duration-150 ease-out\n   active:scale-[0.96] disabled:opacity-50 disabled:pointer-events-none`,\n  {\n    variants: {\n      variant: {\n        primary: `bg-ink text-canvas hover:opacity-90 dark:bg-ink dark:text-canvas ${filledShadow}`,\n        secondary: \"bg-surface text-ink shadow-btn hover:bg-inset aria-expanded:bg-hover\",\n        ghost: \"bg-hover-2 text-ink hover:bg-line-strong\",\n        accent: `bg-accent text-white hover:bg-accent-ink ${filledShadow}`,\n        success: `bg-green text-white hover:brightness-95 ${filledShadow}`,\n        /* transparent until hovered — for dense toolbars/action rows */\n        quiet: \"text-ink hover:bg-hover\",\n      },\n      size: {\n        /* compact toolbar pill — fixed height, lighter weight */\n        xs: \"h-7 rounded-full px-2.5 text-[12px] font-normal leading-none gap-1\",\n        /* canonical action pill — 27px tall, roomy sides */\n        sm: \"h-[27px] px-3 text-[13px] leading-none rounded-full gap-1.5\",\n        md: \"px-4 py-[9px] text-sm leading-none rounded-full gap-2\",\n      },\n    },\n    defaultVariants: { variant: \"secondary\", size: \"md\" },\n  },\n);\n\nexport type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>[\"variant\"]>;\n\nexport function Button({\n  variant,\n  size,\n  className,\n  ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>) {\n  return <button className={cn(buttonVariants({ variant, size }), className)} {...props} />;\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/utils.ts",
          "target": "@components/beautiful-ui/original/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Merge class names, letting later Tailwind classes win over conflicting earlier ones. */\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-filter-table",
      "type": "registry:block",
      "title": "Beautiful Original Filter Table",
      "description": "Original Beautiful UI FilterTable",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/FilterTable.tsx",
          "target": "@components/beautiful-ui/original/primitives/FilterTable.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * FILTER TABLE\n * Status chips directly filter the task table.\n * ───────────────────────────────────────────────────────── */\n\ntype Status = \"todo\" | \"progress\" | \"done\";\n\nexport type TableRow = { task: string; date: string; status: Status; owner: string };\n\nexport type FilterTableLabels = {\n  columns: { task: string; date: string; status: string; owner: string };\n};\n\nconst FILTERS: { key: \"all\" | Status; label: string; dot?: string; count: number }[] = [\n  { key: \"all\", label: \"All\", count: 5 },\n  { key: \"todo\", label: \"To do\", dot: \"#f09a2f\", count: 2 },\n  { key: \"progress\", label: \"In Progress\", dot: \"#16a6c7\", count: 2 },\n  { key: \"done\", label: \"Completed\", dot: \"#25a878\", count: 1 },\n];\n\nconst ROWS: TableRow[] = [\n  { task: \"Restock mango sorbet\", date: \"Dec 03\", status: \"todo\", owner: \"Mango Moon Gelato\" },\n  { task: \"Churn black sesame\", date: \"Sep 22\", status: \"progress\", owner: \"Kumo Creamery\" },\n  { task: \"Print summer menu\", date: \"Jan 02\", status: \"todo\", owner: \"Coral Coast Sorbet\" },\n  { task: \"Taste-test batch 42\", date: \"Nov 08\", status: \"progress\", owner: \"Maple Orbit\" },\n  { task: \"Order waffle cones\", date: \"Apr 14\", status: \"done\", owner: \"Aurora Scoops\" },\n];\n\nconst LABELS: FilterTableLabels = {\n  columns: { task: \"Task name\", date: \"Date\", status: \"Status\", owner: \"Advisor\" },\n};\n\nconst PILLS: Record<Status, { label: string; cls: string }> = {\n  todo: { label: \"To do\", cls: \"filter-status-todo\" },\n  progress: { label: \"In Progress\", cls: \"filter-status-progress\" },\n  done: { label: \"Completed\", cls: \"filter-status-done\" },\n};\n\nexport default function FilterTable({\n  rows = ROWS,\n  labels = LABELS,\n}: {\n  rows?: TableRow[];\n  labels?: FilterTableLabels;\n  variant?: string;\n} = {}) {\n  const [filter, setFilter] = useState<\"all\" | Status>(\"all\");\n\n  return (\n    <div className=\"w-full max-w-105\">\n      {/* filter chips */}\n      <div\n        className=\"-mx-1 mb-1 flex items-center gap-1 overflow-x-auto px-1 py-1\"\n        style={{ scrollbarWidth: \"none\" }}\n      >\n        {FILTERS.map((f) => {\n          const active = filter === f.key;\n          return (\n            <button\n              key={f.key}\n              type=\"button\"\n              aria-pressed={active}\n              onClick={() => setFilter(f.key)}\n              className={`flex h-6.5 shrink-0 items-center gap-1.5 rounded-full px-2.5 text-[12px]\n                font-medium transition-[background-color,box-shadow,color] duration-200\n                ${active ? \"bg-surface text-ink shadow-btn\" : \"text-ink-2 hover:bg-hover\"}`}\n            >\n              {f.dot && <span className=\"size-1.5 rounded-full\" style={{ background: f.dot }} />}\n              {f.label}\n              <span\n                className={`rounded-[4px] px-1 text-[10.5px] tabular-nums\n                  ${active ? \"bg-field text-ink-2\" : \"text-ink-3\"}`}\n              >\n                {f.count}\n              </span>\n            </button>\n          );\n        })}\n      </div>\n\n      {/* table */}\n      <div\n        aria-label=\"Scrollable task table\"\n        className=\"overflow-x-auto rounded-card bg-surface shadow-card\"\n        role=\"region\"\n        tabIndex={0}\n        style={{ scrollbarWidth: \"none\" }}\n      >\n        <div className=\"min-w-[420px]\">\n          <div className=\"grid grid-cols-[minmax(0,1.3fr)_minmax(0,0.6fr)_minmax(0,0.95fr)_minmax(0,0.9fr)] border-b border-[var(--grid-line)] text-[12.5px] font-medium text-ink-2\">\n            <span className=\"border-r border-[var(--grid-line)] px-3 py-2\">{labels.columns.task}</span>\n            <span className=\"border-r border-[var(--grid-line)] px-3 py-2\">{labels.columns.date}</span>\n            <span className=\"border-r border-[var(--grid-line)] px-3 py-2\">{labels.columns.status}</span>\n            <span className=\"px-3 py-2\">{labels.columns.owner}</span>\n          </div>\n          {rows.map((row) => {\n            const shown = filter === \"all\" || row.status === filter;\n            const pill = PILLS[row.status];\n            return (\n              <div\n                key={row.task}\n                className=\"grid transition-[grid-template-rows,opacity] duration-300\"\n                style={{\n                  gridTemplateRows: shown ? \"1fr\" : \"0fr\",\n                  opacity: shown ? 1 : 0,\n                  transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n                }}\n              >\n                <div className=\"overflow-hidden\">\n                  <div\n                    className=\"grid grid-cols-[minmax(0,1.3fr)_minmax(0,0.6fr)_minmax(0,0.95fr)_minmax(0,0.9fr)] border-b\n                      border-[var(--grid-line)] text-[13px] transition-colors duration-100 hover:bg-hover\"\n                  >\n                    <span className=\"flex min-w-0 items-center border-r border-[var(--grid-line)] px-3 py-2\">\n                      <span className=\"truncate font-medium text-ink\">{row.task}</span>\n                    </span>\n                    <span className=\"flex items-center whitespace-nowrap border-r border-[var(--grid-line)] px-3 py-2 text-ink-2 tabular-nums\">\n                      {row.date}\n                    </span>\n                    <span className=\"flex items-center border-r border-[var(--grid-line)] px-3 py-2\">\n                      <span\n                        className={`inline-flex h-[23px] shrink-0 items-center whitespace-nowrap rounded-[8px] border px-[7px]\n                          text-[13px] font-medium ${pill.cls}`}\n                      >\n                        {pill.label}\n                      </span>\n                    </span>\n                    <span className=\"flex min-w-0 items-center px-3 py-2 text-ink-2\">\n                      <span className=\"truncate\">{row.owner}</span>\n                    </span>\n                  </div>\n                </div>\n              </div>\n            );\n          })}\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-fine-tune-card",
      "type": "registry:block",
      "title": "Beautiful Original Fine Tune Card",
      "description": "Original Beautiful UI FineTuneCard",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/FineTuneCard.tsx",
          "target": "@components/beautiful-ui/original/primitives/FineTuneCard.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useRef, useState } from \"react\";\nimport GlideMenu from \"./GlideMenu\";\n\n/* ─────────────────────────────────────────────────────────\n * FINE-TUNE CARD — compact interactive inspector.\n * Number fields scrub: hover the label for an ↔ cursor and\n * drag to adjust, use ↑/↓ (⇧ for ×10), or type directly.\n * ───────────────────────────────────────────────────────── */\n\nfunction ScrubField({\n  label,\n  value,\n  onChange,\n  min,\n  max,\n  step = 1,\n  suffix = \"\",\n  active,\n}: {\n  label: string;\n  value: number;\n  onChange: (v: number) => void;\n  min: number;\n  max: number;\n  step?: number;\n  suffix?: string;\n  active?: boolean;\n}) {\n  const drag = useRef<{ x: number; v: number } | null>(null);\n  const clamp = (v: number) => Math.min(max, Math.max(min, Math.round(v)));\n\n  return (\n    <label\n      className=\"flex h-6.5 min-w-0 items-center gap-1 rounded-chip py-1 pr-1 pl-0.5\n        transition-[background-color,box-shadow] duration-200\"\n      style={{\n        background: active ? \"var(--accent-tint)\" : \"var(--field)\",\n        boxShadow: active ? \"0 0 0 1px var(--accent)\" : \"none\",\n      }}\n    >\n      {/* scrub handle */}\n      <span\n        role=\"slider\"\n        aria-label={label}\n        aria-valuenow={value}\n        aria-valuemin={min}\n        aria-valuemax={max}\n        tabIndex={0}\n        onPointerDown={(e) => {\n          (e.target as HTMLElement).setPointerCapture(e.pointerId);\n          drag.current = { x: e.clientX, v: value };\n        }}\n        onPointerMove={(e) => {\n          if (!drag.current) return;\n          onChange(clamp(drag.current.v + ((e.clientX - drag.current.x) / 2) * step));\n        }}\n        onPointerUp={() => (drag.current = null)}\n        onKeyDown={(e) => {\n          const mult = e.shiftKey ? 10 : 1;\n          if (e.key === \"ArrowUp\" || e.key === \"ArrowRight\") {\n            e.preventDefault();\n            onChange(clamp(value + step * mult));\n          } else if (e.key === \"ArrowDown\" || e.key === \"ArrowLeft\") {\n            e.preventDefault();\n            onChange(clamp(value - step * mult));\n          }\n        }}\n        className=\"flex h-full shrink-0 cursor-ew-resize touch-none items-center rounded-[4px]\n          px-0.5 text-[12px] text-ink-3 select-none hover:text-ink-2 focus-visible:text-accent-ink\n          focus-visible:outline-none\"\n      >\n        {label}\n      </span>\n      <input\n        inputMode=\"numeric\"\n        value={value}\n        onChange={(e) => {\n          const n = Number(e.target.value.replace(/[^\\d-]/g, \"\"));\n          if (!Number.isNaN(n)) onChange(clamp(n));\n        }}\n        aria-label={`${label} value`}\n        className=\"min-w-0 flex-1 bg-transparent text-[12px] text-ink tabular-nums outline-none\"\n      />\n      {suffix && <span className=\"shrink-0 pr-0.5 text-[11.5px] text-ink-3\">{suffix}</span>}\n    </label>\n  );\n}\n\nconst SEGMENTS = [\"row\", \"col\", \"grid\"] as const;\n\nfunction SegmentIcon({ kind }: { kind: string }) {\n  const dot = \"size-1.5 rounded-[2px] border-[1.2px] border-current\";\n  if (kind === \"row\")\n    return <span className=\"flex gap-0.5\">{[0, 1, 2].map((i) => <span key={i} className={dot} />)}</span>;\n  if (kind === \"col\")\n    return <span className=\"flex flex-col gap-0.5\">{[0, 1].map((i) => <span key={i} className={dot} />)}</span>;\n  return (\n    <span className=\"grid grid-cols-2 gap-0.5\">\n      {[0, 1, 2, 3].map((i) => <span key={i} className={dot} />)}\n    </span>\n  );\n}\n\n/* A single scrub-able number property. `value` is the initial/default value. */\nexport type FineTuneField = {\n  key: string;\n  label: string;\n  value: number;\n  min: number;\n  max: number;\n  step?: number;\n  suffix?: string;\n};\n/* Prominent copy strings on the card. */\nexport type FineTuneCardLabels = {\n  title: string;\n  layout: string;\n  type: string;\n  placeholder: string;\n  adjust: string;\n  edited: string;\n};\n/* The editable state emitted by `onChange`. */\nexport type FineTuneState = {\n  segment: number;\n  values: Record<string, number>;\n  type: string;\n};\n\nconst FIELDS: FineTuneField[] = [\n  { key: \"width\", label: \"W\", value: 324, min: 40, max: 999 },\n  { key: \"height\", label: \"H\", value: 96, min: 24, max: 999 },\n  { key: \"radius\", label: \"Radius\", value: 28, min: 0, max: 64 },\n  { key: \"opacity\", label: \"Opacity\", value: 100, min: 0, max: 100, suffix: \"%\" },\n];\n\nconst OPTIONS = [\"Seasonal\", \"Classic\", \"Limited\"];\n\nconst DEFAULT_LABELS: FineTuneCardLabels = {\n  title: \"Flavor card\",\n  layout: \"Layout\",\n  type: \"Type\",\n  placeholder: \"Select type\",\n  adjust: \"Adjust\",\n  edited: \"Edited\",\n};\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n  const rows: T[][] = [];\n  for (let i = 0; i < items.length; i += size) rows.push(items.slice(i, i + size));\n  return rows;\n}\n\nexport type FineTuneCardProps = {\n  /** Accepted for gallery/registry parity; not used by this card. */\n  variant?: string;\n  /** The scrub-able properties shown in the layout grid (rendered in pairs). */\n  fields?: FineTuneField[];\n  /** Options offered in the Type menu. */\n  options?: string[];\n  /** Prominent copy strings. */\n  labels?: Partial<FineTuneCardLabels>;\n  /** Called with the full editable state whenever the user edits it. */\n  onChange?: (state: FineTuneState) => void;\n};\n\nexport default function FineTuneCard({\n  fields = FIELDS,\n  options = OPTIONS,\n  labels,\n  onChange,\n}: FineTuneCardProps) {\n  const text = { ...DEFAULT_LABELS, ...labels };\n  const [seg, setSeg] = useState(0);\n  const [values, setValues] = useState<Record<string, number>>(() =>\n    Object.fromEntries(fields.map((f) => [f.key, f.value])),\n  );\n  const [menuOpen, setMenuOpen] = useState(false);\n  const [typeValue, setTypeValue] = useState(text.placeholder);\n\n  const selectSeg = (i: number) => {\n    setSeg(i);\n    onChange?.({ segment: i, values, type: typeValue });\n  };\n  const setValue = (key: string, v: number) => {\n    setValues((current) => {\n      const next = { ...current, [key]: v };\n      onChange?.({ segment: seg, values: next, type: typeValue });\n      return next;\n    });\n  };\n  const selectType = (value: string) => {\n    setTypeValue(value);\n    setMenuOpen(false);\n    onChange?.({ segment: seg, values, type: value });\n  };\n\n  const changed = fields.some((f) => values[f.key] !== f.value);\n  const done = seg !== 0 || changed || typeValue !== text.placeholder;\n\n  return (\n    <div className=\"relative w-full max-w-60 rounded-card bg-surface shadow-raised\">\n      {/* header */}\n      <div className=\"primitive-card-bar flex items-center justify-between border-b border-line\">\n        <span className=\"text-[13px] font-medium text-ink\">{text.title}</span>\n        {done ? (\n          <span\n            className=\"flex items-center gap-1.5 text-[12px] font-medium text-green\"\n            style={{ animation: \"beautiful-pop-in 250ms cubic-bezier(0.23,1,0.32,1) both\" }}\n          >\n            <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n              <path d=\"M20 6L9 17l-5-5\" />\n            </svg>\n            {text.edited}\n          </span>\n        ) : (\n          <span className=\"flex items-center gap-1.5\">\n            <span className=\"flex size-4.5 items-center justify-center rounded-[5px] border border-accent/30 bg-accent-tint\">\n              <svg width=\"9\" height=\"9\" viewBox=\"0 0 24 24\" fill=\"var(--accent)\">\n                <path d=\"M12 2l2.4 7.2L22 12l-7.6 2.8L12 22l-2.4-7.2L2 12l7.6-2.8z\" />\n              </svg>\n            </span>\n            <span\n              className=\"bg-clip-text text-[12px] font-medium text-transparent\"\n              style={{\n                backgroundImage:\n                  \"linear-gradient(90deg, var(--accent) 35%, var(--accent-ink) 50%, var(--accent) 65%)\",\n                backgroundSize: \"200% 100%\",\n                animation: \"beautiful-shimmer-text 1.4s linear infinite\",\n              }}\n            >\n              {text.adjust}\n            </span>\n          </span>\n        )}\n      </div>\n\n      {/* layout section */}\n      <div className=\"primitive-card-pad flex flex-col gap-2 border-b border-line\">\n        <p className=\"text-[12.5px] font-medium text-ink\">{text.layout}</p>\n        {/* segmented control: gray track, raised white thumb */}\n        <div className=\"relative grid grid-cols-3 rounded-control bg-field p-0.5\">\n          <span\n            aria-hidden\n            className=\"absolute inset-y-0.5 rounded-[6px] bg-surface shadow-btn transition-transform duration-300\"\n            style={{\n              width: \"calc((100% - 4px) / 3)\",\n              left: 2,\n              transform: `translateX(${seg * 100}%)`,\n              transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n            }}\n          />\n          {SEGMENTS.map((s, i) => (\n            <button\n              key={s}\n              type=\"button\"\n              aria-label={`${s} layout`}\n              aria-pressed={i === seg}\n              onClick={() => selectSeg(i)}\n              className={`relative z-10 flex h-6 items-center justify-center transition-colors duration-200\n                ${i === seg ? \"text-accent\" : \"text-ink-3\"}`}\n            >\n              <SegmentIcon kind={s} />\n            </button>\n          ))}\n        </div>\n        {chunk(fields, 2).map((pair, ri) => (\n          <div key={ri} className=\"grid min-w-0 grid-cols-2 gap-2\">\n            {pair.map((f) => (\n              <ScrubField\n                key={f.key}\n                label={f.label}\n                value={values[f.key]}\n                onChange={(v) => setValue(f.key, v)}\n                min={f.min}\n                max={f.max}\n                step={f.step}\n                suffix={f.suffix}\n                active={values[f.key] !== f.value}\n              />\n            ))}\n          </div>\n        ))}\n      </div>\n\n      {/* interaction section */}\n      <div className=\"primitive-card-footer flex items-center justify-between\">\n        <span className=\"text-[12px] text-ink-3\">{text.type}</span>\n        <div className=\"relative -mr-0.5 w-30\">\n          <button\n            type=\"button\"\n            aria-expanded={menuOpen}\n            onClick={() => setMenuOpen((current) => !current)}\n            className=\"flex h-6.5 w-full items-center justify-between rounded-chip bg-inset py-1 pr-1 pl-2\n              shadow-hairline transition-shadow duration-200 focus-visible:outline-none\"\n            style={{ boxShadow: menuOpen ? \"0 0 0 1px var(--accent)\" : undefined }}\n          >\n            <span className={`text-[12px] ${typeValue !== text.placeholder ? \"text-ink\" : \"text-ink-3\"}`}>\n              {typeValue}\n            </span>\n            <svg\n              width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--ink-3)\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"\n              className=\"transition-transform duration-200\"\n              style={{ transform: menuOpen ? \"rotate(180deg)\" : \"rotate(0)\" }}\n            >\n              <path d=\"M6 9l6 6 6-6\" />\n            </svg>\n          </button>\n\n          {menuOpen && (\n            <div\n              className=\"absolute right-0 bottom-8 z-10 w-30 rounded-[10px] bg-surface p-1 shadow-raised\"\n              style={{\n                animation: \"beautiful-pop-in 200ms cubic-bezier(0.23,1,0.32,1) both\",\n                transformOrigin: \"bottom right\",\n              }}\n            >\n              <GlideMenu className=\"flex flex-col gap-px\" highlightClassName=\"inset-x-0 rounded-[6px] bg-field\">\n                {options.map((item) => (\n                  <button\n                    key={item}\n                    data-menu-row\n                    type=\"button\"\n                    onClick={() => selectType(item)}\n                    className={`relative z-10 flex h-6.5 w-full items-center rounded-[6px] px-2 text-left text-[12.5px] text-ink ${\n                      item === typeValue ? \"bg-field group-hover/glide-menu:bg-transparent\" : \"\"\n                    }`}\n                  >\n                    {item}\n                  </button>\n                ))}\n              </GlideMenu>\n            </div>\n          )}\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "target": "@components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useRef, useState, type ReactNode } from \"react\";\n\ntype GlideMenuProps = {\n  children: ReactNode;\n  className?: string;\n  highlightClassName?: string;\n  rowSelector?: string;\n};\n\n/** A single hover layer that glides between interactive menu rows. */\nexport default function GlideMenu({\n  children,\n  className = \"\",\n  highlightClassName = \"inset-x-0 rounded-[8px] bg-hover\",\n  rowSelector = \"[data-menu-row]\",\n}: GlideMenuProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const [box, setBox] = useState<{ top: number; height: number } | null>(null);\n  const [visible, setVisible] = useState(false);\n\n  const moveTo = (target: EventTarget | null) => {\n    const container = ref.current;\n    if (!(target instanceof Element) || !container) return;\n    const row = target.closest(rowSelector);\n    if (!(row instanceof HTMLElement) || !container.contains(row)) return;\n    const containerRect = container.getBoundingClientRect();\n    const rowRect = row.getBoundingClientRect();\n    setBox({ top: rowRect.top - containerRect.top, height: rowRect.height });\n    setVisible(true);\n  };\n\n  return (\n    <div\n      ref={ref}\n      onMouseOver={(event) => moveTo(event.target)}\n      onMouseLeave={() => setVisible(false)}\n      onFocusCapture={(event) => moveTo(event.target)}\n      onBlurCapture={(event) => {\n        if (!ref.current?.contains(event.relatedTarget as Node | null)) setVisible(false);\n      }}\n      className={`group/glide-menu relative ${className}`}\n    >\n      <span\n        aria-hidden\n        className={`pointer-events-none absolute ${highlightClassName}`}\n        style={{\n          top: box?.top ?? 0,\n          height: box?.height ?? 0,\n          opacity: box && visible ? 1 : 0,\n          transition:\n            \"top 220ms cubic-bezier(0.23,1,0.32,1), height 220ms cubic-bezier(0.23,1,0.32,1), opacity 150ms ease\",\n        }}\n      />\n      {children}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-flowchart",
      "type": "registry:block",
      "title": "Beautiful Original Flowchart",
      "description": "Original Beautiful UI Flowchart",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/Flowchart.tsx",
          "target": "@components/beautiful-ui/original/primitives/Flowchart.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { useLayoutEffect } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * FLOWCHART — an agent workflow on a dotted editor canvas.\n * Two steps: a Trigger card and an If/Else condition card,\n * joined by a measured connector. Cards drag anywhere on\n * the canvas; the connector follows. Condition chips open\n * real dropdowns (same menu as the PromptBar model picker).\n * ───────────────────────────────────────────────────────── */\n\nconst PURPLE = \"#9a5cff\";\nconst AMBER = \"#f09a2f\";\n\nconst mix = (hue: string, pct: number, base = \"var(--surface)\") =>\n  `color-mix(in srgb, ${hue} ${pct}%, ${base})`;\n\n/* ── layout constants ── */\nconst PAD_Y = 24;\nconst ROW_GAP = 64;\nconst PILL_OFFSET = 30; // kind pill + gap above a card\n\nexport type StepNode = {\n  id: string;\n  row: number;\n  x: number; // 0–1 center of the node\n  w: number;\n  kind?: { label: string; hue: string };\n  hue?: string;\n  title?: string;\n  caption?: string;\n  condition?: boolean; // renders the if/else chip rows instead\n};\n\nconst NODES: StepNode[] = [\n  {\n    id: \"trigger\",\n    row: 0,\n    x: 0.5,\n    w: 300,\n    kind: { label: \"Trigger\", hue: PURPLE },\n    hue: PURPLE,\n    title: \"Renewal risk updated\",\n    caption: \"Trigger when an account crosses the review threshold\",\n  },\n  {\n    id: \"cond\",\n    row: 1,\n    x: 0.5,\n    w: 356,\n    kind: { label: \"If / Else\", hue: AMBER },\n    condition: true,\n  },\n];\n\nconst EDGES = [{ from: \"trigger\", to: \"cond\" }];\n\n/* estimated heights for the first paint; measured immediately after */\nconst EST_H: Record<string, number> = { trigger: 92, cond: 134 };\n\nconst PROPERTIES = [\"risk\", \"segment\", \"owner\", \"renewal date\"];\nconst FLAVORS = [\n  { name: \"High\", tag: \"Urgent\" },\n  { name: \"Medium\", tag: \"Review\" },\n  { name: \"Low\", tag: \"Stable\" },\n  { name: \"Unknown\", tag: \"Missing\" },\n];\nconst TOPPINGS = [\n  { name: \"Executive sponsor missing\" },\n  { name: \"Owner note is stale\" },\n  { name: \"Usage declined\" },\n  { name: \"Renewal date is near\" },\n];\n\n/* ── icons ── */\nfunction ConeIcon({ size = 16 }: { size?: number }) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <rect x=\"4\" y=\"4\" width=\"6\" height=\"6\" rx=\"1.5\" />\n      <rect x=\"14\" y=\"14\" width=\"6\" height=\"6\" rx=\"1.5\" />\n      <path d=\"M10 7h3a4 4 0 0 1 4 4v3\" />\n    </svg>\n  );\n}\n\nfunction Chevron() {\n  return (\n    <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"shrink-0 text-ink-3\">\n      <path d=\"m6 9 6 6 6-6\" />\n    </svg>\n  );\n}\n\nfunction Handle() {\n  return (\n    <svg width=\"10\" height=\"16\" viewBox=\"0 0 10 16\" className=\"shrink-0 cursor-grab text-ink-3/70\">\n      {[3, 8, 13].flatMap((y) => [\n        <circle key={`l${y}`} cx=\"3\" cy={y} r=\"1.1\" fill=\"currentColor\" />,\n        <circle key={`r${y}`} cx=\"7.5\" cy={y} r=\"1.1\" fill=\"currentColor\" />,\n      ])}\n    </svg>\n  );\n}\n\nfunction CheckIcon() {\n  return (\n    <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <path d=\"M20 6L9 17l-5-5\" />\n    </svg>\n  );\n}\n\n/* ── dropdown menu — same pattern as the PromptBar model picker ── */\nfunction Menu({\n  items,\n  value,\n  width,\n  align,\n  onPick,\n}: {\n  items: { name: string; tag?: string }[];\n  value: string;\n  width: string;\n  align: \"left\" | \"right\";\n  onPick: (name: string) => void;\n}) {\n  const [hovered, setHovered] = useState<number | null>(null);\n  const rowRefs = useRef<(HTMLButtonElement | null)[]>([]);\n  const [box, setBox] = useState<{ top: number; height: number } | null>(null);\n\n  const valueIndex = items.findIndex((item) => item.name === value);\n  useLayoutEffect(() => {\n    const row = rowRefs.current[hovered ?? valueIndex];\n    if (row) setBox({ top: row.offsetTop, height: row.offsetHeight });\n  }, [hovered, valueIndex]);\n\n  return (\n    <div\n      onMouseLeave={() => setHovered(null)}\n      className={`absolute bottom-full z-20 mb-1.5 rounded-[10px] bg-surface p-1 shadow-raised ${width}\n        ${align === \"right\" ? \"right-0\" : \"left-0\"}`}\n      style={{\n        animation: \"beautiful-pop-in 180ms cubic-bezier(0.23,1,0.32,1) both\",\n        transformOrigin: align === \"right\" ? \"bottom right\" : \"bottom left\",\n      }}\n    >\n      <span\n        aria-hidden\n        className=\"pointer-events-none absolute inset-x-1 rounded-[6px] bg-hover\"\n        style={{\n          top: box?.top ?? 0,\n          height: box?.height ?? 0,\n          opacity: box && hovered !== null ? 1 : 0,\n          transition:\n            \"top 220ms cubic-bezier(0.23,1,0.32,1), height 220ms cubic-bezier(0.23,1,0.32,1), opacity 150ms ease\",\n        }}\n      />\n      {items.map((item, i) => (\n        <button\n          key={item.name}\n          type=\"button\"\n          ref={(el) => {\n            rowRefs.current[i] = el;\n          }}\n          onMouseEnter={() => setHovered(i)}\n          onClick={() => onPick(item.name)}\n          className=\"relative z-10 flex h-7.5 w-full cursor-pointer items-center gap-2 rounded-[6px] px-2 text-left\"\n        >\n          <span className=\"min-w-0 flex-1 truncate text-[12.5px] font-medium text-ink\">{item.name}</span>\n          {item.tag && <span className=\"shrink-0 text-[11px] text-ink-3\">{item.tag}</span>}\n          <span className={`shrink-0 text-ink ${item.name === value ? \"\" : \"invisible\"}`}>\n            <CheckIcon />\n          </span>\n        </button>\n      ))}\n    </div>\n  );\n}\n\n/* ── chips used inside the condition card ── */\nfunction SourceChip() {\n  return (\n    <span\n      data-ui\n      className=\"inline-flex h-6 shrink-0 items-center gap-1 rounded-[6px] bg-surface px-1.5 text-[12px] font-medium text-ink shadow-btn\"\n    >\n      <span className=\"text-ink-2\">\n        <ConeIcon size={12} />\n      </span>\n      order\n    </span>\n  );\n}\n\nfunction SelectChip({\n  id,\n  value,\n  dot,\n  items,\n  width,\n  align = \"left\",\n  open,\n  onToggle,\n  onPick,\n}: {\n  id: string;\n  value: string;\n  dot?: boolean;\n  items: { name: string; tag?: string }[];\n  width: string;\n  align?: \"left\" | \"right\";\n  open: boolean;\n  onToggle: (id: string) => void;\n  onPick: (id: string, name: string) => void;\n}) {\n  return (\n    <span data-ui className=\"relative inline-flex min-w-0\">\n      <button\n        type=\"button\"\n        aria-expanded={open}\n        onClick={() => onToggle(id)}\n        className={`inline-flex h-6 min-w-0 cursor-pointer items-center gap-1 rounded-[6px] px-1.5\n          text-[12px] font-medium text-ink transition-colors duration-100\n          ${open ? \"bg-hover-2\" : \"bg-field hover:bg-hover-2\"}`}\n      >\n        {dot && <span className=\"size-1.5 shrink-0 rounded-full\" style={{ background: AMBER }} />}\n        <span className=\"min-w-0 truncate\">{value}</span>\n        <Chevron />\n      </button>\n      {open && (\n        <Menu\n          items={items}\n          value={value}\n          width={width}\n          align={align}\n          onPick={(name) => onPick(id, name)}\n        />\n      )}\n    </span>\n  );\n}\n\nfunction ConditionBody() {\n  const [values, setValues] = useState<Record<string, string>>({\n    prop1: \"risk\",\n    val1: \"High\",\n    prop2: \"owner\",\n    val2: \"Executive sponsor missing\",\n  });\n  const [open, setOpen] = useState<string | null>(null);\n\n  /* click anywhere else closes the menu */\n  useEffect(() => {\n    if (!open) return;\n    const close = (event: PointerEvent) => {\n      if (!(event.target as Element).closest(\"[data-ui]\")) setOpen(null);\n    };\n    document.addEventListener(\"pointerdown\", close);\n    return () => document.removeEventListener(\"pointerdown\", close);\n  }, [open]);\n\n  const toggle = (id: string) => setOpen((current) => (current === id ? null : id));\n  const pick = (id: string, name: string) => {\n    setValues((current) => ({ ...current, [id]: name }));\n    setOpen(null);\n  };\n\n  const chip = (id: string, items: { name: string; tag?: string }[], width: string, extra?: object) => (\n    <SelectChip\n      id={id}\n      value={values[id]}\n      items={items}\n      width={width}\n      open={open === id}\n      onToggle={toggle}\n      onPick={pick}\n      {...extra}\n    />\n  );\n\n  return (\n    <div className=\"flex flex-col gap-1.5 px-3 py-2.5\">\n      <div className=\"flex min-w-0 items-center gap-1.5\">\n        <Handle />\n        <span className=\"w-7 text-[12.5px] text-ink-2\">If</span>\n        <SourceChip />\n        {chip(\"prop1\", PROPERTIES.map((name) => ({ name })), \"w-36\")}\n        <span className=\"text-[12.5px] text-ink-2\">is</span>\n        {chip(\"val1\", FLAVORS, \"w-44\", { dot: true, align: \"right\" })}\n      </div>\n      <div className=\"flex min-w-0 flex-wrap items-center gap-x-1.5 gap-y-1.5\">\n        <Handle />\n        <span className=\"w-7 text-[12.5px] text-ink-2\">and</span>\n        <SourceChip />\n        {chip(\"prop2\", PROPERTIES.map((name) => ({ name })), \"w-36\")}\n        <span className=\"text-[12.5px] text-ink-2\">is</span>\n        <span className=\"max-w-full pl-[49px]\">\n          {chip(\"val2\", TOPPINGS, \"w-64\", { dot: true })}\n        </span>\n      </div>\n    </div>\n  );\n}\n\nfunction StepBody({ node }: { node: StepNode }) {\n  return (\n    <div className=\"flex items-center gap-2.5 p-2.5\">\n      <span\n        className=\"flex size-9 shrink-0 items-center justify-center rounded-[8px]\"\n        style={{\n          background: mix(node.hue!, 12),\n          color: node.hue,\n          boxShadow: `0 0 0 1px ${mix(node.hue!, 20)}`,\n        }}\n      >\n        <ConeIcon />\n      </span>\n      <span className=\"min-w-0 text-left\">\n        <span className=\"block truncate text-[13px] font-semibold leading-tight text-ink\">{node.title}</span>\n        <span className=\"mt-0.5 block text-[12px] leading-snug text-ink-2\">{node.caption}</span>\n      </span>\n    </div>\n  );\n}\n\n/* ── the canvas ── */\nexport default function Flowchart({ steps = NODES }: { steps?: StepNode[]; variant?: string } = {}) {\n  const canvasRef = useRef<HTMLDivElement>(null);\n  const nodeRefs = useRef(new Map<string, HTMLElement>());\n  const [width, setWidth] = useState(0);\n  const [heights, setHeights] = useState<Record<string, number>>(EST_H);\n  const [selected, setSelected] = useState<string | null>(null);\n  const [offsets, setOffsets] = useState<Record<string, { dx: number; dy: number }>>({});\n  const drag = useRef<{\n    id: string;\n    startX: number;\n    startY: number;\n    baseDx: number;\n    baseDy: number;\n    moved: boolean;\n  } | null>(null);\n\n  useLayoutEffect(() => {\n    const canvas = canvasRef.current;\n    if (!canvas) return;\n\n    const measure = () => {\n      setWidth(canvas.clientWidth);\n      setHeights((prev) => {\n        const next = { ...prev };\n        let changed = false;\n        nodeRefs.current.forEach((el, id) => {\n          const h = el.offsetHeight;\n          if (h && Math.abs(h - (next[id] ?? 0)) > 0.5) {\n            next[id] = h;\n            changed = true;\n          }\n        });\n        return changed ? next : prev;\n      });\n    };\n\n    measure();\n    const observer = new ResizeObserver(measure);\n    observer.observe(canvas);\n    nodeRefs.current.forEach((el) => observer.observe(el));\n    return () => observer.disconnect();\n  }, []);\n\n  /* rows → y offsets from measured node heights */\n  const rows = [...new Set(steps.map((n) => n.row))].sort((a, b) => a - b);\n  const rowH = rows.map((r) =>\n    Math.max(...steps.filter((n) => n.row === r).map((n) => heights[n.id] ?? 90)),\n  );\n  const rowY: number[] = [];\n  rows.forEach((_, i) => {\n    rowY[i] = i === 0 ? PAD_Y : rowY[i - 1] + rowH[i - 1] + ROW_GAP;\n  });\n  const canvasH = rowY[rows.length - 1] + rowH[rows.length - 1] + PAD_Y;\n\n  const cw = width || 480;\n  const place = (n: StepNode) => {\n    const w = Math.min(n.w, cw * 0.92);\n    const off = offsets[n.id];\n    return {\n      w,\n      cx: n.x * cw + (off?.dx ?? 0),\n      top: rowY[rows.indexOf(n.row)] + (off?.dy ?? 0),\n    };\n  };\n\n  /* card anchor points (pills sit above the card, so offset the top) */\n  const anchors = (n: StepNode) => {\n    const { cx, top } = place(n);\n    return {\n      top: { x: cx, y: top + (n.kind ? PILL_OFFSET : 0) },\n      bottom: { x: cx, y: top + (heights[n.id] ?? 90) },\n    };\n  };\n\n  const bezier = (edge: { from: string; to: string }) => {\n    const from = anchors(steps.find((n) => n.id === edge.from)!).bottom;\n    const to = anchors(steps.find((n) => n.id === edge.to)!).top;\n    const k = Math.min(Math.max(Math.abs(to.y - from.y) * 0.55, 24), 84);\n    return `M ${from.x} ${from.y} C ${from.x} ${from.y + k}, ${to.x} ${to.y - k}, ${to.x} ${to.y}`;\n  };\n\n  /* ── dragging ── */\n  const onPointerDown = (node: StepNode) => (event: React.PointerEvent<HTMLDivElement>) => {\n    if ((event.target as Element).closest(\"[data-ui]\")) return;\n    const off = offsets[node.id];\n    drag.current = {\n      id: node.id,\n      startX: event.clientX,\n      startY: event.clientY,\n      baseDx: off?.dx ?? 0,\n      baseDy: off?.dy ?? 0,\n      moved: false,\n    };\n    (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n  };\n\n  const onPointerMove = (node: StepNode) => (event: React.PointerEvent<HTMLDivElement>) => {\n    const d = drag.current;\n    if (!d || d.id !== node.id) return;\n    const dx = d.baseDx + event.clientX - d.startX;\n    const dy = d.baseDy + event.clientY - d.startY;\n    if (!d.moved && Math.hypot(dx - d.baseDx, dy - d.baseDy) < 3) return;\n    d.moved = true;\n\n    /* keep the card inside the canvas */\n    const { w } = place(node);\n    const h = heights[node.id] ?? 90;\n    const baseCx = node.x * cw;\n    const baseTop = rowY[rows.indexOf(node.row)];\n    const cx = Math.min(Math.max(baseCx + dx, w / 2 + 8), cw - w / 2 - 8);\n    const top = Math.min(Math.max(baseTop + dy, 8), canvasH - h - 8);\n    setOffsets((current) => ({ ...current, [node.id]: { dx: cx - baseCx, dy: top - baseTop } }));\n  };\n\n  const onPointerUp = (node: StepNode) => () => {\n    const d = drag.current;\n    if (d?.id === node.id) {\n      /* a real drag shouldn't also toggle selection */\n      if (d.moved) setTimeout(() => (drag.current = null), 0);\n      else drag.current = null;\n    }\n  };\n\n  const wasDragged = () => drag.current?.moved === true;\n\n  const isLit = (edge: { from: string; to: string }) =>\n    selected === edge.from || selected === edge.to;\n\n  return (\n    <div\n      ref={canvasRef}\n      className=\"relative w-full select-none overflow-hidden rounded-card bg-page shadow-hairline\"\n      style={{\n        height: canvasH,\n        backgroundImage: \"radial-gradient(var(--line-strong) 1px, transparent 1.25px)\",\n        backgroundSize: \"22px 22px\",\n        backgroundPosition: \"center\",\n      }}\n    >\n      {/* connectors */}\n      <svg width={cw} height={canvasH} className=\"pointer-events-none absolute inset-0\">\n        {EDGES.map((edge) => (\n          <path\n            key={`${edge.from}-${edge.to}`}\n            d={bezier(edge)}\n            fill=\"none\"\n            stroke={isLit(edge) ? \"var(--accent)\" : \"var(--line-strong)\"}\n            strokeWidth=\"1.25\"\n            className=\"transition-[stroke] duration-150\"\n          />\n        ))}\n      </svg>\n\n      {/* nodes */}\n      {steps.map((node) => {\n        const { w, cx, top } = place(node);\n        const active = selected === node.id;\n        return (\n          <div\n            key={node.id}\n            ref={(el) => {\n              if (el) nodeRefs.current.set(node.id, el);\n              else nodeRefs.current.delete(node.id);\n            }}\n            onPointerDown={onPointerDown(node)}\n            onPointerMove={onPointerMove(node)}\n            onPointerUp={onPointerUp(node)}\n            className=\"absolute flex -translate-x-1/2 touch-none flex-col items-start gap-1.5\"\n            style={{ left: cx, top, width: w, zIndex: drag.current?.id === node.id ? 2 : 1 }}\n          >\n            {node.kind && (\n              <span\n                className=\"inline-flex h-6 items-center rounded-[6px] px-2 text-[11.5px] font-medium\"\n                style={{\n                  background: mix(node.kind.hue, 14, \"var(--page)\"),\n                  color: mix(node.kind.hue, 80, \"var(--ink)\"),\n                }}\n              >\n                {node.kind.label}\n              </span>\n            )}\n            {node.condition ? (\n              <div className=\"w-full rounded-[18px] bg-surface shadow-card transition-shadow duration-150 hover:shadow-raised\">\n                <ConditionBody />\n              </div>\n            ) : (\n              <button\n                type=\"button\"\n                onClick={() => {\n                  if (wasDragged()) return;\n                  setSelected(active ? null : node.id);\n                }}\n                aria-pressed={active}\n                className={`w-full cursor-pointer rounded-[18px] bg-surface text-left outline-none\n                  transition-shadow duration-150 focus-visible:shadow-[0_0_0_1.5px_var(--accent)]\n                  ${\n                    active\n                      ? \"shadow-[0_0_0_1.5px_var(--accent),0_2px_10px_rgba(0,0,0,0.045)]\"\n                      : \"shadow-card hover:shadow-raised\"\n                  }`}\n              >\n                <StepBody node={node} />\n              </button>\n            )}\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-insight-cards",
      "type": "registry:block",
      "title": "Beautiful Original Insight Cards",
      "description": "Original Beautiful UI InsightCards",
      "dependencies": [
        "liveline@0.0.7",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/InsightCards.tsx",
          "target": "@components/beautiful-ui/original/primitives/InsightCards.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { Liveline, type LivelinePoint, type LivelineSeries } from \"liveline\";\nimport { useEffect, useMemo, useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * INSIGHT CARDS\n * Embedded mini-visualizations in an \"Insights N ‹ ›\"\n * carousel. Autoplay yields as soon as a person uses it.\n * ───────────────────────────────────────────────────────── */\n\nconst EASE = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\nconst formatPercent = (v: number) => `${v > 0 ? \"+\" : \"\"}${v.toFixed(2)}%`;\nconst formatMoney = (v: number) => `$${Math.round(v).toLocaleString(\"en-US\")}`;\n/* anchor the snapshot to *call* time (inside each card's mount-time memo) —\n * a module-load constant goes stale, and once the points age past the chart\n * window the canvas renders empty */\nfunction makePoints(values: number[], gap = 6): LivelinePoint[] {\n  const end = Math.floor(Date.now() / 1000);\n  return values.map((value, index) => ({\n    time: end - (values.length - 1 - index) * gap,\n    value,\n  }));\n}\n\n/* Catmull-Rom resample — turn a sparse series into a dense, smoothly curved\n * one so both the line and the hover cursor glide instead of stepping between\n * a handful of points. */\nfunction smooth(values: number[], perSegment = 9): number[] {\n  if (values.length < 3) return values.slice();\n  const out: number[] = [];\n  const n = values.length;\n  for (let i = 0; i < n - 1; i += 1) {\n    const p0 = values[Math.max(0, i - 1)];\n    const p1 = values[i];\n    const p2 = values[i + 1];\n    const p3 = values[Math.min(n - 1, i + 2)];\n    for (let s = 0; s < perSegment; s += 1) {\n      const t = s / perSegment;\n      const t2 = t * t;\n      const t3 = t2 * t;\n      out.push(\n        0.5 *\n          (2 * p1 +\n            (-p0 + p2) * t +\n            (2 * p0 - 5 * p1 + 4 * p2 - p3) * t2 +\n            (-p0 + 3 * p1 - 3 * p2 + p3) * t3),\n      );\n    }\n  }\n  out.push(values[n - 1]);\n  return out;\n}\n\n/* dense, smoothed points spanning exactly `spanSecs` — keeps the chart window\n * unchanged while multiplying the resolution. */\nfunction smoothPoints(values: number[], spanSecs: number): LivelinePoint[] {\n  const dense = smooth(values);\n  return makePoints(dense, spanSecs / (dense.length - 1));\n}\n\nfunction useDarkMode() {\n  const [dark, setDark] = useState(false);\n\n  useEffect(() => {\n    const root = document.documentElement;\n    const update = () => setDark(root.classList.contains(\"dark\"));\n    update();\n    const observer = new MutationObserver(update);\n    observer.observe(root, { attributes: true, attributeFilter: [\"class\"] });\n    return () => observer.disconnect();\n  }, []);\n\n  return dark;\n}\n\n/* inline @entity mention */\nfunction Entity({ name, tone }: { name: string; tone: string }) {\n  return (\n    <span className=\"inline-flex items-center gap-1 align-baseline font-medium text-ink\">\n      <span className={`inline-block size-2.5 rounded-full ${tone}`} />\n      @{name}\n    </span>\n  );\n}\n\nfunction Mono({ children, tone }: { children: React.ReactNode; tone: \"red\" | \"green\" }) {\n  return (\n    <code className={`font-mono text-[11.5px] ${tone === \"red\" ? \"text-red\" : \"text-green\"}`}>\n      {children}\n    </code>\n  );\n}\n\nfunction chartIndexFromPointer(event: React.PointerEvent<HTMLDivElement>, pointCount: number) {\n  const rect = event.currentTarget.getBoundingClientRect();\n  const progress = Math.max(0, Math.min(1, (event.clientX - rect.left) / rect.width));\n  return Math.round(progress * (pointCount - 1));\n}\n\nfunction ChartTooltip({ rows }: { rows: { label: string; value: string; color: string }[] }) {\n  return (\n    <div className=\"insight-chart-tooltip\">\n      {rows.map((row) => (\n        <span key={row.label} className=\"insight-chart-tooltip-item\">\n          <span className=\"insight-chart-tooltip-dot\" style={{ background: row.color }} />\n          {row.value}\n        </span>\n      ))}\n    </div>\n  );\n}\n\n/* content shape for the return-comparison card's two plotted series */\nexport type CompareSeries = {\n  name: string;\n  values: number[];\n  sub: string;\n  tone: \"red\" | \"green\";\n  dot: string;\n  color: string;\n  tooltipColor: string;\n};\n\nconst COMPARE_SERIES: CompareSeries[] = [\n  {\n    name: \"At risk\",\n    values: [-2.9, -3.4, -3.05, -3.86, -3.52, -4.1, -3.82, -4.41],\n    sub: \"-$2,377.66\",\n    tone: \"red\",\n    dot: \"bg-orange\",\n    color: \"#f68f3c\",\n    tooltipColor: \"var(--orange)\",\n  },\n  {\n    name: \"Healthy\",\n    values: [0.22, 0.58, 0.42, 0.91, 0.76, 1.08, 0.96, 1.15],\n    sub: \"+$617.22\",\n    tone: \"green\",\n    dot: \"bg-accent\",\n    color: \"#3d9aff\",\n    tooltipColor: \"var(--accent)\",\n  },\n];\n\n/* 1 — return comparison: 2 series, legend + big deltas + line chart */\nfunction CompareCard({ series = COMPARE_SERIES }: { series?: CompareSeries[] }) {\n  const dark = useDarkMode();\n  const [hoverIndex, setHoverIndex] = useState<number | null>(null);\n  const points = useMemo(\n    () => series.map((s) => smoothPoints(s.values, 42)),\n    [series],\n  );\n  const pointCount = points[0]?.length ?? 0;\n\n  const chartSeries: LivelineSeries[] = useMemo(\n    () =>\n      series.map((s, i) => ({\n        id: s.name,\n        label: \"\",\n        data: points[i],\n        value: points[i].at(-1)?.value ?? (s.values.at(-1) ?? 0),\n        color: s.color,\n      })),\n    [series, points],\n  );\n\n  return (\n    <div className=\"min-h-[278px] rounded-card bg-surface p-3 shadow-hairline\">\n      <div className=\"flex items-center gap-4\">\n        {series.map((s, i) => (\n          <div key={s.name} className=\"flex-1\">\n            <span className=\"flex items-center gap-1.5 text-[11.5px] text-ink-2\">\n              <span className={`size-2 rounded-full ${s.dot}`} />\n              {s.name}\n            </span>\n            <span className={`block text-[17px] font-semibold tracking-[-0.01em] tabular-nums ${s.tone === \"red\" ? \"text-red\" : \"text-green\"}`}>\n              {formatPercent(points[i].at(-1)?.value ?? (s.values.at(-1) ?? 0))}\n            </span>\n            <Mono tone={s.tone}>{s.sub}</Mono>\n          </div>\n        ))}\n      </div>\n      <div className=\"mt-2 overflow-hidden rounded-control bg-inset shadow-hairline\">\n        <div className=\"flex items-center justify-between border-b border-line px-2.5 py-1.5\">\n          <span className=\"text-[11px] text-ink-3 tabular-nums\">\n            Trend snapshot\n          </span>\n          <span className=\"rounded-full bg-field px-2 py-0.5 text-[10.5px] font-medium text-ink-2\">\n            Snapshot\n          </span>\n        </div>\n        <div\n          className=\"insight-chart-stage relative h-[166px]\"\n          onPointerDown={(event) => setHoverIndex(chartIndexFromPointer(event, pointCount))}\n          onPointerMove={(event) => setHoverIndex(chartIndexFromPointer(event, pointCount))}\n          onPointerLeave={() => setHoverIndex(null)}\n          onPointerCancel={() => setHoverIndex(null)}\n          onPointerUp={() => setHoverIndex(null)}\n        >\n          <Liveline\n            data={[]}\n            value={0}\n            series={chartSeries}\n            theme={dark ? \"dark\" : \"light\"}\n            grid={false}\n            pulse={false}\n            window={42}\n            paused\n            scrub={false}\n            cursor=\"default\"\n            lineWidth={2.25}\n            padding={{ top: 40, right: 0, bottom: 22, left: 0 }}\n            formatValue={formatPercent}\n          />\n          {hoverIndex !== null && <>\n            <span className=\"insight-chart-cursor\" style={{ left: `${(hoverIndex / (pointCount - 1)) * 100}%` }} />\n            <span className=\"insight-chart-tooltip-anchor\" style={{ left: `${Math.min(Math.max((hoverIndex / (pointCount - 1)) * 100, 28), 72)}%` }}>\n              <ChartTooltip rows={series.map((s, i) => ({ label: s.name, value: formatPercent(points[i][hoverIndex].value), color: s.tooltipColor }))} />\n            </span>\n          </>}\n        </div>\n      </div>\n    </div>\n  );\n}\n\n/* content shape for the anomaly card's two toggled metric series */\nexport type AnomalyData = {\n  spend: number[];\n  usage: number[];\n};\n\nconst ANOMALY_DATA: AnomalyData = {\n  spend: [274, 289, 264, 307, 331, 1210, 1718, 2112],\n  usage: [18, 19, 17, 21, 22, 58, 81, 96],\n};\n\n/* 2 — anomaly: bars with threshold + big spent value */\nfunction AnomalyCard({ data: anomaly = ANOMALY_DATA }: { data?: AnomalyData }) {\n  const dark = useDarkMode();\n  const [metric, setMetric] = useState<\"spend\" | \"usage\">(\"spend\");\n  const [hoverIndex, setHoverIndex] = useState<number | null>(null);\n  const spend = useMemo(\n    () => makePoints(anomaly.spend, 7),\n    [anomaly],\n  );\n  const usage = useMemo(\n    () => makePoints(anomaly.usage, 7),\n    [anomaly],\n  );\n\n  const data = metric === \"spend\" ? spend : usage;\n  const value = data.at(-1)?.value ?? (metric === \"spend\" ? 2112 : 96);\n  const threshold = metric === \"spend\" ? \"$2,112\" : \"82 kWh\";\n  const moneyLabel = formatMoney(spend.at(-1)?.value ?? 2112);\n\n  return (\n    <div className=\"min-h-[278px] rounded-card bg-surface p-3 shadow-hairline\">\n      <div className=\"flex items-center justify-between\">\n        <span className=\"flex items-center gap-1.5 text-[12px] font-medium text-ink\">\n          <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--red)\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M12 19V5M5 12l7-7 7 7\" /></svg>\n          Unusual support activity\n        </span>\n        <span className=\"rounded-full bg-field px-2 py-0.5 text-[10.5px] font-medium text-ink-2\">\n          Snapshot\n        </span>\n      </div>\n      <div className=\"mt-2 overflow-hidden rounded-control bg-inset shadow-hairline\">\n        <div className=\"flex items-center justify-between border-b border-line px-2.5 py-1.5\">\n          <span className=\"text-[11px] text-ink-3 tabular-nums\">\n            {hoverIndex !== null\n              ? metric === \"spend\"\n                ? formatMoney(data[hoverIndex].value)\n                : `${Math.round(data[hoverIndex].value)} kWh`\n              : `${threshold} threshold`}\n          </span>\n          <span className=\"flex rounded-full bg-field p-0.5\">\n            {([\"spend\", \"usage\"] as const).map((item) => (\n              <button\n                key={item}\n                type=\"button\"\n                aria-pressed={metric === item}\n                onClick={() => setMetric(item)}\n                className={`rounded-full px-2 py-0.5 text-[10.5px] font-medium transition-[background-color,color,box-shadow,transform] duration-150 active:scale-[0.96] ${\n                  metric === item ? \"bg-surface text-ink shadow-btn\" : \"text-ink-3 hover:text-ink-2\"\n                }`}\n              >\n                {item === \"spend\" ? \"Spend\" : \"Usage\"}\n              </button>\n            ))}\n          </span>\n        </div>\n        <div\n          className=\"insight-chart-stage relative h-[166px]\"\n          onPointerDown={(event) => setHoverIndex(chartIndexFromPointer(event, data.length))}\n          onPointerMove={(event) => setHoverIndex(chartIndexFromPointer(event, data.length))}\n          onPointerLeave={() => setHoverIndex(null)}\n          onPointerCancel={() => setHoverIndex(null)}\n          onPointerUp={() => setHoverIndex(null)}\n        >\n          <Liveline\n            data={data}\n            value={value}\n            theme={dark ? \"dark\" : \"light\"}\n            color=\"#ee5c61\"\n            grid\n            scrub={false}\n            fill={false}\n            pulse={false}\n            momentum={false}\n            paused\n            window={49}\n            lineWidth={2.25}\n            cursor=\"crosshair\"\n            padding={{ top: 34, right: 0, bottom: 22, left: 0 }}\n            formatValue={(v) => (metric === \"spend\" ? formatMoney(v) : `${Math.round(v)} kWh`)}\n          />\n          {hoverIndex !== null && <>\n            <span className=\"insight-chart-cursor\" style={{ left: `${(hoverIndex / (data.length - 1)) * 100}%` }} />\n            <span className=\"insight-chart-tooltip-anchor\" style={{ left: `${Math.min(Math.max((hoverIndex / (data.length - 1)) * 100, 28), 72)}%` }}>\n              <ChartTooltip rows={[{ label: metric === \"spend\" ? \"Spend\" : \"Usage\", value: metric === \"spend\" ? formatMoney(data[hoverIndex].value) : `${Math.round(data[hoverIndex].value)} kWh`, color: \"var(--red)\" }]} />\n            </span>\n          </>}\n        </div>\n      </div>\n      <div className=\"mt-1.5 flex items-baseline gap-2\">\n        <span className=\"text-[17px] font-semibold tracking-[-0.01em] text-ink tabular-nums\">\n          {moneyLabel} spent\n        </span>\n        <Mono tone=\"red\">+$1,834.66</Mono>\n        <span className=\"text-[11px] text-ink-3\">vs 3 months</span>\n      </div>\n    </div>\n  );\n}\n\n/* content shape for one allocation segment */\nexport type AllocationSegment = {\n  name: string;\n  label: string;\n  pct: number;\n  amount: string;\n  cls: string;\n  tone: string;\n};\n\nconst ALLOCATION_SEGMENTS: AllocationSegment[] = [\n  { name: \"ENT\", label: \"Enterprise\", pct: 72.5, amount: \"$51,785\", cls: \"bg-orange\", tone: \"text-orange\" },\n  { name: \"MID\", label: \"Mid-market\", pct: 22.8, amount: \"$16,278\", cls: \"bg-line-strong\", tone: \"text-ink-2\" },\n  { name: \"SMB\", label: \"Small business\", pct: 4.7, amount: \"$3,357\", cls: \"bg-line\", tone: \"text-ink-3\" },\n];\n\n/* 3 — allocation: hero number + segmented bar + legend */\nfunction AllocationCard({ segments = ALLOCATION_SEGMENTS }: { segments?: AllocationSegment[] }) {\n  const [selected, setSelected] = useState(segments[0].name);\n  const active = segments.find((segment) => segment.name === selected) ?? segments[0];\n\n  return (\n    <div className=\"min-h-[278px] rounded-card bg-surface p-3 shadow-hairline\">\n      <span className=\"flex items-center gap-1.5 text-[12px] font-medium text-ink\">\n        <span className=\"flex size-3.5 items-center justify-center rounded-full bg-orange text-[8px] font-bold text-white\">\n          V\n        </span>\n        Renewal allocation\n      </span>\n      <span className=\"mt-1 block text-[20px] font-semibold tracking-[-0.01em] text-ink tabular-nums\">\n        {active.amount}\n      </span>\n      <div\n        className=\"mt-3 flex h-9 gap-0.5 overflow-hidden rounded-full bg-field p-0.5\"\n        role=\"group\"\n        aria-label=\"Allocation segments\"\n      >\n        {segments.map((s) => (\n          <button\n            key={s.name}\n            type=\"button\"\n            aria-pressed={selected === s.name}\n            aria-label={`${s.label}: ${s.pct}%`}\n            onClick={() => setSelected(s.name)}\n            className={`relative h-full overflow-hidden rounded-full ${s.cls} transition-[opacity,transform,box-shadow] duration-300 active:scale-[0.98]`}\n            style={{\n              width: `${s.pct}%`,\n              opacity: selected === s.name ? 1 : 0.58,\n              boxShadow: selected === s.name ? \"inset 0 0 0 1px rgba(255,255,255,0.22)\" : undefined,\n              transitionTimingFunction: EASE,\n            }}\n          >\n            <span\n              className=\"absolute inset-y-1 left-1 rounded-full bg-white/20 transition-[width,opacity] duration-500\"\n              style={{\n                width: selected === s.name ? \"calc(100% - 8px)\" : \"0%\",\n                opacity: selected === s.name ? 1 : 0,\n                transitionTimingFunction: EASE,\n              }}\n            />\n          </button>\n        ))}\n      </div>\n      <div className=\"mt-2 flex items-center gap-1.5\">\n        {segments.map((s) => (\n          <button\n            key={s.name}\n            type=\"button\"\n            aria-pressed={selected === s.name}\n            onClick={() => setSelected(s.name)}\n            className={`flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[11px] transition-[background-color,color,transform] duration-150 active:scale-[0.96] ${\n              selected === s.name ? \"bg-field text-ink\" : \"text-ink-2 hover:bg-hover hover:text-ink\"\n            }`}\n          >\n            <span className={`size-1.5 rounded-full ${s.cls}`} />\n            {s.name} <span className=\"tabular-nums\">{s.pct}%</span>\n          </button>\n        ))}\n      </div>\n      <div className=\"mt-3 min-h-16 rounded-control bg-inset px-2.5 py-2 shadow-hairline\">\n        <span className={`block text-[11.5px] font-medium ${active.tone}`}>{active.label}</span>\n        <span className=\"mt-1 block text-[11px] leading-relaxed text-ink-3\">\n          Contribution snapshot across current inventory value. Segment selection changes the inspected group without moving the card.\n        </span>\n      </div>\n    </div>\n  );\n}\n\n/* content shape for one insight page in the carousel */\nexport type InsightPage = {\n  key: string;\n  prose: React.ReactNode;\n  Card: React.ComponentType;\n  pill: string;\n};\n\nconst PAGES: InsightPage[] = [\n  {\n    key: \"compare\",\n    prose: (\n      <>\n        The weakest segment in <Entity name=\"Renewals\" tone=\"bg-orange\" /> is\n        mid-market — down <Mono tone=\"red\">-6%</Mono> or <Mono tone=\"red\">-$2,453.44</Mono>.\n      </>\n    ),\n    Card: CompareCard,\n    pill: \"Which accounts drive the decline?\",\n  },\n  {\n    key: \"anomaly\",\n    prose: (\n      <>\n        Unusually high support activity on <span className=\"font-medium text-ink\">Dec 13</span> —{\" \"}\n        <Mono tone=\"red\">+$1,834.66</Mono> above your average.\n      </>\n    ),\n    Card: AnomalyCard,\n    pill: \"Show the affected accounts\",\n  },\n  {\n    key: \"allocation\",\n    prose: (\n      <>\n        Enterprise accounts represent <Entity name=\"Renewal value\" tone=\"bg-orange\" /> — they are{\" \"}\n        <span className=\"font-medium text-ink\">72.5%</span> of your case.\n      </>\n    ),\n    Card: AllocationCard,\n    pill: \"How does this compare by segment?\",\n  },\n];\n\nexport type InsightCardsLabels = {\n  /** carousel heading shown before the page count */\n  title: string;\n};\n\nconst DEFAULT_INSIGHT_LABELS: InsightCardsLabels = {\n  title: \"Insights\",\n};\n\nexport default function InsightCards({\n  pages = PAGES,\n  labels,\n}: {\n  variant?: string;\n  pages?: InsightPage[];\n  labels?: Partial<InsightCardsLabels>;\n} = {}) {\n  const l = { ...DEFAULT_INSIGHT_LABELS, ...labels };\n  const [page, setPage] = useState(0);\n\n  const move = (direction: -1 | 1) => {\n    setPage((current) => (current + direction + pages.length) % pages.length);\n  };\n\n  const { prose, Card, pill } = pages[page];\n\n  return (\n    <div className=\"min-h-[408px] w-full max-w-86\">\n      {/* pager header */}\n      <div className=\"flex items-center justify-between\">\n        <span className=\"flex items-baseline gap-1.5\">\n          <span className=\"text-[13px] font-semibold text-ink\">{l.title}</span>\n          <span className=\"text-[13px] text-ink-3 tabular-nums\">{pages.length}</span>\n        </span>\n        <span className=\"flex items-center gap-0.5\">\n          {([\"M15 18l-6-6 6-6\", \"M9 6l6 6-6 6\"] as const).map((d, i) => (\n            <button\n              key={i}\n              aria-label={i === 0 ? \"Previous insight\" : \"Next insight\"}\n              onClick={() => move(i === 0 ? -1 : 1)}\n              className=\"flex size-6 items-center justify-center rounded-[6px] text-ink-3\n                transition-[background-color,color,transform] duration-100 hover:bg-hover\n                hover:text-ink active:scale-[0.96]\"\n            >\n              <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n                <path d={d} />\n              </svg>\n            </button>\n          ))}\n        </span>\n      </div>\n\n      {/* page content — blurred crossfade */}\n      <div\n        className=\"transition-[opacity,filter] duration-250\"\n        style={{ opacity: 1, filter: \"blur(0)\" }}\n      >\n        <p className=\"mt-1.5 text-[12.5px] leading-relaxed text-ink-2\">{prose}</p>\n        <div className=\"mt-2\">\n          <Card />\n        </div>\n        <button\n          className=\"mt-2 rounded-full bg-surface px-3 py-1.5 text-left text-[12px] text-ink\n            shadow-btn transition-colors duration-100 hover:bg-hover\"\n        >\n          {pill}\n        </button>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-loading-state",
      "type": "registry:block",
      "title": "Beautiful Original Loading State",
      "description": "Original Beautiful UI LoadingState",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/LoadingState.tsx",
          "target": "@components/beautiful-ui/original/primitives/LoadingState.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * LOADING STATE — pixel-grid loader for long-running work\n *\n * Variants:\n *   Drive  — square cells, chevron wavefront driving right;\n *            the 650ms cycle is shorter than the sweep, so\n *            two fronts are always in flight\n *   Dots   — same wavefront, circular cells\n *   Orbit  — a comet lapping the grid perimeter\n *   Surfer — the Drive loader paired with a meme video below\n *\n * Paired with a shimmering label and a live elapsed timer\n * in mono tabular figures. Reduced motion freezes the grid\n * to its dim state; the timer still ticks.\n * ───────────────────────────────────────────────────────── */\n\nconst chevron = Array.from({ length: 9 }, (_, i) => {\n  const r = Math.floor(i / 3), c = i % 3;\n  return (c + Math.abs(r - 1)) * 90;\n});\n\nconst ORBIT_ORDER = [0, 1, 2, 5, 8, 7, 6, 3];\nconst orbit = Array.from({ length: 9 }, (_, i) => {\n  const k = ORBIT_ORDER.indexOf(i);\n  return k === -1 ? null : k * 110;\n});\n\nconst PATTERNS: Record<string, { delays: (number | null)[]; dur: number; round: boolean }> = {\n  Drive: { delays: chevron, dur: 650, round: false },\n  Dots: { delays: chevron, dur: 650, round: true },\n  Orbit: { delays: orbit, dur: 950, round: false },\n};\n\nfunction LoaderGrid({\n  delays,\n  dur,\n  round,\n}: {\n  delays: (number | null)[];\n  dur: number;\n  round: boolean;\n}) {\n  return (\n    <span aria-hidden className=\"grid shrink-0 grid-cols-[repeat(3,4px)] gap-[1.5px]\">\n      {delays.map((delay, index) => (\n        <span\n          key={index}\n          className={`size-[4px] bg-ink ${round ? \"rounded-full\" : \"rounded-[1px]\"}`}\n          style={{\n            opacity: delay === null ? 0.07 : 0.15,\n            animation: delay === null ? \"none\" : `beautiful-pixel-on ${dur}ms ease-in-out ${delay}ms infinite`,\n          }}\n        />\n      ))}\n    </span>\n  );\n}\n\nfunction useElapsed() {\n  const [ds, setDs] = useState(0);\n  useEffect(() => {\n    const t = setInterval(() => setDs((d) => d + 1), 100);\n    return () => clearInterval(t);\n  }, []);\n  const total = ds / 10;\n  if (total < 60) return `${total.toFixed(1)}s`;\n  return `${Math.floor(total / 60)}m ${(total % 60).toFixed(1)}s`;\n}\n\nexport default function LoadingState({\n  label,\n  variant = \"Drive\",\n  /** Caller-provided local or remote recording for the Surfer variant. */\n  videoSrc,\n}: {\n  label?: string;\n  variant?: string;\n  videoSrc?: string;\n}) {\n  const elapsed = useElapsed();\n  const surfer = variant === \"Surfer\";\n  const resolvedLabel = label ?? (surfer ? \"Reviewing the recording\" : \"Working\");\n  const [videoOk, setVideoOk] = useState(Boolean(videoSrc));\n  useEffect(() => setVideoOk(Boolean(videoSrc)), [videoSrc]);\n  const { delays, dur, round } = PATTERNS[variant] ?? PATTERNS.Drive;\n\n  const labelEl = (\n    <span\n      className=\"bg-clip-text text-[13px] font-medium text-transparent\"\n      style={{\n        backgroundImage:\n          \"linear-gradient(90deg, var(--ink-3) 35%, var(--ink) 50%, var(--ink-3) 65%)\",\n        backgroundSize: \"200% 100%\",\n        animation: \"beautiful-shimmer-text 1.4s linear infinite\",\n      }}\n    >\n      {resolvedLabel}\n    </span>\n  );\n  const elapsedEl = <span className=\"font-mono text-[12px] text-ink-3 tabular-nums\">{elapsed}</span>;\n\n  if (surfer) {\n    return (\n      <div role=\"status\" className=\"flex w-fit flex-col items-start\">\n        <div className=\"flex items-center gap-2.5\">\n          <LoaderGrid {...PATTERNS.Drive} />\n          {labelEl}\n          {elapsedEl}\n        </div>\n\n        {/* the context card follows the status text it is illustrating */}\n        <div\n          className=\"mt-2 w-56 overflow-hidden rounded-[10px] shadow-overlay\"\n          style={{ animation: \"beautiful-pop-in 200ms cubic-bezier(0.16,1,0.3,1) both\", transformOrigin: \"top left\" }}\n        >\n          <div className=\"relative aspect-video w-full\" style={{ background: \"var(--tooltip-bg)\" }}>\n            {videoOk ? (\n              <video\n                src={videoSrc}\n                autoPlay\n                muted\n                loop\n                playsInline\n                onError={() => setVideoOk(false)}\n                className=\"h-full w-full object-cover\"\n              />\n            ) : (\n              <div className=\"flex h-full w-full flex-col items-center justify-center gap-1.5\">\n                <LoaderGrid {...PATTERNS.Drive} />\n                <span className=\"px-3 text-center font-mono text-[10px]\" style={{ color: \"var(--tooltip-muted)\" }}>\n                  Video unavailable\n                </span>\n              </div>\n            )}\n          </div>\n        </div>\n      </div>\n    );\n  }\n\n  return (\n    <div role=\"status\" className=\"flex w-fit items-center gap-2.5\">\n      <LoaderGrid delays={delays} dur={dur} round={round} />\n      {labelEl}\n      {elapsedEl}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-prompt-bar",
      "type": "registry:block",
      "title": "Beautiful Original Prompt Bar",
      "description": "Original Beautiful UI PromptBar",
      "dependencies": [
        "glimm@0.3.0",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/PromptBar.tsx",
          "target": "@components/beautiful-ui/original/primitives/PromptBar.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createShader, playSweep, accentChain, ACCENTS } from \"glimm\";\n\n/* The built-in \"prism\" palette is only cyan→indigo→magenta, so a sweep\n * reads as blue/purple. Build a true full-spectrum rainbow instead. */\nconst RAINBOW = accentChain([\n  ACCENTS.red,\n  ACCENTS.orange,\n  ACCENTS.yellow,\n  ACCENTS.green,\n  ACCENTS.cyan,\n  ACCENTS.blue,\n  ACCENTS.purple,\n]);\n\n/* ─────────────────────────────────────────────────────────\n * PROMPT BAR\n * A composer with real controls: attach, @ data sources,\n * / commands, a model picker, dictation, and send.\n * Type @ or / to open the menus; ↑↓ + Enter to pick.\n * Variants: Rounded (card radius) · Pill (full radius).\n * ───────────────────────────────────────────────────────── */\n\nfunction Icon({ children, size = 15, strokeWidth = 1.8 }: { children: React.ReactNode; size?: number; strokeWidth?: number }) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n      {children}\n    </svg>\n  );\n}\n\nconst GLYPHS: Record<string, React.ReactNode> = {\n  clip: <path d=\"m21.4 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\" />,\n  chart: <path d=\"M4 20V10M10 20V4M16 20v-7M22 20H2\" />,\n  layers: <g><path d=\"M12 2 2 7l10 5 10-5-10-5z\" /><path d=\"M2 17l10 5 10-5M2 12l10 5 10-5\" /></g>,\n  globe: <g><circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" /></g>,\n};\n\n/* real product marks, inline so the file stays self-contained */\nconst BRANDS: Record<string, React.ReactNode> = {\n  figma: (\n    <svg width=\"11\" height=\"16\" viewBox=\"0 0 38 57\" aria-hidden=\"true\">\n      <path d=\"M9.5 57A9.5 9.5 0 0 0 19 47.5V38H9.5a9.5 9.5 0 0 0 0 19z\" fill=\"#0ACF83\" />\n      <path d=\"M0 28.5A9.5 9.5 0 0 1 9.5 19H19v19H9.5A9.5 9.5 0 0 1 0 28.5z\" fill=\"#A259FF\" />\n      <path d=\"M0 9.5A9.5 9.5 0 0 1 9.5 0H19v19H9.5A9.5 9.5 0 0 1 0 9.5z\" fill=\"#F24E1E\" />\n      <path d=\"M19 0h9.5a9.5 9.5 0 1 1 0 19H19V0z\" fill=\"#FF7262\" />\n      <path d=\"M38 28.5a9.5 9.5 0 1 1-19 0 9.5 9.5 0 0 1 19 0z\" fill=\"#1ABCFE\" />\n    </svg>\n  ),\n  slack: (\n    <svg width=\"15\" height=\"15\" viewBox=\"0 0 127 127\" aria-hidden=\"true\">\n      <path d=\"M27.2 80c0 7.3-5.9 13.2-13.2 13.2C6.7 93.2.8 87.3.8 80c0-7.3 5.9-13.2 13.2-13.2h13.2V80zm6.6 0c0-7.3 5.9-13.2 13.2-13.2 7.3 0 13.2 5.9 13.2 13.2v33c0 7.3-5.9 13.2-13.2 13.2-7.3 0-13.2-5.9-13.2-13.2V80z\" fill=\"#E01E5A\" />\n      <path d=\"M47 27.2c-7.3 0-13.2-5.9-13.2-13.2C33.8 6.7 39.7.8 47 .8c7.3 0 13.2 5.9 13.2 13.2v13.2H47zm0 6.7c7.3 0 13.2 5.9 13.2 13.2 0 7.3-5.9 13.2-13.2 13.2H13.9C6.6 60.3.7 54.4.7 47.1c0-7.3 5.9-13.2 13.2-13.2H47z\" fill=\"#36C5F0\" />\n      <path d=\"M99.9 47.1c0-7.3 5.9-13.2 13.2-13.2 7.3 0 13.2 5.9 13.2 13.2 0 7.3-5.9 13.2-13.2 13.2H99.9V47.1zm-6.6 0c0 7.3-5.9 13.2-13.2 13.2-7.3 0-13.2-5.9-13.2-13.2V13.9C66.9 6.6 72.8.7 80.1.7c7.3 0 13.2 5.9 13.2 13.2v33.2z\" fill=\"#2EB67D\" />\n      <path d=\"M80.1 99.8c7.3 0 13.2 5.9 13.2 13.2 0 7.3-5.9 13.2-13.2 13.2-7.3 0-13.2-5.9-13.2-13.2V99.8h13.2zm0-6.6c-7.3 0-13.2-5.9-13.2-13.2 0-7.3 5.9-13.2 13.2-13.2h33.1c7.3 0 13.2 5.9 13.2 13.2 0 7.3-5.9 13.2-13.2 13.2H80.1z\" fill=\"#ECB22E\" />\n    </svg>\n  ),\n  gmail: (\n    <svg width=\"15\" height=\"12\" viewBox=\"0 0 256 193\" aria-hidden=\"true\">\n      <path d=\"M58.182 192.05V93.14L27.507 65.077 0 49.504v125.091c0 9.658 7.825 17.455 17.455 17.455h40.727Z\" fill=\"#4285F4\" />\n      <path d=\"M197.818 192.05h40.727c9.659 0 17.455-7.826 17.455-17.455V49.505l-31.156 17.837-27.026 25.798v98.91Z\" fill=\"#34A853\" />\n      <path d=\"m58.182 93.14-4.174-38.647 4.174-36.989L128 69.868l69.818-52.364 4.669 34.992-4.669 40.644L128 145.504 58.182 93.14Z\" fill=\"#EA4335\" />\n      <path d=\"M197.818 17.504V93.14L256 49.504V26.231c0-21.585-24.64-33.89-41.89-20.945l-16.292 12.218Z\" fill=\"#FBBC04\" />\n      <path d=\"m0 49.504 26.759 20.07L58.182 93.14V17.504L41.89 5.286C24.61-7.66 0 4.646 0 26.23v23.273Z\" fill=\"#C5221F\" />\n    </svg>\n  ),\n};\n\ntype Source = {\n  key: string;\n  name: string;\n  desc: string;\n  glyph?: string;\n  brand?: string;\n  attach?: boolean;\n  connect?: boolean;\n};\n\nconst SOURCES: Source[] = [\n  { key: \"attach\", name: \"Add photos & files\", desc: \"Upload from your computer\", glyph: \"clip\", attach: true },\n  { key: \"forecast\", name: \"Renewal forecast\", desc: \"842 accounts and risk signals\", glyph: \"chart\" },\n  { key: \"notes\", name: \"Account notes\", desc: \"CRM notes and owner updates\", glyph: \"layers\" },\n  { key: \"web\", name: \"Web search\", desc: \"Real-time news and info\", glyph: \"globe\" },\n  { key: \"figma\", name: \"Figma\", desc: \"Design-to-code workflows\", brand: \"figma\" },\n  { key: \"slack\", name: \"Slack\", desc: \"Read and manage Slack\", brand: \"slack\" },\n  { key: \"gmail\", name: \"Gmail\", desc: \"Read and manage Gmail\", brand: \"gmail\", connect: true },\n];\n\nconst COMMANDS = [\n  { key: \"compare\", name: \"/compare\", desc: \"Forecast vs. account health\" },\n  { key: \"action-plan\", name: \"/action-plan\", desc: \"Draft an outreach plan\" },\n  { key: \"prioritize\", name: \"/prioritize\", desc: \"Rank accounts by risk\" },\n  { key: \"draft-email\", name: \"/draft-email\", desc: \"Write an owner update\" },\n  { key: \"summarize\", name: \"/summarize\", desc: \"Digest the thread so far\" },\n];\n\nconst MODELS = [\n  { key: \"reasoning\", name: \"Reasoning\", tag: \"Deep\" },\n  { key: \"balanced\", name: \"Balanced\", tag: \"Default\" },\n  { key: \"fast\", name: \"Fast\", tag: \"Quick\" },\n];\n\nconst FILES = [\"renewals_q3.csv\", \"account-notes.md\", \"forecast.pdf\"];\nconst DICTATION = \"Compare the renewal forecast with account health\";\n\n/* self-running demo: walk the @ menu, then the / menu, and repeat.\n * Any pointer or key interaction hands control to the user. */\nconst AUTO_STEPS: {\n  draft: string;\n  active?: number;\n  connect?: boolean;\n  modelOpen?: boolean;\n  model?: string;\n  hold: number;\n}[] = [\n  { draft: \"\", connect: false, model: \"balanced\", hold: 1100 },\n  { draft: \"@\", active: 0, hold: 900 },\n  { draft: \"@\", active: 1, hold: 620 },\n  { draft: \"@\", active: 4, hold: 620 },\n  { draft: \"@\", active: 6, hold: 700 },\n  { draft: \"@\", active: 6, connect: true, hold: 1000 },\n  { draft: \"\", hold: 700 },\n  { draft: \"/\", active: 0, hold: 900 },\n  { draft: \"/\", active: 1, hold: 620 },\n  { draft: \"/\", active: 3, hold: 1000 },\n  { draft: \"\", hold: 800 },\n  // open the model picker and upgrade to the flagship → rainbow sweep\n  { draft: \"\", modelOpen: true, hold: 1200 },\n  { draft: \"\", model: \"reasoning\", hold: 2400 },\n  { draft: \"\", hold: 900 },\n];\n\n/* the last @word or /word being typed, if any */\nfunction parseToken(draft: string): { kind: \"at\" | \"slash\"; query: string; start: number } | null {\n  const match = /(^|\\s)([@/])([\\w-]*)$/.exec(draft);\n  if (!match) return null;\n  return {\n    kind: match[2] === \"@\" ? \"at\" : \"slash\",\n    query: match[3].toLowerCase(),\n    start: match.index + match[1].length,\n  };\n}\n\nexport default function PromptBar({\n  variant = \"Rounded\",\n  demo = true,\n  tall = false,\n  placeholder,\n  onSend,\n}: {\n  variant?: string;\n  /** the self-running walkthrough; turn off when embedding in a real surface */\n  demo?: boolean;\n  /** hero sizing: a multi-line input with controls on their own row */\n  tall?: boolean;\n  placeholder?: string;\n  onSend?: (text: string) => void;\n}) {\n  const pill = variant === \"Pill\";\n  const [draft, setDraft] = useState(\"\");\n  const [dismissed, setDismissed] = useState(false);\n  const [plusOpen, setPlusOpen] = useState(false);\n  const [modelOpen, setModelOpen] = useState(false);\n  const [model, setModel] = useState(MODELS[1]);\n  const [attachments, setAttachments] = useState<string[]>([]);\n  const [connected, setConnected] = useState(false);\n  const [active, setActive] = useState(0);\n  const [listening, setListening] = useState(false);\n  const [auto, setAuto] = useState(demo);\n  const [autoStep, setAutoStep] = useState(0);\n  const [expanded, setExpanded] = useState(false);\n  const wide = expanded || tall;\n  const [rowBox, setRowBox] = useState<{ top: number; height: number } | null>(null);\n  const [engaged, setEngaged] = useState(false);\n  const [modelBox, setModelBox] = useState<{ top: number; height: number } | null>(null);\n  const [modelHovered, setModelHovered] = useState<number | null>(null);\n  const [modelMenuLeft, setModelMenuLeft] = useState(0);\n  const [modelMenuBottom, setModelMenuBottom] = useState(0);\n  const composerAnchorRef = useRef<HTMLDivElement>(null);\n  const controlsRef = useRef<HTMLDivElement>(null);\n  const inputRef = useRef<HTMLTextAreaElement>(null);\n  const measureRef = useRef<HTMLSpanElement>(null);\n  const modelRef = useRef<HTMLButtonElement>(null);\n  const rowRefs = useRef<(HTMLButtonElement | null)[]>([]);\n  const modelRowRefs = useRef<(HTMLButtonElement | null)[]>([]);\n  const glimmRef = useRef<HTMLCanvasElement>(null);\n  const shaderRef = useRef<ReturnType<typeof createShader> | null>(null);\n  const sweepingRef = useRef(false);\n\n  /* hand control to the user: stop the demo loop, and when they aim at\n   * the input itself, clear the demo's leftover draft for a clean start */\n  const takeOver = (event: { target: EventTarget | null }) => {\n    setAuto(false);\n    if (auto && event.target === inputRef.current) setDraft(\"\");\n  };\n\n  const token = dismissed ? null : parseToken(draft);\n  const menu: \"at\" | \"slash\" | null = plusOpen ? \"at\" : token?.kind ?? null;\n  const query = plusOpen ? \"\" : token?.query ?? \"\";\n\n  const rows: { key: string; name: string; desc: string }[] =\n    menu === \"at\"\n      ? SOURCES.filter((s) => s.name.toLowerCase().includes(query))\n      : menu === \"slash\"\n        ? COMMANDS.filter((c) => c.name.slice(1).startsWith(query))\n        : [];\n\n  useEffect(() => {\n    setActive(0);\n    setEngaged(false);\n  }, [menu, query]);\n\n  /* a single highlight glides to the active row instead of each row\n   * toggling its own background — matches the gliding pill in the nav */\n  useLayoutEffect(() => {\n    const target = rowRefs.current[active];\n    if (target) setRowBox({ top: target.offsetTop, height: target.offsetHeight });\n  }, [menu, query, active, connected, rows.length]);\n\n  /* same gliding highlight in the model menu — floats to the hovered\n   * row, falling back to the currently-selected model */\n  const modelIndex = MODELS.findIndex((m) => m.key === model.key);\n  useLayoutEffect(() => {\n    if (!modelOpen) return;\n    const target = modelRowRefs.current[modelHovered ?? modelIndex];\n    if (target) setModelBox({ top: target.offsetTop, height: target.offsetHeight });\n  }, [modelOpen, modelHovered, modelIndex]);\n\n  /* The menu is outside the clipped composer, so align it to the model\n   * trigger by measurement instead of pinning it to the far-right edge. */\n  useLayoutEffect(() => {\n    if (!modelOpen || !composerAnchorRef.current || !modelRef.current) return;\n    const anchorRect = composerAnchorRef.current.getBoundingClientRect();\n    const triggerRect = modelRef.current.getBoundingClientRect();\n    setModelMenuLeft(Math.max(0, Math.min(triggerRect.left - anchorRect.left, anchorRect.width - 176)));\n    setModelMenuBottom(anchorRect.bottom - triggerRect.top + 8);\n  }, [modelOpen, wide, model.name]);\n\n  useEffect(() => {\n    if (!modelOpen) setModelHovered(null);\n  }, [modelOpen]);\n\n  /* Build the shader with a pinned hue phase. createShader seeds its\n   * internal hueShift from Math.random(), which made the sweep a different\n   * colour on every reload — pin it so the rainbow is identical each time. */\n  const makeShader = () => {\n    const canvas = glimmRef.current;\n    if (!canvas) return null;\n    const random = Math.random;\n    Math.random = () => 0;\n    try {\n      return createShader({\n        canvas,\n        palette: RAINBOW,\n        direction: \"ltr\",\n        bandTight: 10,\n        swellAmount: 0.85,\n      });\n    } finally {\n      Math.random = random;\n    }\n  };\n\n  /* Glimm shader lives inside the composer, invisible at rest. Selecting\n   * the flagship model fires a one-shot rainbow sweep across the interior. */\n  useEffect(() => {\n    shaderRef.current = makeShader();\n    return () => {\n      shaderRef.current?.destroy();\n      shaderRef.current = null;\n    };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  const celebrate = () => {\n    if (sweepingRef.current) return;\n    if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n    // Recreate the shader per sweep so uTime restarts at 0 — the hue phase\n    // (which drifts with time) is then identical on every trigger.\n    shaderRef.current?.destroy();\n    const shader = makeShader();\n    shaderRef.current = shader;\n    if (!shader) return;\n    sweepingRef.current = true;\n    const sweep = playSweep(shader, {\n      palette: RAINBOW,\n      direction: \"ltr\",\n      sweepMs: 570,\n      outroMs: 80,\n      peakAlpha: 1.3,\n      bandTight: 10,\n      brightness: 1.4,\n      swellAmount: 1,\n      waveSpeed: 1.8,\n      easing: \"easeOutExpo\",\n    });\n    sweep.done.finally(() => {\n      sweepingRef.current = false;\n    });\n  };\n\n  const selectModel = (next: (typeof MODELS)[number]) => {\n    setModel(next);\n    setModelOpen(false);\n    if (next.key === \"reasoning\") celebrate();\n  };\n\n  /* autoplay: apply the current step, then advance after its hold */\n  useEffect(() => {\n    if (!auto) return;\n    const step = AUTO_STEPS[autoStep % AUTO_STEPS.length];\n    setDraft(step.draft);\n    if (step.active !== undefined) setActive(step.active);\n    if (step.connect !== undefined) setConnected(step.connect);\n    if (step.modelOpen !== undefined) setModelOpen(step.modelOpen);\n    if (step.model) {\n      const next = MODELS.find((m) => m.key === step.model);\n      if (next) selectModel(next);\n    }\n    const t = setTimeout(() => setAutoStep((s) => s + 1), step.hold);\n    return () => clearTimeout(t);\n  }, [auto, autoStep]);\n\n  /* dictation resolves after a beat, like a real transcript landing */\n  useEffect(() => {\n    if (!listening) return;\n    const t = setTimeout(() => {\n      setDraft((current) => (current ? `${current.trimEnd()} ${DICTATION}` : DICTATION));\n      setListening(false);\n      inputRef.current?.focus();\n    }, 2200);\n    return () => clearTimeout(t);\n  }, [listening]);\n\n  /* Move wrapped text above the controls, then grow to a compact maximum. */\n  useLayoutEffect(() => {\n    const input = inputRef.current;\n    const controls = controlsRef.current;\n    const measure = measureRef.current;\n    const modelButton = modelRef.current;\n    if (!input || !controls || !measure || !modelButton) return;\n\n    const fixedControlsWidth = 28 * 3 + modelButton.offsetWidth;\n    const inlineGaps = 4 * 4;\n    const inlineInputWidth = controls.clientWidth - fixedControlsWidth - inlineGaps;\n    const needsFullWidth = draft.includes(\"\\n\") || measure.offsetWidth + 8 > inlineInputWidth;\n    if (needsFullWidth !== expanded) {\n      setExpanded(needsFullWidth);\n    }\n\n    const minHeight = 28;\n    const maxHeight = 100;\n    input.style.height = \"0px\";\n    const contentHeight = input.scrollHeight;\n    input.style.height = `${Math.min(Math.max(contentHeight, minHeight), maxHeight)}px`;\n    input.style.overflowY = contentHeight > maxHeight ? \"auto\" : \"hidden\";\n  }, [draft, expanded]);\n\n  /* clicking anywhere outside the composer closes the open menus */\n  useEffect(() => {\n    if (!modelOpen && !plusOpen) return;\n    const close = (event: PointerEvent) => {\n      if (!(event.target as Element).closest(\"[data-promptbar]\")) {\n        setModelOpen(false);\n        setPlusOpen(false);\n      }\n    };\n    document.addEventListener(\"pointerdown\", close);\n    return () => document.removeEventListener(\"pointerdown\", close);\n  }, [modelOpen, plusOpen]);\n\n  const closeMenus = () => {\n    setPlusOpen(false);\n    setModelOpen(false);\n  };\n\n  const pick = (row: { key: string; name: string }) => {\n    const source = SOURCES.find((s) => s.key === row.key);\n    if (source?.attach) {\n      setAttachments((current) => [...current, FILES[current.length % FILES.length]]);\n      if (token) setDraft(draft.slice(0, token.start));\n    } else if (menu === \"at\") {\n      setDraft(`${token ? draft.slice(0, token.start) : draft}@${row.name} `);\n    } else {\n      setDraft(`${token ? draft.slice(0, token.start) : draft}${row.name} `);\n    }\n    setPlusOpen(false);\n    setDismissed(false);\n    inputRef.current?.focus();\n  };\n\n  const canSend = draft.trim().length > 0 || attachments.length > 0;\n  const send = () => {\n    if (!canSend) return;\n    onSend?.(draft.trim());\n    setDraft(\"\");\n    setAttachments([]);\n    closeMenus();\n  };\n\n  return (\n    <div\n      data-promptbar\n      className={demo ? \"flex min-h-[384px] w-full max-w-105 flex-col justify-end pb-8\" : \"w-full\"}\n      onPointerDownCapture={takeOver}\n      onKeyDownCapture={takeOver}\n    >\n      {/* composer is the anchor — menus grow up from its top edge */}\n      <div ref={composerAnchorRef} className=\"relative\">\n      {/* ── @ / slash menu ─────────────────────────────── */}\n      {menu && (\n        <div\n          onMouseLeave={() => setEngaged(false)}\n          className=\"absolute inset-x-0 bottom-full z-10 mb-2 rounded-[10px] bg-surface p-1 shadow-raised\"\n          style={{ animation: \"beautiful-pop-in 180ms cubic-bezier(0.23,1,0.32,1) both\", transformOrigin: \"bottom center\" }}\n        >\n          {/* single gliding highlight — appears once a row is hovered */}\n          <span\n            aria-hidden\n            className=\"pointer-events-none absolute inset-x-1 rounded-[6px] bg-hover\"\n            style={{\n              top: rowBox?.top ?? 0,\n              height: rowBox?.height ?? 0,\n              opacity: rowBox && engaged && rows.length > 0 ? 1 : 0,\n              transition:\n                \"top 220ms cubic-bezier(0.23,1,0.32,1), height 220ms cubic-bezier(0.23,1,0.32,1), opacity 150ms ease\",\n            }}\n          />\n          {rows.map((row, i) => {\n            const source = menu === \"at\" ? SOURCES.find((s) => s.key === row.key) : undefined;\n            return (\n              <button\n                key={row.key}\n                type=\"button\"\n                ref={(el) => {\n                  rowRefs.current[i] = el;\n                }}\n                onMouseDown={(event) => event.preventDefault()}\n                onMouseEnter={() => {\n                  setActive(i);\n                  setEngaged(true);\n                }}\n                onClick={() => pick(row)}\n                className=\"relative z-10 flex h-9 w-full items-center gap-2.5 rounded-[6px] px-2 text-left\"\n              >\n                {source && (\n                  <span className=\"flex size-5.5 shrink-0 items-center justify-center text-ink-2\">\n                    {source.brand ? BRANDS[source.brand] : <Icon size={15}>{GLYPHS[source.glyph ?? \"clip\"]}</Icon>}\n                  </span>\n                )}\n                <span className=\"shrink-0 text-[12.5px] font-medium text-ink\">\n                  {row.name}\n                </span>\n                <span className=\"min-w-0 flex-1 truncate text-[12px] text-ink-3\">{row.desc}</span>\n                {source?.connect && (\n                  <span\n                    role=\"button\"\n                    tabIndex={-1}\n                    onClick={(event) => {\n                      event.stopPropagation();\n                      setConnected((current) => !current);\n                    }}\n                    className={`shrink-0 text-[12px] font-medium transition-colors duration-100 ${\n                      connected ? \"text-green\" : \"text-accent-ink hover:underline\"\n                    }`}\n                  >\n                    {connected ? \"Connected\" : \"Connect\"}\n                  </span>\n                )}\n              </button>\n            );\n          })}\n          {rows.length === 0 && (\n            <div className=\"flex h-9 items-center px-2 text-[12px] text-ink-3\">\n              No matches for “{query}”\n            </div>\n          )}\n          <div className=\"mt-1 border-t border-line px-2 pt-1.5 pb-1 text-[11px] text-ink-3\">\n            {menu === \"at\" ? \"Type to search sources & files\" : \"Type to search commands\"}\n          </div>\n        </div>\n      )}\n\n      {/* ── model menu ─────────────────────────────────── */}\n      {modelOpen && (\n        <div\n          onMouseLeave={() => setModelHovered(null)}\n          className=\"absolute z-10 w-44 rounded-[10px] bg-surface p-1 shadow-raised\"\n          style={{ left: modelMenuLeft, bottom: modelMenuBottom, animation: \"beautiful-pop-in 180ms cubic-bezier(0.23,1,0.32,1) both\", transformOrigin: \"bottom left\" }}\n        >\n          {/* single gliding highlight — floats to the hovered / selected row */}\n          <span\n            aria-hidden\n            className=\"pointer-events-none absolute inset-x-1 rounded-[6px] bg-hover\"\n            style={{\n              top: modelBox?.top ?? 0,\n              height: modelBox?.height ?? 0,\n              opacity: modelBox && modelHovered !== null ? 1 : 0,\n              transition:\n                \"top 220ms cubic-bezier(0.23,1,0.32,1), height 220ms cubic-bezier(0.23,1,0.32,1), opacity 150ms ease\",\n            }}\n          />\n          {MODELS.map((m, i) => (\n            <button\n              key={m.key}\n              type=\"button\"\n              ref={(el) => {\n                modelRowRefs.current[i] = el;\n              }}\n              onMouseDown={(event) => event.preventDefault()}\n              onMouseEnter={() => setModelHovered(i)}\n              onClick={() => {\n                selectModel(m);\n                inputRef.current?.focus();\n              }}\n              className=\"relative z-10 flex h-7.5 w-full items-center gap-2 rounded-[6px] px-2 text-left\"\n            >\n              <span className=\"min-w-0 flex-1 truncate text-[12.5px] font-medium text-ink\">{m.name}</span>\n              <span className=\"shrink-0 text-[11px] text-ink-3\">{m.tag}</span>\n              <span className={`shrink-0 text-ink ${m.key === model.key ? \"\" : \"invisible\"}`}>\n                <Icon size={13} strokeWidth={2.5}><path d=\"M20 6L9 17l-5-5\" /></Icon>\n              </span>\n            </button>\n          ))}\n        </div>\n      )}\n\n      {/* ── composer ───────────────────────────────────── */}\n      <div\n        className={`relative isolate flex flex-col overflow-hidden border border-line bg-surface shadow-card transition-[border-color,border-radius] duration-150 focus-within:border-line-strong ${\n          tall ? \"gap-2.5 p-3.5\" : \"gap-1.5 p-1.5\"\n        } ${\n          pill ? (attachments.length > 0 || wide ? \"rounded-[24px]\" : \"rounded-full\") : tall ? \"rounded-[22px]\" : \"rounded-[14px]\"\n        }`}\n      >\n        {/* rainbow glimm sweep — plays across the interior on model change.\n            explicit w/h: a <canvas> is a replaced element and won't stretch\n            to inset-0 alone, which feeds back into the shader's ResizeObserver. */}\n        <canvas\n          ref={glimmRef}\n          aria-hidden=\"true\"\n          className=\"pointer-events-none absolute inset-0 -z-10 h-full w-full\"\n          style={{ borderRadius: \"inherit\" }}\n        />\n        <span\n          ref={measureRef}\n          aria-hidden=\"true\"\n          className=\"pointer-events-none absolute invisible whitespace-pre text-[13px] leading-[18px]\"\n        >\n          {draft}\n        </span>\n\n        {attachments.length > 0 && (\n          <div className={`flex flex-wrap gap-1.5 pt-0.5 ${pill ? \"px-1\" : \"px-0.5\"}`}>\n            {attachments.map((file, i) => (\n              <span\n                key={`${file}-${i}`}\n                className={`flex h-6.5 items-center gap-1.5 bg-field py-1 pr-1 pl-1.5 text-[11.5px] text-ink-2 shadow-hairline ${\n                  pill ? \"rounded-full\" : \"rounded-chip\"\n                }`}\n                style={{ animation: \"beautiful-pop-in 200ms cubic-bezier(0.23,1,0.32,1) both\" }}\n              >\n                <Icon size={12}><g><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" /><path d=\"M14 2v6h6\" /></g></Icon>\n                <span className=\"max-w-36 truncate\">{file}</span>\n                <button\n                  type=\"button\"\n                  aria-label={`Remove ${file}`}\n                  onClick={() => setAttachments((current) => current.filter((_, j) => j !== i))}\n                  className={`-my-1 flex size-6 items-center justify-center text-ink-3 transition-colors duration-100 hover:bg-line/70 hover:text-ink ${\n                    pill ? \"rounded-full\" : \"rounded-[5px]\"\n                  }`}\n                >\n                  <Icon size={10} strokeWidth={2.5}><path d=\"M18 6L6 18M6 6l12 12\" /></Icon>\n                </button>\n              </span>\n            ))}\n          </div>\n        )}\n\n        <div\n          ref={controlsRef}\n          className={`grid items-end gap-x-1 gap-y-1.5 ${\n            wide\n              ? \"grid-cols-[28px_auto_minmax(0,1fr)_28px_28px]\"\n              : \"grid-cols-[28px_minmax(0,1fr)_auto_28px_28px]\"\n          } max-[420px]:grid-cols-[28px_auto_minmax(0,1fr)_28px_28px]`}\n        >\n          <button\n            type=\"button\"\n            aria-label=\"Add attachments and sources\"\n            aria-expanded={plusOpen}\n            onClick={() => {\n              setModelOpen(false);\n              setPlusOpen((current) => !current);\n              inputRef.current?.focus();\n            }}\n            className={`flex size-7 shrink-0 items-center justify-center justify-self-start text-ink-3 transition-[background-color,color,transform] duration-150 hover:bg-hover hover:text-ink active:scale-[0.94] ${\n              pill ? \"rounded-full\" : \"rounded-[8px]\"\n            } ${plusOpen ? \"bg-hover text-ink\" : \"\"} ${wide ? \"col-start-1 row-start-2\" : \"col-start-1 row-start-1\"} max-[420px]:col-start-1 max-[420px]:row-start-2`}\n          >\n            <Icon size={16} strokeWidth={2}><path d=\"M12 5v14M5 12h14\" /></Icon>\n          </button>\n\n          <textarea\n            ref={inputRef}\n            rows={1}\n            value={draft}\n            onChange={(event) => {\n              setDraft(event.target.value);\n              setDismissed(false);\n              setPlusOpen(false);\n            }}\n            onKeyDown={(event) => {\n              if (menu && rows.length > 0) {\n                if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n                  event.preventDefault();\n                  setEngaged(true);\n                  setActive((current) => (current + (event.key === \"ArrowDown\" ? 1 : rows.length - 1)) % rows.length);\n                  return;\n                }\n                if ((event.key === \"Enter\" && !event.shiftKey) || event.key === \"Tab\") {\n                  event.preventDefault();\n                  pick(rows[active]);\n                  return;\n                }\n              }\n              if (event.key === \"Escape\") {\n                setDismissed(true);\n                closeMenus();\n                return;\n              }\n              if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n                event.preventDefault();\n                send();\n              }\n            }}\n            placeholder={listening ? \"Listening…\" : placeholder ?? \"Write a message…\"}\n            aria-label=\"Prompt\"\n            className={`${tall ? \"min-h-[68px] px-2 py-2 text-[14px] leading-5\" : \"min-h-7 px-1 py-[5px] text-[13px] leading-[18px]\"} min-w-0 w-full resize-none bg-transparent text-ink outline-none [overflow-wrap:anywhere] placeholder:text-ink-3 ${\n              wide ? \"col-span-full col-start-1 row-start-1\" : \"col-start-2 row-start-1\"\n            } max-[420px]:col-span-full max-[420px]:col-start-1 max-[420px]:row-start-1`}\n          />\n\n          {/* model picker */}\n          <button\n            ref={modelRef}\n            type=\"button\"\n            aria-expanded={modelOpen}\n            aria-label=\"Choose model\"\n            onClick={() => {\n              setPlusOpen(false);\n              setModelOpen((current) => !current);\n            }}\n            className={`flex h-7 shrink-0 items-center gap-1 px-1.5 text-[12px] font-medium text-ink-2 transition-colors duration-150 hover:bg-hover hover:text-ink ${\n              pill ? \"rounded-full\" : \"rounded-[8px]\"\n            } ${wide ? \"col-start-2 row-start-2 justify-self-start\" : \"col-start-3 row-start-1\"} max-[420px]:col-start-2 max-[420px]:row-start-2 max-[420px]:justify-self-start`}\n          >\n            {model.name}\n            <span className=\"text-ink-3\">\n              <Icon size={11} strokeWidth={2.4}><path d=\"M6 9l6 6 6-6\" /></Icon>\n            </span>\n          </button>\n\n          {/* dictation */}\n          <button\n            type=\"button\"\n            aria-label={listening ? \"Stop dictation\" : \"Start dictation\"}\n            aria-pressed={listening}\n            onClick={() => setListening((current) => !current)}\n            className={`flex size-7 shrink-0 items-center justify-center transition-[background-color,color,transform] duration-150 active:scale-[0.94] ${\n              pill ? \"rounded-full\" : \"rounded-[8px]\"\n            } ${listening ? \"bg-accent-tint text-accent-ink\" : \"text-ink-3 hover:bg-hover hover:text-ink\"} ${wide ? \"col-start-4 row-start-2\" : \"col-start-4 row-start-1\"} max-[420px]:col-start-4 max-[420px]:row-start-2`}\n          >\n            {listening ? (\n              <span className=\"flex h-3.5 items-center gap-[2.5px]\">\n                {[0, 1, 2].map((i) => (\n                  <span\n                    key={i}\n                    className=\"w-[2.5px] rounded-full bg-current\"\n                    style={{ height: \"100%\", animation: `beautiful-eq-bounce 900ms ease-in-out ${i * 150}ms infinite` }}\n                  />\n                ))}\n              </span>\n            ) : (\n              <Icon size={15} strokeWidth={2}><g><path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z\" /><path d=\"M19 10v2a7 7 0 0 1-14 0v-2M12 19v3\" /></g></Icon>\n            )}\n          </button>\n\n          {/* send — tactile square (round in the pill variant) */}\n          <button\n            type=\"button\"\n            aria-label=\"Send\"\n            disabled={!canSend}\n            onClick={send}\n            className={`flex size-7 shrink-0 items-center justify-center transition-[background-color,color,transform] duration-200 enabled:active:scale-[0.94] ${\n              pill ? \"rounded-full\" : \"rounded-[8px]\"\n            } ${wide ? \"col-start-5 row-start-2\" : \"col-start-5 row-start-1\"} max-[420px]:col-start-5 max-[420px]:row-start-2`}\n            style={{\n              background: canSend ? \"var(--ink)\" : \"var(--line-strong)\",\n              color: canSend ? \"var(--surface)\" : \"var(--ink-2)\",\n            }}\n          >\n            <Icon size={16} strokeWidth={2.4}><path d=\"M12 19V5M5 12l7-7 7 7\" /></Icon>\n          </button>\n        </div>\n      </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-recommendation-card",
      "type": "registry:block",
      "title": "Beautiful Original Recommendation Card",
      "description": "Original Beautiful UI RecommendationCard",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/RecommendationCard.tsx",
          "target": "@components/beautiful-ui/original/primitives/RecommendationCard.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport { Button, type ButtonVariant } from \"../atoms/Button\";\nimport { EntityChip } from \"../atoms/EntityChip\";\nimport { ValuePill } from \"../atoms/ValuePill\";\n\n/* ─────────────────────────────────────────────────────────\n * RECOMMENDATION CARD\n * The card holds its shape. Pressing \"Alternatives\" opens a\n * new drawer listing the other options; picking one promotes\n * it to the recommendation. The primary action confirms.\n * ───────────────────────────────────────────────────────── */\n\nexport type RecommendationOption = {\n  key: string;\n  body: React.ReactNode;\n  short: string;\n  signal: number;\n  tone: string;\n  label: string;\n  cta: string;\n  ctaVariant: ButtonVariant;\n};\n\nexport type RecommendationLabels = {\n  title: string;\n  alternatives: string;\n  otherOptions: string;\n  accepted: string;\n};\n\nconst DEFAULT_LABELS: RecommendationLabels = {\n  title: \"Want me to place this restock order?\",\n  alternatives: \"Alternatives\",\n  otherOptions: \"Other options\",\n  accepted: \"Accepted\",\n};\n\nconst OPTIONS: RecommendationOption[] = [\n  {\n    key: \"high\",\n    body: (\n      <>\n        Reorder waffle cones from{\" \"}\n        <EntityChip name=\"Cone King\" />{\" \"}\n        with lead time <ValuePill tone=\"green\">7 days</ValuePill>\n      </>\n    ),\n    short: \"Reorder from Cone King · 7-day lead\",\n    signal: 3,\n    tone: \"var(--green)\",\n    label: \"High confidence\",\n    cta: \"Accept\",\n    ctaVariant: \"accent\",\n  },\n  {\n    key: \"review\",\n    body: (\n      <>\n        Switch vanilla to <ValuePill>Vanilla Madagascar</ValuePill> for peak season.\n      </>\n    ),\n    short: \"Switch to Vanilla Madagascar\",\n    signal: 2,\n    tone: \"var(--orange)\",\n    label: \"Needs review\",\n    cta: \"Configure\",\n    ctaVariant: \"primary\",\n  },\n  {\n    key: \"none\",\n    body: (\n      <>\n        Fall back to a <span className=\"font-medium text-ink\">full restock</span> across every SKU.\n      </>\n    ),\n    short: \"Full restock across every SKU\",\n    signal: 0,\n    tone: \"var(--ink-3)\",\n    label: \"No signal\",\n    cta: \"Accept full restock\",\n    ctaVariant: \"primary\",\n  },\n];\n\nfunction Meter({ signal, tone }: { signal: number; tone: string }) {\n  return (\n    <span className=\"flex items-end gap-0.5\">\n      {[0, 1, 2].map((bar) => (\n        <span\n          key={bar}\n          className=\"w-1 rounded-full transition-colors duration-300\"\n          style={{ height: 10, background: bar < signal ? tone : \"var(--line-strong)\" }}\n        />\n      ))}\n    </span>\n  );\n}\n\nexport default function RecommendationCard({\n  options = OPTIONS,\n  labels,\n}: {\n  options?: RecommendationOption[];\n  labels?: Partial<RecommendationLabels>;\n  variant?: string;\n} = {}) {\n  const t = { ...DEFAULT_LABELS, ...labels };\n  const [selected, setSelected] = useState(0);\n  const [open, setOpen] = useState(false);\n  const [accepted, setAccepted] = useState(false);\n\n  const active = options[selected];\n  const others = options.map((o, i) => ({ o, i })).filter(({ i }) => i !== selected);\n\n  return (\n    <div className=\"w-full max-w-95 overflow-hidden rounded-card bg-surface shadow-card\">\n      <div className=\"primitive-card-pad\">\n        <span className=\"text-[14px] font-medium text-ink\">\n          {t.title}\n        </span>\n        <p\n          key={active.key}\n          className=\"mt-1.5 min-h-12 text-[13px] leading-relaxed text-ink-2\"\n          style={{ animation: \"beautiful-fade-in 180ms ease-out both\" }}\n        >\n          {active.body}\n        </p>\n      </div>\n\n      {/* alternatives drawer — a distinctly new section of the card */}\n      <div\n        className=\"grid transition-[grid-template-rows,opacity] duration-300\"\n        style={{\n          gridTemplateRows: open ? \"1fr\" : \"0fr\",\n          opacity: open ? 1 : 0,\n          transitionTimingFunction: \"cubic-bezier(0.16, 1, 0.3, 1)\",\n        }}\n      >\n        <div className=\"overflow-hidden\">\n          <div className=\"border-t border-line bg-surface px-2 py-2\">\n            <p className=\"px-1.5 pb-1 text-[11px] font-medium text-ink-3\">\n              {t.otherOptions}\n            </p>\n            {others.map(({ o, i }) => (\n              <button\n                key={o.key}\n                type=\"button\"\n                onClick={() => {\n                  setSelected(i);\n                  setAccepted(false);\n                }}\n                className=\"flex w-full items-center gap-2.5 rounded-control px-1.5 py-1.5\n                  text-left transition-colors duration-100 hover:bg-hover\"\n              >\n                <Meter signal={o.signal} tone={o.tone} />\n                <span className=\"min-w-0 flex-1 truncate text-[12.5px] text-ink\">{o.short}</span>\n                <span className=\"shrink-0 text-[11px] text-ink-3\">{o.label}</span>\n              </button>\n            ))}\n          </div>\n        </div>\n      </div>\n\n      <div className=\"primitive-card-footer flex items-center justify-between gap-3 bg-surface\">\n        <span className=\"flex items-center gap-2\">\n          <Meter signal={active.signal} tone={active.tone} />\n          <span className=\"text-[12.5px] font-medium text-ink-2\">{active.label}</span>\n        </span>\n\n        <span className=\"-mr-0.5 flex items-center gap-2\">\n          <Button\n            variant=\"secondary\"\n            size=\"sm\"\n            aria-expanded={open}\n            onClick={() => setOpen((current) => !current)}\n            className=\"px-2.5 text-[12.5px]\"\n          >\n            {t.alternatives}\n          </Button>\n          <Button\n            variant={accepted ? \"success\" : active.ctaVariant}\n            size=\"sm\"\n            onClick={() => setAccepted(true)}\n            className=\"text-[12.5px]\"\n          >\n            {accepted ? t.accepted : active.cta}\n          </Button>\n        </span>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/Button.tsx",
          "target": "@components/beautiful-ui/original/atoms/Button.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { ButtonHTMLAttributes } from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../utils\";\n\nconst filledShadow = \"shadow-[inset_0_1px_0_rgba(255,255,255,0.14)]\";\n\n/* Pill-shaped by default — the app's core button style. Explicit symmetric\n * padding (not a fixed height) so the top/bottom spacing is always equal. */\nexport const buttonVariants = cva(\n  `inline-flex items-center justify-center font-medium select-none\n   transition-[transform,background-color,opacity] duration-150 ease-out\n   active:scale-[0.96] disabled:opacity-50 disabled:pointer-events-none`,\n  {\n    variants: {\n      variant: {\n        primary: `bg-ink text-canvas hover:opacity-90 dark:bg-ink dark:text-canvas ${filledShadow}`,\n        secondary: \"bg-surface text-ink shadow-btn hover:bg-inset aria-expanded:bg-hover\",\n        ghost: \"bg-hover-2 text-ink hover:bg-line-strong\",\n        accent: `bg-accent text-white hover:bg-accent-ink ${filledShadow}`,\n        success: `bg-green text-white hover:brightness-95 ${filledShadow}`,\n        /* transparent until hovered — for dense toolbars/action rows */\n        quiet: \"text-ink hover:bg-hover\",\n      },\n      size: {\n        /* compact toolbar pill — fixed height, lighter weight */\n        xs: \"h-7 rounded-full px-2.5 text-[12px] font-normal leading-none gap-1\",\n        /* canonical action pill — 27px tall, roomy sides */\n        sm: \"h-[27px] px-3 text-[13px] leading-none rounded-full gap-1.5\",\n        md: \"px-4 py-[9px] text-sm leading-none rounded-full gap-2\",\n      },\n    },\n    defaultVariants: { variant: \"secondary\", size: \"md\" },\n  },\n);\n\nexport type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>[\"variant\"]>;\n\nexport function Button({\n  variant,\n  size,\n  className,\n  ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>) {\n  return <button className={cn(buttonVariants({ variant, size }), className)} {...props} />;\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/utils.ts",
          "target": "@components/beautiful-ui/original/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Merge class names, letting later Tailwind classes win over conflicting earlier ones. */\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/EntityChip.tsx",
          "target": "@components/beautiful-ui/original/atoms/EntityChip.tsx",
          "type": "registry:component",
          "content": "/** Monogram mark — a colored disc with an initial or short glyph.\n *  The shared building block for entity chips and monogram headings. */\nexport function Monogram({\n  children,\n  color = \"#e08a3c\",\n  className = \"\",\n}: {\n  children: React.ReactNode;\n  color?: string;\n  className?: string;\n}) {\n  return (\n    <span\n      className={`flex size-4 shrink-0 items-center justify-center rounded-full\n        text-[9px] font-semibold leading-none text-white ${className}`}\n      style={{ background: color }}\n    >\n      {children}\n    </span>\n  );\n}\n\n/** Inline entity reference — a monogram + name in a soft field pill.\n *  Names a supplier, person, or record inside running text. Softer than a\n *  StatusPill (no dot, no state) and not a mono token (see Chip). */\nexport function EntityChip({\n  name,\n  color,\n  monogram,\n  className = \"\",\n}: {\n  name: string;\n  color?: string;\n  monogram?: React.ReactNode;\n  className?: string;\n}) {\n  return (\n    <span\n      className={`mx-0.5 inline-flex items-center gap-1 rounded-full bg-field\n        py-px pl-[3px] pr-1.5 align-middle shadow-hairline ${className}`}\n    >\n      <Monogram color={color}>{monogram ?? name.charAt(0)}</Monogram>\n      <span className=\"text-[12px] font-medium text-ink\">{name}</span>\n    </span>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/ValuePill.tsx",
          "target": "@components/beautiful-ui/original/atoms/ValuePill.tsx",
          "type": "registry:component",
          "content": "type Tone = \"neutral\" | \"green\" | \"orange\" | \"red\" | \"accent\";\n\nconst TONES: Record<Tone, { cls: string; ring: string }> = {\n  neutral: { cls: \"bg-field text-ink-2\", ring: \"var(--shadow-hairline)\" },\n  green: { cls: \"bg-green-tint text-green\", ring: \"0 0 0 1px color-mix(in oklch, var(--green) 28%, transparent)\" },\n  orange: { cls: \"bg-orange-tint text-orange\", ring: \"0 0 0 1px color-mix(in oklch, var(--orange) 28%, transparent)\" },\n  red: { cls: \"bg-red-tint text-red\", ring: \"0 0 0 1px color-mix(in oklch, var(--red) 28%, transparent)\" },\n  accent: { cls: \"bg-accent-tint text-accent-ink\", ring: \"0 0 0 1px color-mix(in oklch, var(--accent) 28%, transparent)\" },\n};\n\n/** Inline value badge — a plain value (a date, a name, a count) set off in\n *  prose. Softer than a StatusPill (no dot) and not a mono token (see Chip). */\nexport function ValuePill({\n  children,\n  tone = \"neutral\",\n  className = \"\",\n}: {\n  children: React.ReactNode;\n  tone?: Tone;\n  className?: string;\n}) {\n  const t = TONES[tone];\n  return (\n    <span\n      className={`mx-0.5 inline-flex items-center rounded-full px-1.5 py-0\n        align-middle text-[12px] font-medium ${t.cls} ${className}`}\n      style={{ boxShadow: t.ring }}\n    >\n      {children}\n    </span>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-records-table",
      "type": "registry:block",
      "title": "Beautiful Original Records Table",
      "description": "Original Beautiful UI RecordsTable",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/RecordsTable.tsx",
          "target": "@components/beautiful-ui/original/primitives/RecordsTable.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport GlideMenu from \"./GlideMenu\";\n\n/* ─────────────────────────────────────────────────────────\n * RECORDS TABLE — an AI spreadsheet grid. Columns are\n * *properties*: click a header to open its configuration\n * popover (type, tool, grounding, inputs, prompt, run), add\n * a new AI property from the + header, and watch cells\n * resolve row-by-row while it calculates.\n * ───────────────────────────────────────────────────────── */\n\ntype Strength = \"strong\" | \"weak\" | \"veryweak\" | \"none\";\ntype SortKey = \"name\" | \"last\" | \"strength\";\ntype ColumnKey = \"company\" | \"categories\" | \"last\" | \"strength\" | \"links\" | \"ai\";\n\nconst DEFAULT_COLUMN_WIDTHS: Record<ColumnKey, number> = {\n  company: 270,\n  categories: 275,\n  last: 190,\n  strength: 210,\n  links: 175,\n  ai: 240,\n};\n\nconst STRENGTH: Record<Strength, { label: string; color: string; rank: number }> = {\n  strong: { label: \"Very strong\", color: \"var(--green)\", rank: 3 },\n  weak: { label: \"Weak\", color: \"var(--orange)\", rank: 2 },\n  veryweak: { label: \"Very weak\", color: \"var(--red)\", rank: 1 },\n  none: { label: \"No communication\", color: \"var(--ink-3)\", rank: 0 },\n};\n\n// A single mid-lightness base hue per tag. Background, text, and border are\n// derived from this via color-mix() against the theme tokens in .records-tag,\n// so the chips adapt to light and dark automatically (same pattern as FilterTable).\ntype TagColor = { base: string };\n\nconst TAG_PALETTE: Record<string, TagColor> = {\n  amber: { base: \"oklch(0.76 0.13 70)\" },\n  lime: { base: \"oklch(0.77 0.16 122)\" },\n  yellow: { base: \"oklch(0.80 0.15 101)\" },\n  purple: { base: \"oklch(0.62 0.18 293)\" },\n  orange: { base: \"oklch(0.71 0.16 48)\" },\n  cyan: { base: \"oklch(0.72 0.10 221)\" },\n  red: { base: \"oklch(0.64 0.19 27)\" },\n  magenta: { base: \"oklch(0.66 0.21 323)\" },\n  green: { base: \"oklch(0.70 0.13 162)\" },\n  pink: { base: \"oklch(0.67 0.19 3)\" },\n};\n\nconst TAG_COLORS: Record<string, TagColor> = {\n  B2B: TAG_PALETTE.amber,\n  B2C: TAG_PALETTE.lime,\n  Cafe: TAG_PALETTE.red,\n  Catering: TAG_PALETTE.magenta,\n  \"Dairy-free\": TAG_PALETTE.cyan,\n  Gelato: TAG_PALETTE.purple,\n  Imports: TAG_PALETTE.orange,\n  Local: TAG_PALETTE.green,\n  Seasonal: TAG_PALETTE.yellow,\n  Sorbet: TAG_PALETTE.pink,\n  Vegan: TAG_PALETTE.lime,\n  Wholesale: TAG_PALETTE.amber,\n};\n\nexport type RecordRow = {\n  id: string;\n  name: string;\n  tags: string[];\n  last: string;\n  strength: Strength;\n  website?: string;\n};\n\nconst INITIAL_ROWS: RecordRow[] = [\n  { id: \"aurora\", name: \"Aurora Scoops — Reykjavík\", tags: [\"Gelato\", \"Seasonal\"], last: \"9 days ago\", strength: \"strong\", website: \"aurora-scoops.example.com\" },\n  { id: \"kumo\", name: \"Kumo Creamery — Tokyo\", tags: [\"B2C\", \"Cafe\", \"Vegan\"], last: \"3 weeks ago\", strength: \"strong\", website: \"kumo-creamery.example.com\" },\n  { id: \"sol-nieve\", name: \"Sol y Nieve — Buenos Aires\", tags: [\"Gelato\", \"Local\"], last: \"2 months ago\", strength: \"weak\", website: \"sol-y-nieve.example.com\" },\n  { id: \"maple-orbit\", name: \"Maple Orbit — Montréal\", tags: [\"B2B\", \"Wholesale\", \"Seasonal\"], last: \"15 days ago\", strength: \"weak\", website: \"maple-orbit.example.com\" },\n  { id: \"blue-fig\", name: \"Blue Fig Gelato — Florence\", tags: [\"Gelato\", \"Cafe\"], last: \"over 1 year ago\", strength: \"veryweak\", website: \"blue-fig.example.com\" },\n  { id: \"sahara-swirl\", name: \"Sahara Swirl — Marrakech\", tags: [\"Sorbet\", \"Local\"], last: \"5 months ago\", strength: \"veryweak\" },\n  { id: \"cloudberry\", name: \"Cloudberry Cone — Helsinki\", tags: [\"Dairy-free\", \"Seasonal\"], last: \"No contact\", strength: \"none\", website: \"cloudberry-cone.example.com\" },\n  { id: \"palm-sugar\", name: \"Palm Sugar Creamery — Bangkok\", tags: [\"B2C\", \"Vegan\"], last: \"3 months ago\", strength: \"veryweak\", website: \"palm-sugar.example.com\" },\n  { id: \"cape-vanilla\", name: \"Cape Vanilla Co. — Cape Town\", tags: [\"Wholesale\", \"Imports\"], last: \"over 1 year ago\", strength: \"veryweak\", website: \"cape-vanilla.example.com\" },\n  { id: \"andes-snow\", name: \"Andes Snow Creamery — Quito\", tags: [\"Gelato\", \"Catering\"], last: \"almost 2 years ago\", strength: \"veryweak\" },\n  { id: \"tasman-sea\", name: \"Tasman Sea Gelato — Hobart\", tags: [\"Gelato\", \"Local\"], last: \"2 months ago\", strength: \"weak\", website: \"tasman-sea.example.com\" },\n  { id: \"silk-road\", name: \"Silk Road Sorbet — Tbilisi\", tags: [\"Sorbet\", \"Imports\"], last: \"about 1 month ago\", strength: \"weak\", website: \"silk-road.example.com\" },\n  { id: \"rosewater\", name: \"Rosewater Kulfi — Jaipur\", tags: [\"B2C\", \"Seasonal\"], last: \"2 months ago\", strength: \"veryweak\" },\n  { id: \"lumen\", name: \"Lumen Soft Serve — Copenhagen\", tags: [\"Dairy-free\", \"Cafe\"], last: \"8 months ago\", strength: \"weak\", website: \"lumen-soft-serve.example.com\" },\n  { id: \"cacao-norte\", name: \"Cacao Norte — Oaxaca\", tags: [\"B2B\", \"Local\", \"Wholesale\"], last: \"about 2 years ago\", strength: \"none\", website: \"cacao-norte.example.com\" },\n  { id: \"pine-pistachio\", name: \"Pine & Pistachio — Istanbul\", tags: [\"Gelato\", \"Catering\"], last: \"about 1 month ago\", strength: \"veryweak\" },\n  { id: \"ember-cone\", name: \"Ember Cone Company — Seoul\", tags: [\"B2C\", \"Vegan\"], last: \"15 days ago\", strength: \"weak\", website: \"ember-cone.example.com\" },\n  { id: \"coral-coast\", name: \"Coral Coast Sorbet — Honolulu\", tags: [\"Sorbet\", \"Local\"], last: \"9 days ago\", strength: \"strong\", website: \"coral-coast.example.com\" },\n  { id: \"sunbird\", name: \"Sunbird Gelateria — Lisbon\", tags: [\"Gelato\", \"Cafe\"], last: \"over 2 years ago\", strength: \"none\", website: \"sunbird.example.com\" },\n  { id: \"mooncake\", name: \"Mooncake Ice Cream — Singapore\", tags: [\"B2B\", \"Wholesale\"], last: \"about 1 month ago\", strength: \"veryweak\", website: \"mooncake-ice-cream.example.com\" },\n  { id: \"juniper\", name: \"Juniper & Cream — Vancouver\", tags: [\"Dairy-free\", \"Catering\"], last: \"No contact\", strength: \"none\" },\n  { id: \"mango-moon\", name: \"Mango Moon Gelato — Nairobi\", tags: [\"Sorbet\", \"Vegan\"], last: \"almost 2 years ago\", strength: \"veryweak\", website: \"mango-moon.example.com\" },\n  { id: \"fjord-fizz\", name: \"Fjord Fizz Ice — Oslo\", tags: [\"Dairy-free\", \"Seasonal\"], last: \"No contact\", strength: \"none\" },\n  { id: \"pampa\", name: \"Pampa Creamery — Córdoba\", tags: [\"B2C\", \"Local\"], last: \"12 months ago\", strength: \"veryweak\", website: \"pampa-creamery.example.com\" },\n  { id: \"lotus-leaf\", name: \"Lotus Leaf Scoops — Hanoi\", tags: [\"Vegan\", \"Cafe\"], last: \"15 days ago\", strength: \"weak\" },\n  { id: \"saffron-sky\", name: \"Saffron Sky Kulfi — Dubai\", tags: [\"Imports\", \"Catering\"], last: \"almost 2 years ago\", strength: \"veryweak\", website: \"saffron-sky.example.com\" },\n  { id: \"alpine-churn\", name: \"Alpine Churn — Zürich\", tags: [\"B2B\", \"Gelato\", \"Wholesale\"], last: \"4 days ago\", strength: \"strong\", website: \"alpine-churn.example.com\" },\n  { id: \"monsoon-mango\", name: \"Monsoon Mango — Mumbai\", tags: [\"Sorbet\", \"Vegan\", \"Catering\"], last: \"18 days ago\", strength: \"weak\", website: \"monsoon-mango.example.com\" },\n  { id: \"cedar-spoon\", name: \"Cedar Spoon — Beirut\", tags: [\"Cafe\", \"Local\", \"Seasonal\"], last: \"6 days ago\", strength: \"strong\", website: \"cedar-spoon.example.com\" },\n  { id: \"baltic-berry\", name: \"Baltic Berry — Tallinn\", tags: [\"Dairy-free\", \"Seasonal\", \"B2C\"], last: \"5 weeks ago\", strength: \"weak\", website: \"baltic-berry.example.com\" },\n  { id: \"delta-dairy\", name: \"Delta Dairy Works — New Orleans\", tags: [\"B2B\", \"Wholesale\", \"Local\"], last: \"2 days ago\", strength: \"strong\", website: \"delta-dairy.example.com\" },\n  { id: \"yuzu-yard\", name: \"Yuzu Yard — Kyoto\", tags: [\"Sorbet\", \"Cafe\", \"Seasonal\"], last: \"11 days ago\", strength: \"strong\", website: \"yuzu-yard.example.com\" },\n  { id: \"copper-cone\", name: \"Copper Cone — Melbourne\", tags: [\"Gelato\", \"Cafe\", \"B2C\"], last: \"about 1 month ago\", strength: \"weak\", website: \"copper-cone.example.com\" },\n  { id: \"mint-medina\", name: \"Mint Medina — Tunis\", tags: [\"Dairy-free\", \"Vegan\", \"Local\"], last: \"No contact\", strength: \"none\" },\n  { id: \"glacier-grove\", name: \"Glacier Grove — Anchorage\", tags: [\"Seasonal\", \"Local\", \"Catering\"], last: \"7 weeks ago\", strength: \"weak\", website: \"glacier-grove.example.com\" },\n  { id: \"orchard-cloud\", name: \"Orchard Cloud — Lyon\", tags: [\"Gelato\", \"Seasonal\", \"Cafe\"], last: \"5 days ago\", strength: \"strong\", website: \"orchard-cloud.example.com\" },\n  { id: \"tamarind-tide\", name: \"Tamarind Tide — Chennai\", tags: [\"Vegan\", \"Sorbet\", \"B2C\"], last: \"9 months ago\", strength: \"veryweak\", website: \"tamarind-tide.example.com\" },\n  { id: \"amber-scoop\", name: \"Amber Scoop — Prague\", tags: [\"Gelato\", \"B2B\"], last: \"over 1 year ago\", strength: \"none\" },\n  { id: \"boreal-batch\", name: \"Boreal Batch — Yellowknife\", tags: [\"Dairy-free\", \"Local\", \"Seasonal\"], last: \"8 days ago\", strength: \"strong\", website: \"boreal-batch.example.com\" },\n  { id: \"coconut-commons\", name: \"Coconut Commons — Manila\", tags: [\"Vegan\", \"B2C\", \"Cafe\"], last: \"24 days ago\", strength: \"weak\", website: \"coconut-commons.example.com\" },\n  { id: \"dolomite-dairy\", name: \"Dolomite Dairy — Bolzano\", tags: [\"Gelato\", \"Wholesale\"], last: \"3 days ago\", strength: \"strong\", website: \"dolomite-dairy.example.com\" },\n  { id: \"equator-cream\", name: \"Equator Cream — Kampala\", tags: [\"B2B\", \"Catering\", \"Local\"], last: \"10 months ago\", strength: \"veryweak\", website: \"equator-cream.example.com\" },\n  { id: \"hibiscus-house\", name: \"Hibiscus House — Accra\", tags: [\"Sorbet\", \"Cafe\"], last: \"6 weeks ago\", strength: \"weak\", website: \"hibiscus-house.example.com\" },\n  { id: \"lagoon-ladle\", name: \"Lagoon Ladle — Venice\", tags: [\"Gelato\", \"Seasonal\", \"Catering\"], last: \"7 days ago\", strength: \"strong\", website: \"lagoon-ladle.example.com\" },\n  { id: \"midnight-milk\", name: \"Midnight Milk — Tromsø\", tags: [\"Dairy-free\", \"Vegan\", \"Wholesale\"], last: \"No contact\", strength: \"none\" },\n  { id: \"nomad-nougat\", name: \"Nomad Nougat — Ulaanbaatar\", tags: [\"Imports\", \"B2B\"], last: \"almost 2 years ago\", strength: \"none\", website: \"nomad-nougat.example.com\" },\n  { id: \"olive-snow\", name: \"Olive Snow — Athens\", tags: [\"Gelato\", \"Cafe\", \"Local\"], last: \"4 days ago\", strength: \"strong\", website: \"olive-snow.example.com\" },\n  { id: \"pacific-pear\", name: \"Pacific Pear — Valparaíso\", tags: [\"Sorbet\", \"Seasonal\"], last: \"2 months ago\", strength: \"weak\", website: \"pacific-pear.example.com\" },\n  { id: \"quartz-cone\", name: \"Quartz Cone — Denver\", tags: [\"B2C\", \"Wholesale\"], last: \"10 days ago\", strength: \"strong\", website: \"quartz-cone.example.com\" },\n  { id: \"red-lantern\", name: \"Red Lantern Creamery — Taipei\", tags: [\"Cafe\", \"Vegan\"], last: \"about 1 month ago\", strength: \"weak\", website: \"red-lantern.example.com\" },\n  { id: \"salt-silk\", name: \"Salt & Silk — Muscat\", tags: [\"Imports\", \"Catering\", \"Gelato\"], last: \"8 months ago\", strength: \"veryweak\", website: \"salt-and-silk.example.com\" },\n  { id: \"tropic-churn\", name: \"Tropic Churn — San Juan\", tags: [\"Sorbet\", \"Local\", \"B2C\"], last: \"6 days ago\", strength: \"strong\", website: \"tropic-churn.example.com\" },\n  { id: \"umber-cream\", name: \"Umber Cream — Warsaw\", tags: [\"B2B\", \"Wholesale\", \"Cafe\"], last: \"5 weeks ago\", strength: \"weak\", website: \"umber-cream.example.com\" },\n  { id: \"vanilla-vale\", name: \"Vanilla Vale — Antananarivo\", tags: [\"Imports\", \"Local\"], last: \"No contact\", strength: \"none\" },\n  { id: \"willow-whip\", name: \"Willow Whip — Portland\", tags: [\"Dairy-free\", \"Vegan\", \"Cafe\"], last: \"3 days ago\", strength: \"strong\", website: \"willow-whip.example.com\" },\n  { id: \"zenith-gelato\", name: \"Zenith Gelato — Auckland\", tags: [\"Gelato\", \"Seasonal\"], last: \"3 weeks ago\", strength: \"weak\", website: \"zenith-gelato.example.com\" },\n  { id: \"apricot-atlas\", name: \"Apricot Atlas — Algiers\", tags: [\"Sorbet\", \"Imports\"], last: \"11 months ago\", strength: \"veryweak\", website: \"apricot-atlas.example.com\" },\n  { id: \"black-sesame\", name: \"Black Sesame Social — Bandung\", tags: [\"Vegan\", \"Cafe\", \"B2C\"], last: \"9 days ago\", strength: \"strong\", website: \"black-sesame.example.com\" },\n  { id: \"crimson-clover\", name: \"Crimson Clover — Brussels\", tags: [\"Gelato\", \"Wholesale\", \"Catering\"], last: \"2 months ago\", strength: \"weak\", website: \"crimson-clover.example.com\" },\n  { id: \"dragonfruit-dock\", name: \"Dragonfruit Dock — Shenzhen\", tags: [\"Sorbet\", \"B2B\", \"Wholesale\"], last: \"No contact\", strength: \"none\" },\n];\n\n/* the AI column resolves to related account signals */\nconst AI_LABEL = \"Next action\";\nconst COMPETITOR_POOL = [\n  \"Executive outreach\",\n  \"Refresh owner note\",\n  \"Confirm renewal date\",\n  \"Review usage decline\",\n  \"Schedule follow-up\",\n  \"Verify sponsor\",\n  \"Prepare briefing\",\n  \"Monitor account\",\n];\nconst competitorsFor = (index: number) => `${COMPETITOR_POOL[index % 8]}, ${COMPETITOR_POOL[(index + 3) % 8]}`;\n\nfunction Icon({ children, size = 14, strokeWidth = 1.8 }: { children: React.ReactNode; size?: number; strokeWidth?: number }) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n      {children}\n    </svg>\n  );\n}\n\n/* glyph library for property types & tools */\nconst TYPE_GLYPHS: Record<string, React.ReactNode> = {\n  Text: <path d=\"M4 6h16M4 12h10M4 18h7\" />,\n  File: <g><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" /><path d=\"M14 2v6h6\" /></g>,\n  Collection: <g><ellipse cx=\"12\" cy=\"5\" rx=\"8\" ry=\"3\" /><path d=\"M4 5v14c0 1.66 3.58 3 8 3s8-1.34 8-3V5M4 12c0 1.66 3.58 3 8 3s8-1.34 8-3\" /></g>,\n  \"Single select\": <g><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"m8.5 12 2.4 2.4 4.6-4.9\" /></g>,\n  \"Multi select\": <g><path d=\"M11 6h9M11 12h9M11 18h9\" /><path d=\"M4 6l1.5 1.5L8 5M4 12l1.5 1.5L8 11M4 18l1.5 1.5L8 17\" /></g>,\n  URL: <g><path d=\"M10 13a5 5 0 0 0 7.1.1l2-2a5 5 0 0 0-7.1-7.1l-1.1 1.1\" /><path d=\"M14 11a5 5 0 0 0-7.1-.1l-2 2A5 5 0 0 0 12 20l1.1-1.1\" /></g>,\n  Reference: <path d=\"M7 17 17 7M9 7h8v8\" />,\n  JSON: <g><path d=\"M8 4c-2 0-2 2-2 3s.5 3-2 3c2.5 0 2 2 2 3s0 3 2 3\" /><path d=\"M16 4c2 0 2 2 2 3s-.5 3 2 3c-2.5 0-2 2-2 3s0 3-2 3\" /></g>,\n  \"File splitter\": <g><rect x=\"8\" y=\"8\" width=\"12\" height=\"12\" rx=\"2\" /><path d=\"M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2\" /></g>,\n  Date: <g><rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2.5\" /><path d=\"M8 3v4M16 3v4M3 10h18\" /></g>,\n};\n\nconst TOOL_GLYPHS: Record<string, React.ReactNode> = {\n  model: <path d=\"M12 3l1.7 5.1a2 2 0 0 0 1.2 1.2L20 11l-5.1 1.7a2 2 0 0 0-1.2 1.2L12 19l-1.7-5.1a2 2 0 0 0-1.2-1.2L4 11l5.1-1.7a2 2 0 0 0 1.2-1.2z\" />,\n  web: <g><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M3 12h18M12 3a13.5 13.5 0 0 1 3.5 9 13.5 13.5 0 0 1-3.5 9 13.5 13.5 0 0 1-3.5-9A13.5 13.5 0 0 1 12 3z\" /></g>,\n  user: <g><circle cx=\"12\" cy=\"8\" r=\"4\" /><path d=\"M4 21v-1a6 6 0 0 1 6-6h4a6 6 0 0 1 6 6v1\" /></g>,\n};\n\n/* per-property configuration shown in the popover */\ntype Prompt = { before: string; chip?: string; after?: string };\ntype ToolKind = \"model\" | \"web\" | \"user\";\ntype ColumnMeta = { type: string; tool: string; toolKind: ToolKind; inputs?: string; prompt?: Prompt };\n\nconst COLUMN_META: Record<string, ColumnMeta> = {\n  Company: { type: \"Text\", tool: \"User input\", toolKind: \"user\" },\n  Categories: { type: \"Multi select\", tool: \"Reasoning\", toolKind: \"model\", inputs: \"Company\", prompt: { before: \"Tag each \", chip: \"Company\", after: \" with its market categories.\" } },\n  \"Last interaction\": { type: \"Date\", tool: \"User input\", toolKind: \"user\" },\n  \"Connection strength\": { type: \"Single select\", tool: \"Reasoning\", toolKind: \"model\", inputs: \"Last interaction\", prompt: { before: \"Score the relationship from \", chip: \"Last interaction\", after: \".\" } },\n  Links: { type: \"URL\", tool: \"Web search\", toolKind: \"web\", inputs: \"Company\", prompt: { before: \"Find the website for \", chip: \"Company\", after: \".\" } },\n  [AI_LABEL]: { type: \"Text\", tool: \"Reasoning\", toolKind: \"model\", inputs: \"Company\", prompt: { before: \"Recommend the next action for \", chip: \"Company\" } },\n};\n\nconst NEW_PROPERTY_TYPES = [\"Text\", \"File\", \"Collection\", \"Single select\", \"Multi select\", \"URL\", \"Reference\", \"JSON\", \"File splitter\"];\nconst MODEL_OPTIONS = [\"Reasoning\", \"Balanced\", \"Fast\"];\nconst INPUT_OPTIONS = [\"Company\", \"Categories\", \"Last interaction\", \"Connection strength\", \"Links\"];\n\nfunction Checkbox({ checked, mixed = false, onChange, label }: { checked: boolean; mixed?: boolean; onChange: () => void; label: string }) {\n  return (\n    <label className=\"records-checkbox\" title={label} onClick={(event) => event.stopPropagation()}>\n      <input type=\"checkbox\" checked={checked} onChange={onChange} aria-label={label} />\n      <span className={`records-checkbox-box ${checked || mixed ? \"is-active\" : \"\"}`}>\n        {mixed ? <span className=\"records-checkbox-dash\" /> : checked ? <Icon size={12}><path d=\"m5 12 4 4L19 6\" /></Icon> : null}\n      </span>\n    </label>\n  );\n}\n\nfunction Tag({ name }: { name: string }) {\n  const color = TAG_COLORS[name] ?? { base: \"var(--ink-3)\" };\n  return (\n    <span\n      className=\"records-tag\"\n      style={{ \"--tag-base\": color.base } as React.CSSProperties}\n    >\n      {name}\n    </span>\n  );\n}\n\nfunction TagList({ tags }: { tags: string[] }) {\n  const containerRef = useRef<HTMLDivElement>(null);\n  const measureRef = useRef<HTMLDivElement>(null);\n  const [visibleCount, setVisibleCount] = useState(tags.length);\n\n  useLayoutEffect(() => {\n    const container = containerRef.current;\n    const measure = measureRef.current;\n    if (!container || !measure) return;\n\n    const update = () => {\n      const available = container.clientWidth;\n      const tagWidths = Array.from(measure.querySelectorAll<HTMLElement>(\"[data-tag-measure]\"), (tag) => tag.offsetWidth);\n      const moreWidth = measure.querySelector<HTMLElement>(\"[data-more-measure]\")?.offsetWidth ?? 0;\n      let used = 0;\n      let count = 0;\n\n      for (let index = 0; index < tagWidths.length; index += 1) {\n        const nextUsed = used + (count > 0 ? 4 : 0) + tagWidths[index];\n        const hiddenAfter = tags.length - (index + 1);\n        const totalWithOverflow = nextUsed + (hiddenAfter > 0 ? 4 + moreWidth : 0);\n        if (totalWithOverflow > available) break;\n        used = nextUsed;\n        count += 1;\n      }\n\n      setVisibleCount(count);\n    };\n\n    update();\n    const observer = new ResizeObserver(update);\n    observer.observe(container);\n    return () => observer.disconnect();\n  }, [tags]);\n\n  const hiddenCount = tags.length - visibleCount;\n\n  return (\n    <div ref={containerRef} className=\"records-tags\" title={tags.join(\", \")} aria-label={`Categories: ${tags.join(\", \")}`}>\n      <div ref={measureRef} className=\"records-tags-measure\" aria-hidden>\n        {tags.map((tag) => <span key={tag} data-tag-measure><Tag name={tag} /></span>)}\n        <span data-more-measure className=\"records-more-tag\">+{tags.length}</span>\n      </div>\n      {tags.slice(0, visibleCount).map((tag) => <Tag key={tag} name={tag} />)}\n      {hiddenCount > 0 && <span className=\"records-more-tag\">+{hiddenCount}</span>}\n    </div>\n  );\n}\n\nfunction CalcCell() {\n  return (\n    <span className=\"records-calc\">\n      <span className=\"records-muted\">Calculating…</span>\n      <span className=\"beautiful-records-pulse\" />\n    </span>\n  );\n}\n\nfunction MiniSwitch({ on, onToggle, label }: { on: boolean; onToggle: () => void; label: string }) {\n  return (\n    <button\n      type=\"button\"\n      role=\"switch\"\n      aria-checked={on}\n      aria-label={label}\n      onClick={onToggle}\n      className=\"relative h-4.5 w-7.5 shrink-0 rounded-full transition-colors duration-150\"\n      style={{ background: on ? \"var(--accent)\" : \"var(--line-strong)\" }}\n    >\n      <span\n        className=\"absolute top-0.5 left-0.5 size-3.5 rounded-full bg-white shadow-btn transition-transform duration-150\"\n        style={{ transform: on ? \"translateX(12px)\" : \"translateX(0)\", transitionTimingFunction: \"cubic-bezier(0.23,1,0.32,1)\" }}\n      />\n    </button>\n  );\n}\n\nfunction HeaderCell({ label, icon, sortKey, sort, onSort, onResizeStart, resizing = false, className = \"\", selected = false, onPick }: { label: string; icon: React.ReactNode; sortKey?: SortKey; sort: { key: SortKey; dir: 1 | -1 }; onSort: (key: SortKey) => void; onResizeStart: (event: React.PointerEvent<HTMLSpanElement>) => void; resizing?: boolean; className?: string; selected?: boolean; onPick?: (event: React.MouseEvent) => void }) {\n  return (\n    <th className={`records-header-cell ${selected ? \"is-colsel\" : \"\"} ${className}`}>\n      {/* header click opens the property config; the arrow sorts */}\n      <button type=\"button\" className=\"records-header-button\" onClick={onPick}>\n        <span className=\"records-header-icon\">{icon}</span>\n        <span className=\"truncate\">{label}</span>\n        {sortKey && (\n          <span\n            role=\"button\"\n            tabIndex={0}\n            aria-label={`Sort by ${label}`}\n            onClick={(event) => {\n              event.stopPropagation();\n              onSort(sortKey);\n            }}\n            onKeyDown={(event) => {\n              if (event.key === \"Enter\" || event.key === \" \") {\n                event.preventDefault();\n                event.stopPropagation();\n                onSort(sortKey);\n              }\n            }}\n            className={`records-sort ${sort.key === sortKey ? \"is-visible\" : \"\"}`}\n            style={{ transform: sort.key === sortKey && sort.dir === -1 ? \"rotate(180deg)\" : undefined }}\n          >\n            <Icon size={12}><path d=\"M12 5v14M5 12l7 7 7-7\" /></Icon>\n          </span>\n        )}\n      </button>\n      <span\n        role=\"separator\"\n        aria-orientation=\"vertical\"\n        aria-label={`Resize ${label} column`}\n        className={`records-resize-handle ${resizing ? \"is-resizing\" : \"\"}`}\n        onPointerDown={onResizeStart}\n      />\n    </th>\n  );\n}\n\n/* config row inside the property popover */\nfunction ConfigRow({ label, children }: { label: string; children: React.ReactNode }) {\n  return (\n    <div className=\"relative flex h-8 items-center justify-between\">\n      <span className=\"text-[13px] text-ink-3\">{label}</span>\n      {children}\n    </div>\n  );\n}\n\nfunction ConfigPicker({\n  label,\n  options,\n  selected,\n  onSelect,\n}: {\n  label: string;\n  options: { label: string; icon: React.ReactNode }[];\n  selected: string;\n  onSelect: (value: string) => void;\n}) {\n  return (\n    <div\n      role=\"menu\"\n      aria-label={label}\n      className=\"absolute left-full top-0 z-30 ml-5 w-[210px] rounded-[12px] bg-surface p-1.5 shadow-overlay\"\n      style={{ animation: \"beautiful-pop-in 140ms cubic-bezier(0.23,1,0.32,1) both\", transformOrigin: \"top left\" }}\n    >\n      <div className=\"px-2 pb-1 pt-0.5 text-[11.5px] font-medium text-ink-3\">{label}</div>\n      <GlideMenu className=\"flex flex-col gap-px\">\n        {options.map((option) => (\n          <button\n            key={option.label}\n            data-menu-row\n            type=\"button\"\n            role=\"menuitemradio\"\n            aria-checked={selected === option.label}\n            onClick={() => onSelect(option.label)}\n            className=\"relative z-10 flex h-8 w-full items-center gap-1.5 rounded-[8px] px-1.5 text-left text-[13px] font-medium text-ink\"\n          >\n            <span className=\"flex size-4 shrink-0 items-center justify-center text-ink-2\">{option.icon}</span>\n            <span className=\"min-w-0 flex-1 truncate\">{option.label}</span>\n            <span className={selected === option.label ? \"text-ink\" : \"invisible\"}>\n              <Icon size={14} strokeWidth={2.2}><path d=\"m5 12 4 4L19 6\" /></Icon>\n            </span>\n          </button>\n        ))}\n      </GlideMenu>\n    </div>\n  );\n}\n\nfunction InputPicker({\n  options,\n  selected,\n  onToggle,\n}: {\n  options: string[];\n  selected: string[];\n  onToggle: (value: string) => void;\n}) {\n  return (\n    <div\n      role=\"menu\"\n      aria-label=\"Calculation inputs\"\n      className=\"absolute left-full top-0 z-30 ml-5 w-[220px] rounded-[12px] bg-surface p-1.5 shadow-overlay\"\n      style={{ animation: \"beautiful-pop-in 140ms cubic-bezier(0.23,1,0.32,1) both\", transformOrigin: \"top left\" }}\n    >\n      <div className=\"px-2 pb-1 pt-0.5 text-[11.5px] font-medium text-ink-3\">Use values from</div>\n      <GlideMenu className=\"flex flex-col gap-px\">\n        {options.map((option) => {\n          const checked = selected.includes(option);\n          return (\n            <button\n              key={option}\n              data-menu-row\n              type=\"button\"\n              role=\"menuitemcheckbox\"\n              aria-checked={checked}\n              onClick={() => onToggle(option)}\n              className=\"relative z-10 flex h-8 w-full items-center gap-1.5 rounded-[8px] px-1.5 text-left text-[13px] font-medium text-ink\"\n            >\n              <span className={`flex size-4 shrink-0 items-center justify-center rounded-[5px] border ${checked ? \"border-accent bg-accent text-white\" : \"border-line-strong text-transparent\"}`}>\n                <Icon size={11} strokeWidth={2.4}><path d=\"m5 12 4 4L19 6\" /></Icon>\n              </span>\n              <span className=\"min-w-0 flex-1 truncate\">{option}</span>\n            </button>\n          );\n        })}\n      </GlideMenu>\n    </div>\n  );\n}\n\nexport default function RecordsTable({ rows = INITIAL_ROWS, fill = false }: { rows?: RecordRow[]; fill?: boolean; variant?: string }) {\n  const [selected, setSelected] = useState<Set<string>>(new Set());\n  const [sort, setSort] = useState<{ key: SortKey; dir: 1 | -1 }>({ key: \"name\", dir: 1 });\n  const [columnWidths, setColumnWidths] = useState(DEFAULT_COLUMN_WIDTHS);\n  const [actionColumnWidth, setActionColumnWidth] = useState(100);\n  const [columnWidthsLocked, setColumnWidthsLocked] = useState(false);\n  const [resizingColumn, setResizingColumn] = useState<ColumnKey | null>(null);\n  const initialColumnWidthsRef = useRef<Record<ColumnKey, number> | null>(null);\n  const tableRef = useRef<HTMLTableElement>(null);\n\n  /* property popover, anchored to the clicked header */\n  const [prop, setProp] = useState<{ col: string; x: number; y: number } | null>(null);\n  const [grounding, setGrounding] = useState(false);\n  const [groundingHelpOpen, setGroundingHelpOpen] = useState(false);\n  const [configMenu, setConfigMenu] = useState<\"type\" | \"tool\" | \"inputs\" | null>(null);\n  const [columnOverrides, setColumnOverrides] = useState<Record<string, Partial<ColumnMeta>>>({});\n  const [inputSelections, setInputSelections] = useState<Record<string, string[]>>({});\n  const [pinnedColumns, setPinnedColumns] = useState<Set<string>>(new Set());\n  const [moreSettingsOpen, setMoreSettingsOpen] = useState(false);\n  const [advancedSettings, setAdvancedSettings] = useState({ required: false, allowEmpty: true, confidence: false });\n  /* + new-property menu */\n  const [addOpen, setAddOpen] = useState<{ x: number; y: number } | null>(null);\n  const [tableMenuOpen, setTableMenuOpen] = useState<{ x: number; y: number } | null>(null);\n  /* the added AI column and its lifecycle */\n  const [aiAdded, setAiAdded] = useState(false);\n  const [aiDone, setAiDone] = useState(false);\n  const [pendingOpenAi, setPendingOpenAi] = useState(false);\n  const aiThRef = useRef<HTMLTableCellElement>(null);\n  /* programmatic scrolls (revealing the new column) shouldn't close popovers */\n  const ignoreScrollRef = useRef(false);\n  /* a running calculation resolves rows one by one */\n  const [calc, setCalc] = useState<{ col: string; resolved: number } | null>(null);\n\n  /* Let the table fill its available space once, then capture those rendered\n   * widths before paint. From that point on every column is explicit, so a\n   * resize changes only the dragged column and the table's total width. */\n  useLayoutEffect(() => {\n    if (columnWidthsLocked || !tableRef.current) return;\n    const headers = Array.from(tableRef.current.querySelectorAll<HTMLTableCellElement>(\"thead th\"));\n    if (headers.length < 6) return;\n\n    const measured: Record<ColumnKey, number> = {\n      company: headers[0].getBoundingClientRect().width,\n      categories: headers[1].getBoundingClientRect().width,\n      last: headers[2].getBoundingClientRect().width,\n      strength: headers[3].getBoundingClientRect().width,\n      links: headers[4].getBoundingClientRect().width,\n      ai: DEFAULT_COLUMN_WIDTHS.ai,\n    };\n    initialColumnWidthsRef.current = measured;\n    setColumnWidths(measured);\n    setActionColumnWidth(headers[headers.length - 1].getBoundingClientRect().width);\n    setColumnWidthsLocked(true);\n  }, [columnWidthsLocked]);\n\n  const visibleRows = useMemo(() => {\n    return [...rows].sort((a, b) => {\n      const value = sort.key === \"name\"\n        ? a.name.localeCompare(b.name)\n        : sort.key === \"last\"\n          ? a.last.localeCompare(b.last)\n          : STRENGTH[a.strength].rank - STRENGTH[b.strength].rank;\n      return value * sort.dir;\n    });\n  }, [rows, sort]);\n\n  /* stagger: one row resolves every beat */\n  useEffect(() => {\n    if (!calc) return;\n    if (calc.resolved > visibleRows.length) {\n      if (calc.col === AI_LABEL) setAiDone(true);\n      setCalc(null);\n      return;\n    }\n    const t = setTimeout(() => setCalc((current) => (current ? { ...current, resolved: current.resolved + 1 } : current)), 110);\n    return () => clearTimeout(t);\n  }, [calc, visibleRows.length]);\n\n  /* after adding the AI column, scroll it into view and open its config\n   * anchored to the new header */\n  useEffect(() => {\n    if (!pendingOpenAi || !aiThRef.current) return;\n    const scroller = aiThRef.current.closest(\".records-scroll\");\n    if (scroller) {\n      ignoreScrollRef.current = true;\n      scroller.scrollLeft = scroller.scrollWidth;\n    }\n    const rect = aiThRef.current.getBoundingClientRect();\n    setProp({ col: AI_LABEL, x: Math.min(rect.left, window.innerWidth - 336), y: rect.bottom + 6 });\n    setPendingOpenAi(false);\n  }, [pendingOpenAi, aiAdded]);\n\n  /* click anywhere else closes popovers */\n  useEffect(() => {\n    if (!prop && !addOpen && !tableMenuOpen) return;\n    const close = (event: PointerEvent) => {\n      if (!(event.target as Element).closest(\"[data-recpop]\")) {\n        setProp(null);\n        setConfigMenu(null);\n        setGroundingHelpOpen(false);\n        setMoreSettingsOpen(false);\n        setAddOpen(null);\n        setTableMenuOpen(null);\n      }\n    };\n    document.addEventListener(\"pointerdown\", close);\n    return () => document.removeEventListener(\"pointerdown\", close);\n  }, [prop, addOpen, tableMenuOpen]);\n\n  const openProp = (col: string) => (event: React.MouseEvent) => {\n    const th = (event.currentTarget as Element).closest(\"th\");\n    if (!th) return;\n    setAddOpen(null);\n    setTableMenuOpen(null);\n    setConfigMenu(null);\n    setGroundingHelpOpen(false);\n    setMoreSettingsOpen(false);\n    setProp((current) => {\n      if (current?.col === col) return null;\n      const rect = th.getBoundingClientRect();\n      return { col, x: Math.min(rect.left, window.innerWidth - 336), y: rect.bottom + 6 };\n    });\n  };\n\n  const isCalc = (col: string, index: number) => !!calc && calc.col === col && index >= calc.resolved;\n\n  const allSelected = visibleRows.length > 0 && visibleRows.every((row) => selected.has(row.id));\n  const partiallySelected = !allSelected && visibleRows.some((row) => selected.has(row.id));\n\n  const toggleSort = (key: SortKey) => setSort((current) => current.key === key ? { key, dir: (current.dir * -1) as 1 | -1 } : { key, dir: 1 });\n  const startColumnResize = (key: ColumnKey, minWidth = 120) => (event: React.PointerEvent<HTMLSpanElement>) => {\n    event.preventDefault();\n    event.stopPropagation();\n    setProp(null);\n    setConfigMenu(null);\n    setGroundingHelpOpen(false);\n    setMoreSettingsOpen(false);\n    setAddOpen(null);\n    setTableMenuOpen(null);\n\n    const startX = event.clientX;\n    const startWidth = columnWidths[key];\n    const previousCursor = document.body.style.cursor;\n    const previousSelection = document.body.style.userSelect;\n    document.body.style.cursor = \"col-resize\";\n    document.body.style.userSelect = \"none\";\n    setResizingColumn(key);\n\n    const move = (moveEvent: PointerEvent) => {\n      const width = Math.max(minWidth, startWidth + moveEvent.clientX - startX);\n      setColumnWidths((current) => ({ ...current, [key]: width }));\n    };\n    const finish = () => {\n      window.removeEventListener(\"pointermove\", move);\n      window.removeEventListener(\"pointerup\", finish);\n      window.removeEventListener(\"pointercancel\", finish);\n      document.body.style.cursor = previousCursor;\n      document.body.style.userSelect = previousSelection;\n      setResizingColumn(null);\n    };\n\n    window.addEventListener(\"pointermove\", move);\n    window.addEventListener(\"pointerup\", finish);\n    window.addEventListener(\"pointercancel\", finish);\n  };\n  const toggleRow = (id: string) => setSelected((current) => {\n    const next = new Set(current);\n    if (next.has(id)) next.delete(id);\n    else next.add(id);\n    return next;\n  });\n  const toggleAll = () => setSelected((current) => {\n    const next = new Set(current);\n    if (allSelected) visibleRows.forEach((row) => next.delete(row.id));\n    else visibleRows.forEach((row) => next.add(row.id));\n    return next;\n  });\n\n  const meta = prop ? { ...COLUMN_META[prop.col], ...columnOverrides[prop.col] } : null;\n  const selectedInputs = prop && meta\n    ? inputSelections[prop.col] ?? (meta.inputs ? [meta.inputs] : [])\n    : [];\n  const tableWidth = columnWidths.company + columnWidths.categories + columnWidths.last + columnWidths.strength + columnWidths.links + (aiAdded ? columnWidths.ai : 0) + actionColumnWidth;\n\n  return (\n    <div className={`records-shell${fill ? \" is-fill\" : \"\"}`}>\n      <div\n        className=\"records-scroll\"\n        tabIndex={0}\n        aria-label=\"Companies table. Scroll horizontally and vertically to view all columns and records.\"\n        onScroll={() => {\n          if (ignoreScrollRef.current) {\n            ignoreScrollRef.current = false;\n            return;\n          }\n          setProp(null);\n          setConfigMenu(null);\n          setGroundingHelpOpen(false);\n          setMoreSettingsOpen(false);\n          setAddOpen(null);\n          setTableMenuOpen(null);\n        }}\n      >\n        <table ref={tableRef} className=\"records-table\" style={{ width: columnWidthsLocked ? tableWidth : \"100%\", minWidth: tableWidth }}>\n          <colgroup>\n            <col className=\"records-company-col\" style={{ width: columnWidths.company }} />\n            <col className=\"records-category-col\" style={{ width: columnWidths.categories }} />\n            <col className=\"records-last-col\" style={{ width: columnWidths.last }} />\n            <col className=\"records-strength-col\" style={{ width: columnWidths.strength }} />\n            <col className=\"records-link-col\" style={{ width: columnWidths.links }} />\n            {aiAdded && <col style={{ width: columnWidths.ai }} />}\n            <col style={{ width: 100 }} />\n          </colgroup>\n          <thead>\n            <tr>\n              <th className={`records-header-cell records-sticky-cell ${prop?.col === \"Company\" ? \"is-colsel\" : \"\"}`}>\n                <div className=\"records-company-header\" style={{ cursor: \"pointer\" }} onClick={(event) => openProp(\"Company\")(event)}>\n                  <Checkbox checked={allSelected} mixed={partiallySelected} onChange={toggleAll} label=\"Select all companies\" />\n                  <span>Company</span>\n                </div>\n                <span role=\"separator\" aria-orientation=\"vertical\" aria-label=\"Resize Company column\" className={`records-resize-handle ${resizingColumn === \"company\" ? \"is-resizing\" : \"\"}`} onPointerDown={startColumnResize(\"company\", 180)} />\n              </th>\n              <HeaderCell label=\"Categories\" selected={prop?.col === \"Categories\"} onPick={openProp(\"Categories\")} sort={sort} onSort={toggleSort} onResizeStart={startColumnResize(\"categories\")} resizing={resizingColumn === \"categories\"} icon={<Icon size={15}>{TYPE_GLYPHS[\"Multi select\"]}</Icon>} />\n              <HeaderCell label=\"Last interaction\" selected={prop?.col === \"Last interaction\"} onPick={openProp(\"Last interaction\")} sortKey=\"last\" sort={sort} onSort={toggleSort} onResizeStart={startColumnResize(\"last\")} resizing={resizingColumn === \"last\"} icon={<Icon size={15}>{TYPE_GLYPHS.Date}</Icon>} />\n              <HeaderCell label=\"Connection strength\" selected={prop?.col === \"Connection strength\"} onPick={openProp(\"Connection strength\")} sortKey=\"strength\" sort={sort} onSort={toggleSort} onResizeStart={startColumnResize(\"strength\")} resizing={resizingColumn === \"strength\"} icon={<Icon size={15}>{TYPE_GLYPHS[\"Single select\"]}</Icon>} />\n              <HeaderCell label=\"Links\" selected={prop?.col === \"Links\"} onPick={openProp(\"Links\")} sort={sort} onSort={toggleSort} onResizeStart={startColumnResize(\"links\")} resizing={resizingColumn === \"links\"} icon={<Icon size={15}>{TYPE_GLYPHS.URL}</Icon>} />\n              {aiAdded && (\n                <th ref={aiThRef} className={`records-header-cell ${prop?.col === AI_LABEL ? \"is-colsel\" : \"\"}`}>\n                  <button type=\"button\" className=\"records-header-button\" onClick={openProp(AI_LABEL)}>\n                    <span className=\"records-header-icon\"><Icon size={15}>{TYPE_GLYPHS.Text}</Icon></span>\n                    <span className=\"truncate\">{AI_LABEL}</span>\n                  </button>\n                  <span role=\"separator\" aria-orientation=\"vertical\" aria-label={`Resize ${AI_LABEL} column`} className={`records-resize-handle ${resizingColumn === \"ai\" ? \"is-resizing\" : \"\"}`} onPointerDown={startColumnResize(\"ai\")} />\n                </th>\n              )}\n              <th className=\"records-header-cell\">\n                <div className=\"flex h-[35px] items-center gap-1 px-2\">\n                  <button\n                    type=\"button\"\n                    aria-label=\"New property\"\n                    data-recpop\n                    onClick={(event) => {\n                      setProp(null);\n                      setTableMenuOpen(null);\n                      const rect = (event.currentTarget as Element).getBoundingClientRect();\n                      setAddOpen((current) => (current ? null : { x: Math.min(rect.left, window.innerWidth - 276), y: rect.bottom + 6 }));\n                    }}\n                    className=\"flex size-7 items-center justify-center rounded-[7px] text-ink-2 transition-colors duration-100 hover:bg-hover hover:text-ink\"\n                  >\n                    <Icon size={15} strokeWidth={2}><path d=\"M12 5v14M5 12h14\" /></Icon>\n                  </button>\n                  <button\n                    type=\"button\"\n                    aria-label=\"Table options\"\n                    aria-expanded={!!tableMenuOpen}\n                    data-recpop\n                    onClick={(event) => {\n                      setProp(null);\n                      setAddOpen(null);\n                      const rect = event.currentTarget.getBoundingClientRect();\n                      setTableMenuOpen((current) => current ? null : {\n                        x: Math.max(8, Math.min(rect.right - 220, window.innerWidth - 228)),\n                        y: rect.bottom + 6,\n                      });\n                    }}\n                    className=\"flex size-7 items-center justify-center rounded-[7px] text-ink-3 transition-colors duration-100 hover:bg-hover hover:text-ink\"\n                  >\n                    <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden><circle cx=\"5\" cy=\"12\" r=\"1.6\" /><circle cx=\"12\" cy=\"12\" r=\"1.6\" /><circle cx=\"19\" cy=\"12\" r=\"1.6\" /></svg>\n                  </button>\n                </div>\n              </th>\n            </tr>\n          </thead>\n          {/* data cells stay silent — the papery link/flick sound is too much when scanning rows */}\n          <tbody data-sound-silent>\n            {visibleRows.map((row, index) => {\n              const selectedRow = selected.has(row.id);\n              const strength = STRENGTH[row.strength];\n              return <tr key={row.id} className={`records-row ${selectedRow ? \"is-selected\" : \"\"}`}>\n                <td className={`records-cell records-sticky-cell records-company-cell ${prop?.col === \"Company\" ? \"is-colsel\" : \"\"}`}><span className=\"records-rownum\">{index + 1}</span><Checkbox checked={selectedRow} onChange={() => toggleRow(row.id)} label={`Select ${row.name}`} /><span className=\"records-company-mark\">{row.name.slice(0, 1).toUpperCase()}</span><a href={row.website ? `https://${row.website}` : \"#\"} onClick={(event) => !row.website && event.preventDefault()} title={row.name} className={`records-company-name ${row.website ? \"has-link\" : \"\"}`}>{row.name}</a></td>\n                <td className={`records-cell ${prop?.col === \"Categories\" ? \"is-colsel\" : \"\"}`}>{isCalc(\"Categories\", index) ? <CalcCell /> : <TagList tags={row.tags} />}</td>\n                <td className={`records-cell ${row.last === \"No contact\" ? \"records-muted\" : \"\"} ${prop?.col === \"Last interaction\" ? \"is-colsel\" : \"\"}`}>{isCalc(\"Last interaction\", index) ? <CalcCell /> : row.last}</td>\n                <td className={`records-cell ${prop?.col === \"Connection strength\" ? \"is-colsel\" : \"\"}`}>{isCalc(\"Connection strength\", index) ? <CalcCell /> : <span className=\"records-strength\"><span className=\"records-strength-dot\" style={{ background: strength.color }} />{strength.label}</span>}</td>\n                <td className={`records-cell ${prop?.col === \"Links\" ? \"is-colsel\" : \"\"}`}>{isCalc(\"Links\", index) ? <CalcCell /> : row.website ? <a className=\"records-link\" href={`https://${row.website}`} title={row.website} target=\"_blank\" rel=\"noreferrer\"><span className=\"records-link-label\">{row.website}</span><Icon size={12}><path d=\"M14 5h5v5M19 5l-8 8\" /></Icon></a> : <span className=\"records-muted\">—</span>}</td>\n                {aiAdded && (\n                  <td className={`records-cell ${prop?.col === AI_LABEL ? \"is-colsel\" : \"\"}`}>\n                    {calc?.col === AI_LABEL ? (index < calc.resolved ? competitorsFor(index) : <CalcCell />) : aiDone ? competitorsFor(index) : <span className=\"records-muted\">—</span>}\n                  </td>\n                )}\n                <td className=\"records-cell\" />\n              </tr>;\n            })}\n          </tbody>\n          <tfoot>\n            <tr className=\"records-calculation-row\">\n              <td className=\"records-cell records-sticky-cell\">\n                <span className=\"records-footer-value records-calculation-label\"><span className=\"records-calculation-number\">{rows.length}</span> count</span>\n              </td>\n              <td className=\"records-cell\">\n                <button type=\"button\" className=\"records-add-calculation\"><Icon size={15}><path d=\"M12 5v14M5 12h14\" /></Icon>Add calculation</button>\n              </td>\n              <td className=\"records-cell records-muted\"><span className=\"records-footer-value\">—</span></td>\n              <td className=\"records-cell\">\n                <span className=\"records-footer-value records-average\"><span className=\"records-strength-dot\" style={{ background: \"var(--orange)\" }} />{Math.round(rows.reduce((sum, row) => sum + STRENGTH[row.strength].rank, 0) / rows.length / 3 * 100)}% average</span>\n              </td>\n              <td className=\"records-cell\"><span className=\"records-footer-value records-muted\">{rows.filter((row) => row.website).length} links</span></td>\n              {aiAdded && <td className=\"records-cell records-muted\"><span className=\"records-footer-value\">{aiDone ? `${rows.length} filled` : \"—\"}</span></td>}\n              <td className=\"records-cell\" />\n            </tr>\n          </tfoot>\n        </table>\n      </div>\n\n      {/* ── property configuration popover ─────────────────── */}\n      {prop && meta && (\n        <div\n          data-recpop\n          className=\"fixed z-50 w-[320px] rounded-[14px] bg-surface px-3 pt-3 pb-1.5 shadow-overlay\"\n          style={{ top: prop.y, left: prop.x, animation: \"beautiful-pop-in 160ms cubic-bezier(0.23,1,0.32,1) both\", transformOrigin: \"top left\" }}\n        >\n          <div className=\"pb-2 text-[13.5px] font-medium text-ink\">{prop.col}</div>\n\n          <ConfigRow label=\"Type\">\n            <button\n              type=\"button\"\n              aria-haspopup=\"menu\"\n              aria-expanded={configMenu === \"type\"}\n              onClick={() => setConfigMenu((current) => current === \"type\" ? null : \"type\")}\n              className=\"flex items-center gap-1.5 rounded-[6px] px-1.5 py-1 text-[13px] font-medium text-ink transition-colors duration-100 hover:bg-hover\"\n            >\n              <span className=\"text-ink-2\"><Icon size={14}>{TYPE_GLYPHS[meta.type] ?? TYPE_GLYPHS.Text}</Icon></span>\n              {meta.type}\n              <span className=\"text-ink-3\"><Icon size={12} strokeWidth={2.2}><path d=\"M9 6l6 6-6 6\" /></Icon></span>\n            </button>\n            {configMenu === \"type\" && (\n              <ConfigPicker\n                label=\"Property type\"\n                selected={meta.type}\n                options={NEW_PROPERTY_TYPES.map((type) => ({ label: type, icon: <Icon size={15}>{TYPE_GLYPHS[type]}</Icon> }))}\n                onSelect={(type) => {\n                  setColumnOverrides((current) => ({ ...current, [prop.col]: { ...current[prop.col], type } }));\n                  setConfigMenu(null);\n                }}\n              />\n            )}\n          </ConfigRow>\n          <ConfigRow label=\"Tool\">\n            <button\n              type=\"button\"\n              aria-haspopup=\"menu\"\n              aria-expanded={configMenu === \"tool\"}\n              onClick={() => setConfigMenu((current) => current === \"tool\" ? null : \"tool\")}\n              className=\"flex items-center gap-1.5 rounded-[6px] px-1.5 py-1 text-[13px] font-medium text-ink transition-colors duration-100 hover:bg-hover\"\n            >\n              <span className={meta.toolKind === \"model\" ? \"text-accent\" : \"text-ink-2\"}>\n                {meta.toolKind === \"model\"\n                  ? <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden>{TOOL_GLYPHS.model}</svg>\n                  : <Icon size={14}>{TOOL_GLYPHS[meta.toolKind]}</Icon>}\n              </span>\n              {meta.tool}\n              <span className=\"text-ink-3\"><Icon size={12} strokeWidth={2.2}><path d=\"M9 6l6 6-6 6\" /></Icon></span>\n            </button>\n            {configMenu === \"tool\" && (\n              <ConfigPicker\n                label=\"Model\"\n                selected={meta.tool}\n                options={MODEL_OPTIONS.map((model) => ({\n                  label: model,\n                  icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden>{TOOL_GLYPHS.model}</svg>,\n                }))}\n                onSelect={(tool) => {\n                  setColumnOverrides((current) => ({ ...current, [prop.col]: { ...current[prop.col], tool, toolKind: \"model\" } }));\n                  setConfigMenu(null);\n                }}\n              />\n            )}\n          </ConfigRow>\n          <ConfigRow label=\"Grounding\">\n            <span className=\"flex items-center gap-2\">\n              <MiniSwitch label=\"Grounding\" on={grounding} onToggle={() => setGrounding((current) => !current)} />\n              <button\n                type=\"button\"\n                aria-label=\"About grounding\"\n                aria-expanded={groundingHelpOpen}\n                onClick={() => setGroundingHelpOpen((open) => !open)}\n                className=\"flex size-6 items-center justify-center rounded-[6px] text-ink-3 transition-colors duration-100 hover:bg-hover hover:text-ink\"\n              >\n                <Icon size={13}><g><circle cx=\"12\" cy=\"12\" r=\"9\" /><path d=\"M12 8h.01M11 12h1v4h1\" /></g></Icon>\n              </button>\n            </span>\n            {groundingHelpOpen && (\n              <div className=\"absolute right-0 top-[30px] z-30 w-[230px] rounded-[10px] px-3 py-2.5 text-[12px] leading-relaxed shadow-overlay\" style={{ color: \"var(--tooltip-fg)\", background: \"var(--tooltip-bg)\" }} role=\"status\">\n                Grounding lets the model verify generated values against connected sources.\n              </div>\n            )}\n          </ConfigRow>\n          <ConfigRow label=\"Inputs\">\n            <button\n              type=\"button\"\n              aria-haspopup=\"menu\"\n              aria-expanded={configMenu === \"inputs\"}\n              onClick={() => setConfigMenu((current) => current === \"inputs\" ? null : \"inputs\")}\n              className=\"flex max-w-[220px] items-center gap-1.5 rounded-[6px] px-1.5 py-1 text-[13px] text-ink-2 transition-colors duration-100 hover:bg-hover hover:text-ink\"\n            >\n              {selectedInputs.length ? (\n                <span className=\"flex min-w-0 items-center gap-1\">\n                  {selectedInputs.slice(0, 2).map((input) => (\n                    <span key={input} className=\"max-w-[92px] truncate rounded-[5px] bg-accent-tint px-1.5 py-0.5 text-[12px] font-medium text-accent-ink\">{input}</span>\n                  ))}\n                  {selectedInputs.length > 2 && <span className=\"text-[11px] font-medium text-ink-3\">+{selectedInputs.length - 2}</span>}\n                </span>\n              ) : (\n                <span>Select inputs</span>\n              )}\n              <span className=\"shrink-0 text-ink-3\"><Icon size={12} strokeWidth={2.2}><path d=\"M9 6l6 6-6 6\" /></Icon></span>\n            </button>\n            {configMenu === \"inputs\" && (\n              <InputPicker\n                selected={selectedInputs}\n                options={INPUT_OPTIONS.filter((input) => input !== prop.col)}\n                onToggle={(input) => {\n                  setInputSelections((current) => {\n                    const existing = current[prop.col] ?? (meta.inputs ? [meta.inputs] : []);\n                    const next = existing.includes(input) ? existing.filter((item) => item !== input) : [...existing, input];\n                    return { ...current, [prop.col]: next };\n                  });\n                }}\n              />\n            )}\n          </ConfigRow>\n\n          {/* prompt — @-mention chips inline */}\n          <div\n            contentEditable\n            suppressContentEditableWarning\n            role=\"textbox\"\n            aria-label={`${prop.col} calculation prompt`}\n            aria-multiline=\"true\"\n            spellCheck\n            className=\"mt-2 min-h-[88px] cursor-text rounded-[10px] bg-inset p-3 text-[13px] leading-relaxed shadow-hairline outline-none transition-[box-shadow] duration-150 focus:shadow-[0_0_0_2px_var(--accent)]\"\n          >\n            {meta.prompt ? (\n              <span className=\"text-ink\">\n                {meta.prompt.before}\n                {meta.prompt.chip && <span contentEditable={false} className=\"rounded-[5px] bg-accent-tint px-1.5 py-0.5 text-[12px] font-medium text-accent-ink\">{meta.prompt.chip}</span>}\n                {meta.prompt.after}\n              </span>\n            ) : (\n              <span className=\"text-ink-3\">Set a prompt (press @ to mention an input)</span>\n            )}\n          </div>\n\n          <button\n            type=\"button\"\n            disabled={!!calc}\n            onClick={() => {\n              setCalc({ col: prop.col, resolved: 0 });\n              setProp(null);\n            }}\n            className=\"mt-2.5 flex h-9 w-full items-center justify-center gap-2 rounded-[9px] text-[12.5px] font-medium text-ink shadow-btn transition-[background-color,transform] duration-150 hover:bg-hover active:scale-[0.98] disabled:opacity-60\"\n          >\n            <Icon size={14} strokeWidth={1.9}><path d=\"M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6\" /></Icon>\n            Go calculate\n          </button>\n\n          <GlideMenu className=\"mt-3 flex flex-col gap-0.5 border-t border-line pt-2\" highlightClassName=\"-inset-x-1.5 rounded-[8px] bg-hover\">\n            <button\n              data-menu-row\n              type=\"button\"\n              aria-pressed={pinnedColumns.has(prop.col)}\n              onClick={() => setPinnedColumns((current) => {\n                const next = new Set(current);\n                if (next.has(prop.col)) next.delete(prop.col);\n                else next.add(prop.col);\n                return next;\n              })}\n              className=\"relative z-10 -mx-1.5 flex h-8 items-center gap-2.5 rounded-[8px] px-1.5 text-left text-[13px] leading-none text-ink transition-transform duration-150 active:scale-[0.96]\"\n            >\n              <span className={pinnedColumns.has(prop.col) ? \"text-accent\" : \"text-ink-2\"}><Icon size={15}><path d=\"M12 17v5M8 3h8l-1 7 3 3H6l3-3-1-7z\" /></Icon></span>\n              {pinnedColumns.has(prop.col) ? \"Unpin\" : \"Pin\"}\n            </button>\n            <button\n              data-menu-row\n              type=\"button\"\n              aria-expanded={moreSettingsOpen}\n              onClick={() => setMoreSettingsOpen((open) => !open)}\n              className=\"relative z-10 -mx-1.5 flex h-8 items-center gap-2.5 rounded-[8px] px-1.5 text-left text-[13px] leading-none text-ink transition-transform duration-150 active:scale-[0.96]\"\n            >\n              <span className={moreSettingsOpen ? \"text-ink\" : \"text-ink-2\"}><Icon size={15}><g><circle cx=\"12\" cy=\"12\" r=\"3\" /><path d=\"M12 2v3M12 19v3M4.9 4.9l2.1 2.1M17 17l2.1 2.1M2 12h3M19 12h3M4.9 19.1 7 17M17 7l2.1-2.1\" /></g></Icon></span>\n              <span className=\"flex-1\">More settings</span>\n              <span className={`text-ink-3 transition-transform duration-150 ${moreSettingsOpen ? \"rotate-90\" : \"\"}`}><Icon size={12} strokeWidth={2.2}><path d=\"M9 6l6 6-6 6\" /></Icon></span>\n            </button>\n            {prop.col === AI_LABEL && (\n              <button\n                data-menu-row\n                type=\"button\"\n                onClick={() => {\n                  setAiAdded(false);\n                  setAiDone(false);\n                  setProp(null);\n                }}\n                className=\"relative z-10 -mx-1.5 flex h-8 items-center gap-2.5 rounded-[8px] px-1.5 text-left text-[13px] leading-none text-ink transition-transform duration-150 active:scale-[0.96]\"\n              >\n                <span className=\"text-ink-2\"><Icon size={15}><g><path d=\"M10.6 5.1A9.8 9.8 0 0 1 12 5c7 0 10 7 10 7a16.3 16.3 0 0 1-2.1 3M6.6 6.6A16 16 0 0 0 2 12s3 7 10 7a9.7 9.7 0 0 0 5.4-1.6M3 3l18 18\" /><path d=\"M9.9 9.9a3 3 0 0 0 4.2 4.2\" /></g></Icon></span>\n                Hide from view\n              </button>\n            )}\n          </GlideMenu>\n\n          {moreSettingsOpen && (\n            <div className=\"mt-2 border-t border-line pt-2\" style={{ animation: \"beautiful-fade-up 160ms cubic-bezier(0.23,1,0.32,1) both\" }}>\n              <div className=\"pb-1 text-[11.5px] font-medium text-ink-3\">Behavior</div>\n              <ConfigRow label=\"Required value\">\n                <MiniSwitch label=\"Required value\" on={advancedSettings.required} onToggle={() => setAdvancedSettings((current) => ({ ...current, required: !current.required }))} />\n              </ConfigRow>\n              <ConfigRow label=\"Allow empty results\">\n                <MiniSwitch label=\"Allow empty results\" on={advancedSettings.allowEmpty} onToggle={() => setAdvancedSettings((current) => ({ ...current, allowEmpty: !current.allowEmpty }))} />\n              </ConfigRow>\n              <ConfigRow label=\"Show confidence\">\n                <MiniSwitch label=\"Show confidence\" on={advancedSettings.confidence} onToggle={() => setAdvancedSettings((current) => ({ ...current, confidence: !current.confidence }))} />\n              </ConfigRow>\n            </div>\n          )}\n        </div>\n      )}\n\n      {/* ── new property type menu ─────────────────────────── */}\n      {addOpen && (\n        <div\n          data-recpop\n          className=\"fixed z-50 w-[260px] rounded-[14px] bg-surface p-1.5 shadow-overlay\"\n          style={{ top: addOpen.y, left: addOpen.x, animation: \"beautiful-pop-in 160ms cubic-bezier(0.23,1,0.32,1) both\", transformOrigin: \"top left\" }}\n        >\n          <div className=\"px-2 pb-1 pt-1 text-[12px] font-medium text-ink-3\">New property</div>\n          <GlideMenu className=\"flex flex-col gap-px\">\n            {NEW_PROPERTY_TYPES.map((type) => (\n              <button\n                key={type}\n                data-menu-row\n                type=\"button\"\n                onClick={() => {\n                  setAddOpen(null);\n                  setAiDone(false);\n                  setAiAdded(true);\n                  setPendingOpenAi(true);\n                }}\n                className=\"relative z-10 flex h-9 w-full items-center gap-2.5 rounded-[8px] px-2 text-left text-[13px] text-ink\"\n              >\n                <span className=\"text-ink-2\"><Icon size={15}>{TYPE_GLYPHS[type]}</Icon></span>\n                {type}\n              </button>\n            ))}\n          </GlideMenu>\n        </div>\n      )}\n\n      {/* ── table options menu ─────────────────────────────── */}\n      {tableMenuOpen && (\n        <div\n          data-recpop\n          className=\"fixed z-50 w-[220px] rounded-[14px] bg-surface p-1.5 shadow-overlay\"\n          style={{ top: tableMenuOpen.y, left: tableMenuOpen.x, animation: \"beautiful-pop-in 160ms cubic-bezier(0.23,1,0.32,1) both\", transformOrigin: \"top right\" }}\n        >\n          <div className=\"px-2 pb-1 pt-1 text-[12px] font-medium text-ink-3\">Table options</div>\n          <GlideMenu className=\"flex flex-col gap-px\">\n          <button\n            data-menu-row\n            type=\"button\"\n            onClick={() => {\n              const position = tableMenuOpen;\n              setTableMenuOpen(null);\n              setAddOpen({ x: Math.min(position.x, window.innerWidth - 276), y: position.y });\n            }}\n            className=\"relative z-10 flex h-9 w-full items-center gap-2.5 rounded-[8px] px-2 text-left text-[13px] text-ink\"\n          >\n            <span className=\"text-ink-2\"><Icon size={15} strokeWidth={2}><path d=\"M12 5v14M5 12h14\" /></Icon></span>\n            Add property\n          </button>\n          <button\n            data-menu-row\n            type=\"button\"\n            onClick={() => {\n              setColumnWidths({ company: 220, categories: 220, last: 155, strength: 180, links: 160, ai: 200 });\n              setTableMenuOpen(null);\n            }}\n            className=\"relative z-10 flex h-9 w-full items-center gap-2.5 rounded-[8px] px-2 text-left text-[13px] text-ink\"\n          >\n            <span className=\"text-ink-2\"><Icon size={15}><path d=\"M4 8h16M7 4 3 8l4 4M17 4l4 4-4 4M4 16h16\" /></Icon></span>\n            Compact columns\n          </button>\n          <button\n            data-menu-row\n            type=\"button\"\n            onClick={() => {\n              setColumnWidths({ ...(initialColumnWidthsRef.current ?? DEFAULT_COLUMN_WIDTHS) });\n              setTableMenuOpen(null);\n            }}\n            className=\"relative z-10 flex h-9 w-full items-center gap-2.5 rounded-[8px] px-2 text-left text-[13px] text-ink\"\n          >\n            <span className=\"text-ink-2\"><Icon size={15}><path d=\"M3 12a9 9 0 1 0 3-6.7M3 4v6h6\" /></Icon></span>\n            Reset column widths\n          </button>\n          <div className=\"my-1 h-px bg-line\" />\n          <button\n            data-menu-row\n            type=\"button\"\n            onClick={() => {\n              setSelected(new Set());\n              setTableMenuOpen(null);\n            }}\n            className=\"relative z-10 flex h-9 w-full items-center gap-2.5 rounded-[8px] px-2 text-left text-[13px] text-ink\"\n          >\n            <span className=\"text-ink-2\"><Icon size={15}><path d=\"M5 5l14 14M19 5 5 19\" /></Icon></span>\n            Clear selection\n          </button>\n          </GlideMenu>\n        </div>\n      )}\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "target": "@components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useRef, useState, type ReactNode } from \"react\";\n\ntype GlideMenuProps = {\n  children: ReactNode;\n  className?: string;\n  highlightClassName?: string;\n  rowSelector?: string;\n};\n\n/** A single hover layer that glides between interactive menu rows. */\nexport default function GlideMenu({\n  children,\n  className = \"\",\n  highlightClassName = \"inset-x-0 rounded-[8px] bg-hover\",\n  rowSelector = \"[data-menu-row]\",\n}: GlideMenuProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const [box, setBox] = useState<{ top: number; height: number } | null>(null);\n  const [visible, setVisible] = useState(false);\n\n  const moveTo = (target: EventTarget | null) => {\n    const container = ref.current;\n    if (!(target instanceof Element) || !container) return;\n    const row = target.closest(rowSelector);\n    if (!(row instanceof HTMLElement) || !container.contains(row)) return;\n    const containerRect = container.getBoundingClientRect();\n    const rowRect = row.getBoundingClientRect();\n    setBox({ top: rowRect.top - containerRect.top, height: rowRect.height });\n    setVisible(true);\n  };\n\n  return (\n    <div\n      ref={ref}\n      onMouseOver={(event) => moveTo(event.target)}\n      onMouseLeave={() => setVisible(false)}\n      onFocusCapture={(event) => moveTo(event.target)}\n      onBlurCapture={(event) => {\n        if (!ref.current?.contains(event.relatedTarget as Node | null)) setVisible(false);\n      }}\n      className={`group/glide-menu relative ${className}`}\n    >\n      <span\n        aria-hidden\n        className={`pointer-events-none absolute ${highlightClassName}`}\n        style={{\n          top: box?.top ?? 0,\n          height: box?.height ?? 0,\n          opacity: box && visible ? 1 : 0,\n          transition:\n            \"top 220ms cubic-bezier(0.23,1,0.32,1), height 220ms cubic-bezier(0.23,1,0.32,1), opacity 150ms ease\",\n        }}\n      />\n      {children}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-search-list",
      "type": "registry:block",
      "title": "Beautiful Original Search List",
      "description": "Original Beautiful UI SearchList",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/SearchList.tsx",
          "target": "@components/beautiful-ui/original/primitives/SearchList.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useState } from \"react\";\nimport GlideMenu from \"./GlideMenu\";\n\n/* ─────────────────────────────────────────────────────────\n * SEARCH — command search with live filtering.\n * The field, clear action, and results are directly usable.\n * ───────────────────────────────────────────────────────── */\n\nexport type SearchItem = string;\n\nexport type SearchListLabels = {\n  placeholder: string;\n  ariaLabel: string;\n  emptyTitle: string;\n  emptyHint: string;\n};\n\nconst ITEMS: SearchItem[] = [\n  \"Forecast summer demand\",\n  \"Find waffle cone suppliers\",\n  \"Compare seasonal flavors\",\n  \"Draft flavor launch plan\",\n  \"Check cold-chain status\",\n  \"Audit sugar costs\",\n  \"Retire low sellers\",\n];\n\nconst LABELS: SearchListLabels = {\n  placeholder: \"Search flavors…\",\n  ariaLabel: \"Search flavors\",\n  emptyTitle: \"No results found\",\n  emptyHint: \"Adjust your search to try again\",\n};\n\nexport default function SearchList({\n  items = ITEMS,\n  labels = LABELS,\n}: {\n  items?: SearchItem[];\n  labels?: SearchListLabels;\n  variant?: string;\n} = {}) {\n  const [query, setQuery] = useState(\"\");\n  const results = query\n    ? items.filter((i) => i.toLowerCase().includes(query.toLowerCase()))\n    : items.slice(0, 5);\n  const empty = query.length > 2 && results.length === 0;\n\n  return (\n    <div className=\"flex min-h-[248px] w-full max-w-72 flex-col items-stretch\">\n      <div className=\"w-full self-start overflow-hidden rounded-card bg-surface shadow-raised\">\n        {/* input row */}\n        <div className=\"flex h-10 items-center gap-2 border-b border-line px-3 transition-colors duration-100 hover:bg-hover\">\n          <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--ink-3)\" strokeWidth=\"2\" strokeLinecap=\"round\" className=\"shrink-0\">\n            <circle cx=\"11\" cy=\"11\" r=\"7\" />\n            <path d=\"M21 21l-4.3-4.3\" />\n          </svg>\n          <input\n            value={query}\n            onChange={(event) => setQuery(event.target.value)}\n            placeholder={labels.placeholder}\n            aria-label={labels.ariaLabel}\n            className=\"min-w-0 flex-1 bg-transparent text-[13px] text-ink outline-none placeholder:text-ink-3\"\n          />\n          {query && (\n            <button\n              aria-label=\"Clear search\"\n              type=\"button\"\n              onClick={() => setQuery(\"\")}\n              className=\"flex size-6 items-center justify-center rounded-full text-ink-3\n                transition-colors duration-100 hover:bg-line/70 hover:text-ink\"\n              style={{ animation: \"beautiful-fade-in 150ms ease-out both\" }}\n            >\n              <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\">\n                <path d=\"M18 6L6 18M6 6l12 12\" />\n              </svg>\n            </button>\n          )}\n        </div>\n\n        {/* results / empty state */}\n        {empty ? (\n          <div className=\"flex flex-col items-center justify-center gap-1 px-4 py-8\" style={{ animation: \"beautiful-fade-in 250ms ease-out both\" }}>\n            <span className=\"mb-1.5 flex size-8 items-center justify-center rounded-control bg-inset text-ink-3 shadow-hairline\">\n              <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\">\n                <circle cx=\"11\" cy=\"11\" r=\"7\" />\n                <path d=\"M21 21l-4.3-4.3\" />\n              </svg>\n            </span>\n            <span className=\"text-[13px] font-medium text-ink\">{labels.emptyTitle}</span>\n            <span className=\"text-[12px] text-ink-3\">{labels.emptyHint}</span>\n          </div>\n        ) : (\n          <div className=\"p-1\">\n            <GlideMenu className=\"flex flex-col gap-px\" highlightClassName=\"inset-x-0 rounded-[6px] bg-hover\">\n              {results.map((item) => (\n                <button\n                  key={item}\n                  data-menu-row\n                  type=\"button\"\n                  onClick={() => setQuery(item)}\n                  className=\"relative z-10 flex h-8 w-full items-center rounded-[6px] px-2 text-left text-[13px] text-ink\"\n                  style={{ animation: \"beautiful-fade-in 200ms ease-out both\" }}\n                >\n                  {item}\n                </button>\n              ))}\n            </GlideMenu>\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "target": "@components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useRef, useState, type ReactNode } from \"react\";\n\ntype GlideMenuProps = {\n  children: ReactNode;\n  className?: string;\n  highlightClassName?: string;\n  rowSelector?: string;\n};\n\n/** A single hover layer that glides between interactive menu rows. */\nexport default function GlideMenu({\n  children,\n  className = \"\",\n  highlightClassName = \"inset-x-0 rounded-[8px] bg-hover\",\n  rowSelector = \"[data-menu-row]\",\n}: GlideMenuProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const [box, setBox] = useState<{ top: number; height: number } | null>(null);\n  const [visible, setVisible] = useState(false);\n\n  const moveTo = (target: EventTarget | null) => {\n    const container = ref.current;\n    if (!(target instanceof Element) || !container) return;\n    const row = target.closest(rowSelector);\n    if (!(row instanceof HTMLElement) || !container.contains(row)) return;\n    const containerRect = container.getBoundingClientRect();\n    const rowRect = row.getBoundingClientRect();\n    setBox({ top: rowRect.top - containerRect.top, height: rowRect.height });\n    setVisible(true);\n  };\n\n  return (\n    <div\n      ref={ref}\n      onMouseOver={(event) => moveTo(event.target)}\n      onMouseLeave={() => setVisible(false)}\n      onFocusCapture={(event) => moveTo(event.target)}\n      onBlurCapture={(event) => {\n        if (!ref.current?.contains(event.relatedTarget as Node | null)) setVisible(false);\n      }}\n      className={`group/glide-menu relative ${className}`}\n    >\n      <span\n        aria-hidden\n        className={`pointer-events-none absolute ${highlightClassName}`}\n        style={{\n          top: box?.top ?? 0,\n          height: box?.height ?? 0,\n          opacity: box && visible ? 1 : 0,\n          transition:\n            \"top 220ms cubic-bezier(0.23,1,0.32,1), height 220ms cubic-bezier(0.23,1,0.32,1), opacity 150ms ease\",\n        }}\n      />\n      {children}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-selection-actions",
      "type": "registry:block",
      "title": "Beautiful Original Selection Actions",
      "description": "Original Beautiful UI SelectionActions",
      "dependencies": [
        "class-variance-authority@^0.7.1",
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/SelectionActions.tsx",
          "target": "@components/beautiful-ui/original/primitives/SelectionActions.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  useCallback,\n  useEffect,\n  useLayoutEffect,\n  useRef,\n  useState,\n  type ReactNode,\n} from \"react\";\nimport {\n  ArrowUp,\n  Check,\n  ChevronRight as NavArrowRight,\n  MessageCircleQuestion as ChatBubbleQuestion,\n  RefreshCw as Refresh,\n  Scissors as Scissor,\n  Smile as EmojiSatisfied,\n  Sparkles as Spark,\n  Type as TextBox,\n  X as Xmark,\n} from \"lucide-react\";\nimport { Button } from \"../atoms/Button\";\nimport { Shimmer } from \"../atoms/Shimmer\";\nimport { StreamText } from \"../atoms/StreamText\";\n\n/* ─────────────────────────────────────────────────────────\n * SELECTION ACTIONS\n * A contextual AI bar attached beneath selected text.\n * The global theme owns its surface; this component only\n * composes existing surface, ink, accent, radius and motion\n * tokens.\n * ───────────────────────────────────────────────────────── */\n\nconst LEAD = \"Pistachio holds the top slot all weekend. \";\nconst PICKED =\n  \"Churn it first thing Saturday so the batch has time to firm up before the afternoon rush.\";\nconst REWRITE =\n  \"Churn pistachio first thing Saturday so the batch has time to fully firm before the afternoon rush.\";\nconst TOOLBAR_GUTTER = 10;\n\nexport function isCompactToolbar(hostWidth: number) {\n  return hostWidth < 390;\n}\n\nexport function clampToolbarCenter(\n  desiredX: number,\n  toolbarWidth: number,\n  hostLeft: number,\n  hostWidth: number,\n  viewportWidth: number,\n) {\n  const halfWidth = toolbarWidth / 2;\n  const viewportLeft = TOOLBAR_GUTTER;\n  const viewportRight = viewportWidth - TOOLBAR_GUTTER;\n  const localLeft = Math.max(hostLeft, viewportLeft);\n  const localRight = Math.min(hostLeft + hostWidth, viewportRight);\n  const fitsLocally = localRight - localLeft >= toolbarWidth;\n  const left = fitsLocally ? localLeft : viewportLeft;\n  const right = fitsLocally ? localRight : viewportRight;\n  const center = Math.min(\n    Math.max(hostLeft + desiredX, left + halfWidth),\n    right - halfWidth,\n  );\n\n  return Math.round(center - hostLeft);\n}\n\n/* The passage: lead-in text, the selected `original`, and the streamed `rewrite`. */\nexport type SelectionText = {\n  lead: string;\n  original: string;\n  rewrite: string;\n};\n\n/* A single AI action offered in the bar. Omit `action` for a no-op button\n * (e.g. Explain); `busyLabel` is the gerund shown while it runs. */\nexport type SelectionAction = {\n  id: string;\n  icon: ReactNode;\n  action?: string;\n  busyLabel?: string;\n};\n\n/* The action set: `primary` are always visible; `more` reveal on expand. */\nexport type SelectionActionSet = {\n  primary: SelectionAction[];\n  more: SelectionAction[];\n};\n\n/* Prominent copy strings. */\nexport type SelectionActionsLabels = {\n  keep: string;\n  discard: string;\n  placeholder: string;\n};\n\nconst DEFAULT_TEXT: SelectionText = {\n  lead: LEAD,\n  original: PICKED,\n  rewrite: REWRITE,\n};\n\nconst DEFAULT_LABELS: SelectionActionsLabels = {\n  keep: \"Keep\",\n  discard: \"Discard\",\n  placeholder: \"Describe edits\",\n};\n\ntype Mode = \"idle\" | \"thinking\" | \"streaming\" | \"result\";\n\nconst iconProps = {\n  width: 14,\n  height: 14,\n  strokeWidth: 1.8,\n  \"aria-hidden\": true,\n} as const;\n\nconst icons = {\n  explain: <ChatBubbleQuestion {...iconProps} />,\n  improve: <Spark {...iconProps} />,\n  shorten: <Scissor {...iconProps} />,\n  tone: <EmojiSatisfied {...iconProps} />,\n  grammar: <TextBox {...iconProps} />,\n  send: (\n    <ArrowUp\n      width=\"16\"\n      height=\"16\"\n      strokeWidth=\"2.4\"\n      aria-hidden=\"true\"\n    />\n  ),\n  chevron: <NavArrowRight {...iconProps} />,\n  check: <Check {...iconProps} />,\n  close: <Xmark {...iconProps} />,\n  retry: <Refresh {...iconProps} />,\n};\n\n/* the single \"keep\" affirm — solid ink with a hairline (not the atom's filled\n * highlight) shadow, so it stays a local one-off rather than a Button variant */\nconst primary =\n  \"inline-flex h-7 shrink-0 items-center gap-1 rounded-full bg-ink px-2.5 text-[12.5px] font-normal text-canvas shadow-hairline transition-[opacity,transform] duration-150 hover:opacity-90 active:scale-[0.96]\";\n\n\nconst DEFAULT_ACTIONS: SelectionActionSet = {\n  primary: [\n    { id: \"Explain\", icon: icons.explain },\n    { id: \"Improve\", icon: icons.improve, action: \"Improve\", busyLabel: \"Improving\" },\n  ],\n  more: [\n    { id: \"Shorten\", icon: icons.shorten, action: \"Shorten\", busyLabel: \"Shortening\" },\n    { id: \"Tone\", icon: icons.tone, action: \"Change tone\", busyLabel: \"Changing tone\" },\n    { id: \"Grammar\", icon: icons.grammar, action: \"Fix grammar\" },\n  ],\n};\n\nexport type SelectionActionsProps = {\n  /** Accepted for gallery/registry parity; not used by this bar. */\n  variant?: string;\n  /** The passage shown above the bar. */\n  text?: Partial<SelectionText>;\n  /** The AI actions offered in the bar. */\n  actions?: SelectionActionSet;\n  /** Prominent copy strings. */\n  labels?: Partial<SelectionActionsLabels>;\n  /** Called with the action name whenever an edit is run. */\n  onAction?: (action: string) => void;\n};\n\nexport default function SelectionActions({\n  text: textProp,\n  actions = DEFAULT_ACTIONS,\n  labels,\n  onAction,\n}: SelectionActionsProps = {}) {\n  const passage = { ...DEFAULT_TEXT, ...textProp };\n  const copy = { ...DEFAULT_LABELS, ...labels };\n  const [shown, setShown] = useState(false);\n  const [mode, setMode] = useState<Mode>(\"idle\");\n  const [action, setAction] = useState(\"Improve\");\n  const [prompt, setPrompt] = useState(\"\");\n  const [typingWidth, setTypingWidth] = useState<number | null>(null);\n  const [expanded, setExpanded] = useState(false);\n  const [anchor, setAnchor] = useState({ x: 0, y: 0 });\n  const [positioned, setPositioned] = useState(false);\n  const [compact, setCompact] = useState(false);\n\n  const hostRef = useRef<HTMLDivElement>(null);\n  const selectionRef = useRef<HTMLSpanElement>(null);\n  const barRef = useRef<HTMLDivElement>(null);\n  const contentRef = useRef<HTMLDivElement>(null);\n  const frameRef = useRef<number | null>(null);\n  const previousModeRef = useRef<Mode>(\"idle\");\n  const lastWidthRef = useRef(0);\n  const widthAnimationRef = useRef<Animation | null>(null);\n\n  useEffect(() => {\n    const timer = window.setTimeout(() => setShown(true), 280);\n    return () => window.clearTimeout(timer);\n  }, []);\n\n  useEffect(() => {\n    if (mode !== \"thinking\") return;\n    const timer = window.setTimeout(() => setMode(\"streaming\"), 700);\n    return () => window.clearTimeout(timer);\n  }, [mode]);\n\n  /* Attach beneath the final selected line, while centering the bar\n   * against the complete selection bounds. requestAnimationFrame batches\n   * streaming reflow measurements and avoids visible intermediate positions. */\n  const place = useCallback(() => {\n    if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);\n    frameRef.current = requestAnimationFrame(() => {\n      const host = hostRef.current;\n      const selection = selectionRef.current;\n      if (!host || !selection) return;\n\n      const bounds = selection.getBoundingClientRect();\n      const lines = Array.from(selection.getClientRects());\n      const lastLine = lines.at(-1);\n      if (!lastLine) return;\n\n      const hostBounds = host.getBoundingClientRect();\n      const toolbarWidth = barRef.current?.getBoundingClientRect().width ?? 0;\n      const nextCompact = isCompactToolbar(hostBounds.width);\n      const next = {\n        x: nextCompact\n          ? 0\n          : clampToolbarCenter(\n              bounds.left - hostBounds.left + bounds.width / 2,\n              toolbarWidth,\n              hostBounds.left,\n              hostBounds.width,\n              window.innerWidth,\n            ),\n        y: Math.round(lastLine.bottom - hostBounds.top + 8),\n      };\n\n      setCompact(nextCompact);\n      setAnchor((current) =>\n        current.x === next.x && current.y === next.y ? current : next,\n      );\n      setPositioned(true);\n    });\n  }, []);\n\n  useLayoutEffect(() => {\n    place();\n  }, [mode, place]);\n\n  useEffect(() => {\n    const host = hostRef.current;\n    if (!host) return;\n    const observer = new ResizeObserver(place);\n    observer.observe(host);\n    if (barRef.current) observer.observe(barRef.current);\n    window.addEventListener(\"resize\", place);\n    return () => {\n      observer.disconnect();\n      window.removeEventListener(\"resize\", place);\n      if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);\n    };\n  }, [place]);\n\n  /* Intrinsic width handles the preset expansion. When the entire content\n   * changes between idle, loading and confirmation, animate from the last\n   * rendered width to the new intrinsic width before the browser paints. */\n  useLayoutEffect(() => {\n    const bar = barRef.current;\n    const content = contentRef.current;\n    if (!bar || !content) return;\n\n    const nextWidth = Math.ceil(content.getBoundingClientRect().width) + 8;\n    const previousWidth =\n      lastWidthRef.current || Math.ceil(bar.getBoundingClientRect().width);\n\n    if (compact) {\n      widthAnimationRef.current?.cancel();\n      lastWidthRef.current = Math.ceil(bar.getBoundingClientRect().width);\n      previousModeRef.current = mode;\n      return;\n    }\n\n    if (\n      previousModeRef.current !== mode &&\n      Math.abs(nextWidth - previousWidth) > 1\n    ) {\n      widthAnimationRef.current?.cancel();\n      const animation = bar.animate(\n        [\n          { width: `${previousWidth}px` },\n          { width: `${nextWidth}px` },\n        ],\n        {\n          duration: 320,\n          easing: \"cubic-bezier(0.23,1,0.32,1)\",\n        },\n      );\n      widthAnimationRef.current = animation;\n      animation.onfinish = () => {\n        lastWidthRef.current = nextWidth;\n        widthAnimationRef.current = null;\n      };\n    } else {\n      lastWidthRef.current = nextWidth;\n    }\n\n    previousModeRef.current = mode;\n  }, [compact, mode]);\n\n  useEffect(() => {\n    const content = contentRef.current;\n    if (!content) return;\n\n    const observer = new ResizeObserver(() => {\n      if (widthAnimationRef.current?.playState === \"running\") return;\n      lastWidthRef.current =\n        Math.ceil(content.getBoundingClientRect().width) + 8;\n    });\n    observer.observe(content);\n    return () => {\n      observer.disconnect();\n      widthAnimationRef.current?.cancel();\n    };\n  }, []);\n\n  const run = (nextAction: string) => {\n    setAction(nextAction);\n    setExpanded(false);\n    setMode(\"thinking\");\n    onAction?.(nextAction);\n  };\n\n  const reset = () => {\n    setExpanded(false);\n    setPrompt(\"\");\n    setTypingWidth(null);\n    setAction(\"Improve\");\n    setMode(\"idle\");\n  };\n\n  const busy = mode === \"thinking\" || mode === \"streaming\";\n  const visible = shown && positioned;\n  const hasPrompt = prompt.trim().length > 0;\n  const busyLabelMap: Record<string, string> = {};\n  for (const item of [...actions.primary, ...actions.more]) {\n    if (item.action && item.busyLabel) busyLabelMap[item.action] = item.busyLabel;\n  }\n  const busyLabel = busyLabelMap[action] ?? \"Editing\";\n\n  return (\n    <div className=\"w-full max-w-[460px]\">\n      <div\n        ref={hostRef}\n        className={`relative select-none ${compact ? (expanded ? \"pb-28\" : \"pb-24\") : \"pb-12\"}`}\n      >\n        <p className=\"text-[13px] leading-relaxed text-ink\">\n          {passage.lead}\n          <span\n            ref={selectionRef}\n            className=\"box-decoration-clone rounded-[3px] bg-[color-mix(in_srgb,var(--accent)_14%,var(--surface))] text-ink dark:bg-accent-tint\"\n          >\n            {mode === \"idle\" || mode === \"thinking\" ? (\n              passage.original\n            ) : mode === \"streaming\" ? (\n              <StreamText\n                text={passage.rewrite}\n                onProgress={place}\n                onDone={() => setMode(\"result\")}\n              />\n            ) : (\n              passage.rewrite\n            )}\n          </span>\n        </p>\n\n        <div\n          className=\"absolute top-0 left-0 z-10\"\n          style={{\n            width: compact ? \"100%\" : undefined,\n            transform: compact\n              ? `translate3d(0, ${anchor.y}px, 0)`\n              : `translate3d(${anchor.x}px, ${anchor.y}px, 0) translateX(-50%)`,\n            transition:\n              \"transform 320ms cubic-bezier(0.77,0,0.175,1), opacity 180ms ease-out\",\n            opacity: visible ? 1 : 0,\n            pointerEvents: visible ? \"auto\" : \"none\",\n            willChange: \"transform\",\n          }}\n        >\n          {/* A 36px pill wraps 28px controls at a 4px inset. The controls\n              resolve to a 14px radius, preserving the concentric curve. */}\n          <div\n            ref={barRef}\n            className={`flex items-center justify-center gap-0.5 overflow-hidden bg-surface p-1 font-sans font-normal text-ink shadow-overlay ${\n              compact\n                ? \"h-auto w-full max-w-none rounded-card\"\n                : \"h-9 w-fit max-w-[calc(100vw-20px)] rounded-full\"\n            }`}\n            style={{\n              width:\n                !compact && mode === \"idle\" && hasPrompt && typingWidth\n                  ? typingWidth\n                  : undefined,\n              ...(visible\n                ? {\n                    animation:\n                      \"beautiful-pop-in 220ms cubic-bezier(0.23,1,0.32,1) both\",\n                  }\n                : {}),\n            }}\n          >\n            <div\n              ref={contentRef}\n              className={\n                compact && mode === \"idle\"\n                  ? \"grid w-full grid-cols-[minmax(0,1fr)_auto] items-center gap-0.5\"\n                  : \"flex w-fit shrink-0 items-center justify-center gap-0.5\"\n              }\n              style={{\n                width:\n                  !compact && mode === \"idle\" && hasPrompt && typingWidth\n                    ? typingWidth - 8\n                    : undefined,\n              }}\n            >\n            {busy && (\n              <span className=\"inline-flex h-7 items-center gap-1.5 whitespace-nowrap px-2.5 text-[12.5px] font-normal text-ink-2\">\n                <span\n                  className=\"size-3 shrink-0 rounded-full border-[1.5px] border-line-strong border-t-ink-2\"\n                  style={{ animation: \"beautiful-spin 700ms linear infinite\" }}\n                />\n                {mode === \"thinking\" ? (\n                  <Shimmer className=\"text-[12.5px] font-normal\">\n                    {busyLabel}…\n                  </Shimmer>\n                ) : (\n                  <span>{busyLabel}…</span>\n                )}\n              </span>\n            )}\n\n            {mode === \"result\" && (\n              <>\n                <button\n                  type=\"button\"\n                  onClick={reset}\n                  className={primary}\n                >\n                  {icons.check}\n                  {copy.keep}\n                </button>\n                <Button type=\"button\" variant=\"quiet\" size=\"xs\" className=\"shrink-0\" onClick={reset}>\n                  {icons.close}\n                  {copy.discard}\n                </Button>\n                <span className=\"mx-0.5 h-4 w-px shrink-0 bg-line\" />\n                <button\n                  type=\"button\"\n                  aria-label=\"Try again\"\n                  onClick={() => run(action)}\n                  className=\"flex size-7 shrink-0 items-center justify-center rounded-full text-ink-3 transition-[background-color,color,transform] duration-150 hover:bg-hover-2 hover:text-ink-2 active:scale-[0.96]\"\n                >\n                  {icons.retry}\n                </button>\n              </>\n            )}\n\n            {mode === \"idle\" && (\n              <>\n                <div\n                  className={`flex min-w-0 items-center overflow-hidden transition-[max-width,opacity,transform] duration-400 ${\n                    compact ? \"col-start-1 row-start-1 w-full\" : \"\"\n                  }`}\n                  style={{\n                    display: compact && expanded ? \"none\" : undefined,\n                    maxWidth: compact\n                      ? expanded\n                        ? 0\n                        : \"none\"\n                      : expanded\n                        ? 0\n                        : hasPrompt && typingWidth\n                          ? typingWidth - 40\n                          : 145,\n                    opacity: expanded ? 0 : 1,\n                    transform: expanded ? \"translateX(-8px)\" : \"translateX(0)\",\n                    transitionTimingFunction: \"cubic-bezier(0.23,1,0.32,1)\",\n                  }}\n                >\n                  <form\n                    className={`flex h-7 shrink-0 items-center transition-[width] duration-400 ${compact ? \"w-full\" : \"\"}`}\n                    style={{\n                      width: compact\n                        ? undefined\n                        : hasPrompt && typingWidth\n                          ? typingWidth - 40\n                          : 145,\n                      transitionTimingFunction: \"cubic-bezier(0.23,1,0.32,1)\",\n                    }}\n                    onSubmit={(event) => {\n                      event.preventDefault();\n                      run(prompt.trim() || \"Improve\");\n                    }}\n                  >\n                    <input\n                      value={prompt}\n                      onChange={(event) => {\n                        const next = event.target.value;\n                        if (!prompt.trim() && next.trim()) {\n                          setTypingWidth(\n                            Math.ceil(\n                              barRef.current?.getBoundingClientRect().width ??\n                                0,\n                            ),\n                          );\n                        } else if (!next.trim()) {\n                          setTypingWidth(null);\n                        }\n                        setPrompt(next);\n                      }}\n                      aria-label={copy.placeholder}\n                      placeholder={copy.placeholder}\n                      className=\"h-7 w-full bg-transparent pr-2.5 pl-3 text-[12.5px] text-ink placeholder:text-ink-3\"\n                    />\n                  </form>\n                </div>\n\n                <div\n                  className={`flex min-w-0 items-center gap-0.5 overflow-hidden transition-[max-width,opacity,transform] duration-400 ${\n                    compact\n                      ? expanded\n                        ? \"col-span-2 row-start-1 w-full flex-wrap justify-center\"\n                        : \"col-span-2 row-start-2 w-full flex-wrap justify-center border-t border-line pt-1\"\n                      : \"\"\n                  }`}\n                  style={{\n                    maxWidth: hasPrompt\n                      ? 0\n                      : compact\n                        ? \"none\"\n                        : expanded\n                          ? 462\n                          : 224,\n                    opacity: hasPrompt ? 0 : 1,\n                    transform: hasPrompt ? \"translateX(-8px)\" : \"translateX(0)\",\n                    transitionTimingFunction: \"cubic-bezier(0.23,1,0.32,1)\",\n                  }}\n                >\n                  {!expanded && !compact && (\n                    <span className=\"mx-1 h-4 w-px shrink-0 bg-line-strong\" />\n                  )}\n                  {actions.primary.map((item) => (\n                    <Button\n                      key={item.id}\n                      type=\"button\"\n                      variant=\"quiet\"\n                      size=\"xs\"\n                      className=\"shrink-0\"\n                      onClick={item.action ? () => run(item.action!) : undefined}\n                    >\n                      {item.icon}\n                      {item.id}\n                    </Button>\n                  ))}\n\n                  <div\n                    className=\"flex min-w-0 items-center gap-0.5 overflow-hidden transition-[max-width,opacity,margin] duration-400\"\n                    style={{\n                      display: compact && expanded ? \"contents\" : undefined,\n                      maxWidth: expanded ? 262 : 0,\n                      opacity: expanded ? 1 : 0,\n                      marginLeft: expanded ? 2 : 0,\n                      transitionTimingFunction: \"cubic-bezier(0.23,1,0.32,1)\",\n                    }}\n                  >\n                  {actions.more.map((item) => (\n                    <Button\n                      key={item.id}\n                      type=\"button\"\n                      variant=\"quiet\"\n                      size=\"xs\"\n                      className=\"shrink-0\"\n                      onClick={item.action ? () => run(item.action!) : undefined}\n                    >\n                      {item.icon}\n                      {item.id}\n                    </Button>\n                  ))}\n                  </div>\n\n                  <span className=\"mx-0.5 h-4 w-px shrink-0 bg-line\" />\n                  <button\n                    type=\"button\"\n                    aria-label={expanded ? \"Show fewer actions\" : \"Show more actions\"}\n                    aria-expanded={expanded}\n                    onClick={() => setExpanded((value) => !value)}\n                    className=\"flex size-7 shrink-0 items-center justify-center rounded-full text-ink transition-[background-color,transform] duration-200 hover:bg-hover active:scale-[0.96]\"\n                  >\n                    <span\n                      className=\"flex transition-transform duration-400\"\n                      style={{\n                        transform: expanded ? \"rotate(180deg)\" : \"rotate(0deg)\",\n                        transitionTimingFunction: \"cubic-bezier(0.23,1,0.32,1)\",\n                      }}\n                    >\n                      {icons.chevron}\n                    </span>\n                  </button>\n                </div>\n\n                <div\n                  className={`flex min-w-0 items-center overflow-hidden transition-[max-width,opacity,transform] duration-400 ${\n                    compact ? \"col-start-2 row-start-1\" : \"\"\n                  }`}\n                  style={{\n                    display: compact && expanded ? \"none\" : undefined,\n                    maxWidth: hasPrompt ? 30 : 0,\n                    opacity: hasPrompt ? 1 : 0,\n                    transform: hasPrompt ? \"scale(1)\" : \"scale(0.88)\",\n                    transitionTimingFunction: \"cubic-bezier(0.23,1,0.32,1)\",\n                  }}\n                >\n                  <button\n                    type=\"button\"\n                    aria-label=\"Send edit instruction\"\n                    onClick={() => run(prompt.trim())}\n                    className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-ink text-surface transition-[opacity,transform] duration-200 active:scale-[0.94]\"\n                  >\n                    {icons.send}\n                  </button>\n                </div>\n              </>\n            )}\n            </div>\n          </div>\n        </div>\n      </div>\n\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/Button.tsx",
          "target": "@components/beautiful-ui/original/atoms/Button.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { ButtonHTMLAttributes } from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../utils\";\n\nconst filledShadow = \"shadow-[inset_0_1px_0_rgba(255,255,255,0.14)]\";\n\n/* Pill-shaped by default — the app's core button style. Explicit symmetric\n * padding (not a fixed height) so the top/bottom spacing is always equal. */\nexport const buttonVariants = cva(\n  `inline-flex items-center justify-center font-medium select-none\n   transition-[transform,background-color,opacity] duration-150 ease-out\n   active:scale-[0.96] disabled:opacity-50 disabled:pointer-events-none`,\n  {\n    variants: {\n      variant: {\n        primary: `bg-ink text-canvas hover:opacity-90 dark:bg-ink dark:text-canvas ${filledShadow}`,\n        secondary: \"bg-surface text-ink shadow-btn hover:bg-inset aria-expanded:bg-hover\",\n        ghost: \"bg-hover-2 text-ink hover:bg-line-strong\",\n        accent: `bg-accent text-white hover:bg-accent-ink ${filledShadow}`,\n        success: `bg-green text-white hover:brightness-95 ${filledShadow}`,\n        /* transparent until hovered — for dense toolbars/action rows */\n        quiet: \"text-ink hover:bg-hover\",\n      },\n      size: {\n        /* compact toolbar pill — fixed height, lighter weight */\n        xs: \"h-7 rounded-full px-2.5 text-[12px] font-normal leading-none gap-1\",\n        /* canonical action pill — 27px tall, roomy sides */\n        sm: \"h-[27px] px-3 text-[13px] leading-none rounded-full gap-1.5\",\n        md: \"px-4 py-[9px] text-sm leading-none rounded-full gap-2\",\n      },\n    },\n    defaultVariants: { variant: \"secondary\", size: \"md\" },\n  },\n);\n\nexport type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>[\"variant\"]>;\n\nexport function Button({\n  variant,\n  size,\n  className,\n  ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>) {\n  return <button className={cn(buttonVariants({ variant, size }), className)} {...props} />;\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/utils.ts",
          "target": "@components/beautiful-ui/original/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Merge class names, letting later Tailwind classes win over conflicting earlier ones. */\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/Shimmer.tsx",
          "target": "@components/beautiful-ui/original/atoms/Shimmer.tsx",
          "type": "registry:component",
          "content": "/** Shimmering label — signals the agent is processing. */\nexport function Shimmer({\n  children,\n  className = \"\",\n}: {\n  children: React.ReactNode;\n  className?: string;\n}) {\n  return (\n    <span\n      className={`inline-block bg-clip-text text-transparent ${className}`}\n      style={{\n        backgroundImage:\n          \"linear-gradient(90deg, var(--ink-3) 35%, var(--ink) 50%, var(--ink-3) 65%)\",\n        backgroundSize: \"200% 100%\",\n        animation: \"beautiful-shimmer-text 1.8s linear infinite\",\n      }}\n    >\n      {children}\n    </span>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/atoms/StreamText.tsx",
          "target": "@components/beautiful-ui/original/atoms/StreamText.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * STREAM TEXT — reusable streaming primitive\n * Reveals characters quickly (fast, like a real token stream);\n * the leading edge resolves out of a soft blur, and the caret\n * stays solid while streaming, then blinks once the text\n * settles. Inherits typography from its context, so it drops\n * into any text surface (Selection Actions, chat, etc.).\n * ───────────────────────────────────────────────────────── */\n\nexport function StreamText({\n  text,\n  charsPerTick = 2,\n  tickMs = 9,\n  blurTail = 6,\n  caret = true,\n  className,\n  onProgress,\n  onDone,\n}: {\n  text: string;\n  /** characters revealed per tick — higher is faster */\n  charsPerTick?: number;\n  /** interval between reveals, ms */\n  tickMs?: number;\n  /** how many trailing characters carry the soft blur edge */\n  blurTail?: number;\n  /** render the caret (solid while streaming, blinks once idle) */\n  caret?: boolean;\n  className?: string;\n  /** fires each tick — useful for re-anchoring UI to reflowing text */\n  onProgress?: () => void;\n  /** fires once the full string is shown */\n  onDone?: () => void;\n}) {\n  const [count, setCount] = useState(0);\n  const onProgressRef = useRef(onProgress);\n  const onDoneRef = useRef(onDone);\n  onProgressRef.current = onProgress;\n  onDoneRef.current = onDone;\n\n  useEffect(() => {\n    setCount(0);\n    let i = 0;\n    const id = setInterval(() => {\n      i = Math.min(i + charsPerTick, text.length);\n      setCount(i);\n      onProgressRef.current?.();\n      if (i >= text.length) {\n        clearInterval(id);\n        onDoneRef.current?.();\n      }\n    }, tickMs);\n    return () => clearInterval(id);\n  }, [text, charsPerTick, tickMs]);\n\n  const streaming = count < text.length;\n  const shown = text.slice(0, count);\n  const split = streaming ? Math.max(0, shown.length - blurTail) : shown.length;\n\n  return (\n    <span className={className}>\n      {shown.slice(0, split)}\n      {split < shown.length && (\n        <span className=\"stream-tail\">{shown.slice(split)}</span>\n      )}\n      {caret && (\n        <span\n          aria-hidden\n          className={`stream-caret${streaming ? \" is-streaming\" : \"\"}`}\n        />\n      )}\n    </span>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-sidebar-nav",
      "type": "registry:block",
      "title": "Beautiful Original Sidebar Nav",
      "description": "Original Beautiful UI SidebarNav",
      "dependencies": [
        "lucide-react@0.577.0",
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/SidebarNav.tsx",
          "target": "@components/beautiful-ui/original/primitives/SidebarNav.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n  Bot as IconPopsicle2,\n  Check as IconCheckmark1Small,\n  ChevronDown as IconChevronDownSmall,\n  Home as IconHome,\n  LogOut as IconArrowBoxLeft,\n  PanelLeftClose as IconSidebarLeftArrow,\n  Plus as IconPlusMedium,\n  Search as IconMagnifyingGlass,\n  Settings as IconSettingsGear1,\n  SquarePen as IconEditBig,\n  UserPlus as IconUserAdd,\n  X as IconCrossSmall,\n} from \"lucide-react\";\nimport GlideMenu from \"./GlideMenu\";\n\n/* ─────────────────────────────────────────────────────────\n * SIDEBAR NAV\n * Shared by the design-system preview and the harness shell:\n * compact workspace switcher, primary navigation, searchable\n * chat history, and a collapse that preserves icon alignment.\n * ───────────────────────────────────────────────────────── */\n\nconst WORKSPACE = { key: \"fieldwork\", name: \"Fieldwork\", monogram: \"F\" };\n\nconst NAV_ITEMS = [\n  { key: \"home\", label: \"Home\", icon: <IconHome size={18} /> },\n  { key: \"invite\", label: \"Invite users\", icon: <IconUserAdd size={18} />, count: \"3/10\" },\n];\n\nexport type SidebarRecent = {\n  id: string;\n  label: string;\n  prompt?: string;\n};\n\nconst DEFAULT_RECENTS: SidebarRecent[] = [\n  { id: \"suppliers\", label: \"Supplier records\" },\n  { id: \"todos\", label: \"Urgent to-dos this morning\" },\n  { id: \"flavor\", label: \"Flavor page ticket\" },\n  { id: \"workload\", label: \"Workload summary\" },\n  { id: \"offboarding\", label: \"Off-board a supplier\" },\n  { id: \"restock\", label: \"Batch restock function\" },\n  { id: \"edits\", label: \"Propose flavor edits\" },\n  { id: \"subway\", label: \"Subway surfing\" },\n];\n\ntype SidebarNavProps = {\n  activeTitle?: string | null;\n  className?: string;\n  fill?: boolean;\n  onNewChat?: () => void;\n  onPick?: (id: string, label: string, prompt?: string) => void;\n  /** controlled primary-nav selection (e.g. \"home\" | \"invite\") */\n  activeNav?: string;\n  onNavigate?: (key: string) => void;\n  /** footer call-to-action — defaults to the demo \"Upgrade\" button */\n  footerLabel?: string;\n  footerIcon?: ReactNode;\n  onFooterClick?: () => void;\n  recents?: SidebarRecent[];\n  variant?: string;\n};\n\nconst SIDEBAR_MOTION = {\n  expandedWidth: 224,\n  collapsedWidth: 52,\n  duration: 280,\n  copyDuration: 180,\n  copyOffset: 8,\n  easing: \"cubic-bezier(0.16, 1, 0.3, 1)\",\n};\n\n/* ─────────────────────────────────────────────────────────\n * CHAT SEARCH STORYBOARD\n *\n *   0ms   search is triggered; Chats label begins fading\n *   0ms   field grows right → left from the search control\n * 180ms   field fills the row; cursor is focused and ready\n * ───────────────────────────────────────────────────────── */\nconst CHAT_SEARCH_MOTION = {\n  duration: 180,\n  closedWidth: 28,\n  easing: \"cubic-bezier(0.16, 1, 0.3, 1)\",\n};\n\nfunction GlideGroup({ children }: { children: ReactNode }) {\n  return (\n    <GlideMenu\n      rowSelector=\"[data-row]\"\n      highlightClassName=\"sidebar-glide-highlight rounded-[7px] bg-hover-2\"\n      className=\"group/glide flex flex-col gap-px\"\n    >\n      {children}\n    </GlideMenu>\n  );\n}\n\nfunction RailButton({\n  icon,\n  label,\n  active = false,\n  count,\n  onClick,\n}: {\n  icon: ReactNode;\n  label: string;\n  active?: boolean;\n  count?: string;\n  onClick?: () => void;\n}) {\n  return (\n    <button\n      data-row\n      type=\"button\"\n      onClick={onClick}\n      className={`sidebar-row relative z-10 mx-2 flex h-8 items-center rounded-[8px] px-2 text-left\n        transition-[width,background-color,color,transform] duration-150 active:scale-[0.98]\n        ${active ? \"bg-hover-2 group-hover/glide:bg-transparent\" : \"\"}`}\n    >\n      <span className={`flex size-5 shrink-0 items-center justify-center ${active ? \"text-ink\" : \"text-ink-2\"}`}>\n        {icon}\n      </span>\n      <span className={`sidebar-copy ml-1.5 min-w-0 flex-1 truncate text-[14px] font-medium ${active ? \"text-ink\" : \"text-ink-2\"}`}>\n        {label}\n      </span>\n      {count && (\n        <span className=\"sidebar-copy mr-2 shrink-0 text-[12px] font-medium tabular-nums text-ink-3\">\n          {count}\n        </span>\n      )}\n    </button>\n  );\n}\n\nfunction WorkspaceMenu({\n  position,\n  onClose,\n}: {\n  position: { top: number; left: number };\n  onClose: () => void;\n}) {\n  return createPortal(\n    <div\n      data-workspace-menu\n      className=\"beautiful-ui-scope fixed z-50 w-64 rounded-[14px] bg-surface p-1.5 text-ink shadow-overlay\"\n      style={{\n        top: position.top,\n        left: position.left,\n        animation: \"beautiful-pop-in 180ms cubic-bezier(0.23,1,0.32,1) both\",\n        transformOrigin: \"top left\",\n      }}\n    >\n      <GlideMenu className=\"flex flex-col gap-px\" highlightClassName=\"inset-x-0 rounded-[8px] bg-hover-2\">\n        <button\n          data-menu-row\n          type=\"button\"\n          onClick={onClose}\n          className=\"relative z-10 flex h-10 w-full items-center gap-1.5 rounded-[8px] px-2 text-left\"\n        >\n          <span className=\"flex size-6 shrink-0 items-center justify-center rounded-[7px] bg-ink text-[11px] font-semibold text-surface\">\n            {WORKSPACE.monogram}\n          </span>\n          <span className=\"min-w-0 flex-1 truncate text-[13.5px] font-medium text-ink\">{WORKSPACE.name}</span>\n          <span className=\"shrink-0 text-ink\"><IconCheckmark1Small size={18} /></span>\n        </button>\n        <div className=\"my-1 h-px bg-line\" />\n        {[\n          { label: \"New workspace\", icon: <IconPlusMedium size={16} /> },\n          { label: \"Workspace settings\", icon: <IconSettingsGear1 size={16} /> },\n          { label: \"Invite team members\", icon: <IconUserAdd size={16} /> },\n        ].map((item) => (\n          <button\n            key={item.label}\n            data-menu-row\n            type=\"button\"\n            onClick={onClose}\n            className=\"relative z-10 flex h-9 w-full items-center gap-1.5 rounded-[8px] px-2 text-left\"\n          >\n            <span className=\"flex size-5 shrink-0 items-center justify-center text-ink-2\">{item.icon}</span>\n            <span className=\"min-w-0 flex-1 truncate text-[13.5px] text-ink\">{item.label}</span>\n          </button>\n        ))}\n        <div className=\"my-1 h-px bg-line\" />\n        <button\n          data-menu-row\n          type=\"button\"\n          onClick={onClose}\n          className=\"relative z-10 flex h-9 w-full items-center gap-1.5 rounded-[8px] px-2 text-left\"\n        >\n          <span className=\"flex size-5 shrink-0 items-center justify-center text-ink-2\"><IconArrowBoxLeft size={16} /></span>\n          <span className=\"min-w-0 flex-1 truncate text-[13.5px] text-ink\">Sign out</span>\n        </button>\n      </GlideMenu>\n    </div>,\n    document.body,\n  );\n}\n\nexport default function SidebarNav({\n  activeTitle,\n  className = \"\",\n  fill = false,\n  onNewChat,\n  onPick,\n  activeNav,\n  onNavigate,\n  footerLabel = \"Upgrade\",\n  footerIcon,\n  onFooterClick,\n  recents = DEFAULT_RECENTS,\n}: SidebarNavProps) {\n  const [collapsed, setCollapsed] = useState(false);\n  const [internalNav, setInternalNav] = useState(\"chats\");\n  const currentNav = activeNav ?? internalNav;\n  const selectNav = (key: string) => {\n    setInternalNav(key);\n    onNavigate?.(key);\n  };\n  const [demoActiveTitle, setDemoActiveTitle] = useState<string | null>(null);\n  const [workspaceOpen, setWorkspaceOpen] = useState(false);\n  const [workspacePosition, setWorkspacePosition] = useState({ top: 0, left: 0 });\n  const [searchOpen, setSearchOpen] = useState(false);\n  const [query, setQuery] = useState(\"\");\n  const workspaceButtonRef = useRef<HTMLButtonElement>(null);\n  const searchRef = useRef<HTMLInputElement>(null);\n\n  const selectedTitle = activeTitle === undefined ? demoActiveTitle : activeTitle;\n  const visibleRecents = recents.filter((item) => item.label.toLowerCase().includes(query.trim().toLowerCase()));\n\n  useEffect(() => {\n    if (!workspaceOpen) return;\n    const close = (event: PointerEvent) => {\n      const target = event.target as Element;\n      if (!target.closest(\"[data-workspace-trigger]\") && !target.closest(\"[data-workspace-menu]\")) {\n        setWorkspaceOpen(false);\n      }\n    };\n    document.addEventListener(\"pointerdown\", close);\n    return () => document.removeEventListener(\"pointerdown\", close);\n  }, [workspaceOpen]);\n\n  useEffect(() => {\n    if (searchOpen) searchRef.current?.focus();\n  }, [searchOpen]);\n\n  const collapse = () => {\n    setCollapsed(true);\n    setWorkspaceOpen(false);\n    setSearchOpen(false);\n    setQuery(\"\");\n  };\n\n  return (\n    <aside\n      data-sidebar-collapsed={collapsed}\n      aria-label=\"Workspace navigation\"\n      className={`relative flex shrink-0 overflow-hidden transition-[width] ${fill ? \"h-full\" : \"h-[600px]\"} ${className}`}\n      style={{\n        width: collapsed ? SIDEBAR_MOTION.collapsedWidth : SIDEBAR_MOTION.expandedWidth,\n        transitionDuration: `${SIDEBAR_MOTION.duration}ms`,\n        transitionTimingFunction: SIDEBAR_MOTION.easing,\n        \"--sidebar-copy-duration\": `${SIDEBAR_MOTION.copyDuration}ms`,\n        \"--sidebar-copy-offset\": `${SIDEBAR_MOTION.copyOffset}px`,\n        \"--sidebar-easing\": SIDEBAR_MOTION.easing,\n      } as CSSProperties}\n    >\n      <div className=\"flex min-h-0 w-[224px] shrink-0 flex-col\">\n        <div className=\"relative mb-2.5 h-10 shrink-0\">\n          <button\n            ref={workspaceButtonRef}\n            data-workspace-trigger\n            type=\"button\"\n            aria-expanded={workspaceOpen}\n            aria-hidden={collapsed}\n            tabIndex={collapsed ? -1 : 0}\n            onClick={() => {\n              if (!workspaceOpen && workspaceButtonRef.current) {\n                const rect = workspaceButtonRef.current.getBoundingClientRect();\n                setWorkspacePosition({ top: rect.bottom + 6, left: rect.left });\n              }\n              setWorkspaceOpen((open) => !open);\n            }}\n            className=\"sidebar-workspace-control absolute left-2 top-1 flex h-8 w-[164px] items-center rounded-[8px] px-2 text-left transition-[background-color,transform] duration-100 hover:bg-hover-2 active:scale-[0.99]\"\n          >\n            <span className=\"sidebar-logo flex size-5 shrink-0 items-center justify-center text-ink\">\n              <IconPopsicle2 size={18} />\n            </span>\n            <span className=\"sidebar-copy ml-1.5 min-w-0 flex-1 truncate text-[14px] font-medium text-ink-2\">\n              {WORKSPACE.name}\n            </span>\n            <span className=\"sidebar-copy ml-1 flex shrink-0 text-ink-3\">\n              <IconChevronDownSmall size={16} />\n            </span>\n          </button>\n\n          {workspaceOpen && <WorkspaceMenu position={workspacePosition} onClose={() => setWorkspaceOpen(false)} />}\n\n          <button\n            type=\"button\"\n            aria-label=\"Collapse sidebar\"\n            aria-hidden={collapsed}\n            tabIndex={collapsed ? -1 : 0}\n            onClick={collapse}\n            className=\"sidebar-collapse-control absolute right-2 top-1 flex size-8 items-center justify-center rounded-[8px] text-ink-3 transition-[opacity,background-color,color] duration-150 hover:bg-hover-2 hover:text-ink\"\n          >\n            <IconSidebarLeftArrow size={18} />\n          </button>\n          <button\n            type=\"button\"\n            aria-label=\"Expand sidebar\"\n            aria-hidden={!collapsed}\n            tabIndex={collapsed ? 0 : -1}\n            onClick={() => setCollapsed(false)}\n            className=\"sidebar-expand-control absolute left-2 top-0.5 flex size-9 items-center justify-center rounded-[8px] text-ink-3 transition-[opacity,background-color,color] duration-150 hover:bg-hover-2 hover:text-ink\"\n          >\n            <IconSidebarLeftArrow size={18} className=\"rotate-180\" />\n          </button>\n        </div>\n\n        <GlideGroup>\n          <RailButton\n            icon={<IconEditBig size={18} />}\n            label=\"New chat\"\n            onClick={() => {\n              if (activeTitle === undefined) setDemoActiveTitle(null);\n              selectNav(\"chats\");\n              onNewChat?.();\n            }}\n          />\n          {NAV_ITEMS.map((item) => (\n            <RailButton\n              key={item.key}\n              icon={item.icon}\n              label={item.label}\n              count={item.count}\n              active={currentNav === item.key}\n              onClick={() => selectNav(item.key)}\n            />\n          ))}\n        </GlideGroup>\n\n        <div className=\"mt-3 min-h-0 flex-1 overflow-y-auto\">\n          <div className=\"sidebar-copy relative mx-2 mb-1 h-8\">\n            <div\n              aria-hidden={searchOpen}\n              className={`absolute inset-0 flex items-center gap-1.5 px-2 text-[12.5px] font-medium text-ink-3 transition-[opacity,transform] ${searchOpen ? \"pointer-events-none -translate-x-1 opacity-0\" : \"translate-x-0 opacity-100\"}`}\n              style={{ transitionDuration: `${CHAT_SEARCH_MOTION.duration}ms`, transitionTimingFunction: CHAT_SEARCH_MOTION.easing }}\n            >\n              <IconChevronDownSmall size={16} />\n              <span>Chats</span>\n            </div>\n\n            <button\n              type=\"button\"\n              aria-label=\"Search chats\"\n              aria-expanded={searchOpen}\n              onClick={() => setSearchOpen(true)}\n              className={`absolute right-0 top-0 z-10 flex size-8 items-center justify-center rounded-[8px] text-ink-3 transition-[opacity,background-color,color,transform] hover:bg-hover-2 hover:text-ink active:scale-[0.96] ${searchOpen ? \"pointer-events-none opacity-0\" : \"opacity-100\"}`}\n              style={{ transitionDuration: `${CHAT_SEARCH_MOTION.duration}ms` }}\n            >\n              <IconMagnifyingGlass size={16} />\n            </button>\n\n            <div\n              className={`absolute right-0 top-0 z-20 flex h-8 items-center overflow-hidden rounded-[8px] bg-field text-ink-3 shadow-hairline transition-[width,opacity] focus-within:text-ink-2 ${searchOpen ? \"pointer-events-auto opacity-100\" : \"pointer-events-none opacity-0\"}`}\n              style={{\n                width: searchOpen ? \"100%\" : CHAT_SEARCH_MOTION.closedWidth,\n                transitionDuration: `${CHAT_SEARCH_MOTION.duration}ms`,\n                transitionTimingFunction: CHAT_SEARCH_MOTION.easing,\n              }}\n            >\n              <span className=\"ml-2 flex shrink-0 items-center justify-center\">\n                <IconMagnifyingGlass size={15} />\n              </span>\n              <input\n                ref={searchRef}\n                value={query}\n                onChange={(event) => setQuery(event.target.value)}\n                onKeyDown={(event) => {\n                  if (event.key === \"Escape\") {\n                    setSearchOpen(false);\n                    setQuery(\"\");\n                  }\n                }}\n                placeholder=\"Search chats\"\n                aria-label=\"Search chat history\"\n                className=\"ml-1.5 min-w-0 flex-1 bg-transparent text-[13px] font-medium text-ink outline-none placeholder:text-ink-3\"\n              />\n              <button\n                type=\"button\"\n                aria-label=\"Close chat search\"\n                onClick={() => {\n                  setSearchOpen(false);\n                  setQuery(\"\");\n                }}\n                className=\"flex size-8 shrink-0 items-center justify-center rounded-[8px] text-ink-3 transition-[background-color,color,transform] duration-150 hover:bg-hover-2 hover:text-ink active:scale-[0.96]\"\n              >\n                <IconCrossSmall size={16} />\n              </button>\n            </div>\n          </div>\n\n          <GlideGroup>\n            {visibleRecents.map((item) => {\n              const active = item.label === selectedTitle;\n              return (\n                <button\n                  key={item.id}\n                  data-row\n                  type=\"button\"\n                  title={item.label}\n                  onClick={() => {\n                    selectNav(\"chats\");\n                    if (activeTitle === undefined) setDemoActiveTitle(item.label);\n                    onPick?.(item.id, item.label, item.prompt);\n                  }}\n                  className={`sidebar-row relative z-10 mx-2 flex h-8 items-center rounded-[8px] px-2 text-left transition-[width,background-color,color,transform] duration-150 active:scale-[0.98] ${\n                    active ? \"bg-hover-2 group-hover/glide:bg-transparent\" : \"\"\n                  }`}\n                >\n                  <span className={`sidebar-copy min-w-0 flex-1 truncate text-[14px] font-medium ${active ? \"text-ink\" : \"text-ink-2\"}`}>\n                    {item.label}\n                  </span>\n                </button>\n              );\n            })}\n            {query && visibleRecents.length === 0 && (\n              <div className=\"sidebar-copy mx-2 px-2 py-2 text-[12.5px] text-ink-3\">No chats found</div>\n            )}\n          </GlideGroup>\n        </div>\n\n        <div className=\"sidebar-copy mx-2 mt-3 w-[208px] border-t border-line pt-3\">\n          <button\n            type=\"button\"\n            onClick={onFooterClick ?? onNewChat}\n            className=\"flex h-8 w-full items-center justify-center gap-1.5 rounded-control bg-hover-2 text-[12.5px] font-medium text-ink transition-[background-color,transform] duration-150 hover:bg-line-strong active:scale-[0.98]\"\n          >\n            {footerIcon}\n            {footerLabel}\n          </button>\n        </div>\n      </div>\n    </aside>\n  );\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "target": "@components/beautiful-ui/original/primitives/GlideMenu.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useRef, useState, type ReactNode } from \"react\";\n\ntype GlideMenuProps = {\n  children: ReactNode;\n  className?: string;\n  highlightClassName?: string;\n  rowSelector?: string;\n};\n\n/** A single hover layer that glides between interactive menu rows. */\nexport default function GlideMenu({\n  children,\n  className = \"\",\n  highlightClassName = \"inset-x-0 rounded-[8px] bg-hover\",\n  rowSelector = \"[data-menu-row]\",\n}: GlideMenuProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const [box, setBox] = useState<{ top: number; height: number } | null>(null);\n  const [visible, setVisible] = useState(false);\n\n  const moveTo = (target: EventTarget | null) => {\n    const container = ref.current;\n    if (!(target instanceof Element) || !container) return;\n    const row = target.closest(rowSelector);\n    if (!(row instanceof HTMLElement) || !container.contains(row)) return;\n    const containerRect = container.getBoundingClientRect();\n    const rowRect = row.getBoundingClientRect();\n    setBox({ top: rowRect.top - containerRect.top, height: rowRect.height });\n    setVisible(true);\n  };\n\n  return (\n    <div\n      ref={ref}\n      onMouseOver={(event) => moveTo(event.target)}\n      onMouseLeave={() => setVisible(false)}\n      onFocusCapture={(event) => moveTo(event.target)}\n      onBlurCapture={(event) => {\n        if (!ref.current?.contains(event.relatedTarget as Node | null)) setVisible(false);\n      }}\n      className={`group/glide-menu relative ${className}`}\n    >\n      <span\n        aria-hidden\n        className={`pointer-events-none absolute ${highlightClassName}`}\n        style={{\n          top: box?.top ?? 0,\n          height: box?.height ?? 0,\n          opacity: box && visible ? 1 : 0,\n          transition:\n            \"top 220ms cubic-bezier(0.23,1,0.32,1), height 220ms cubic-bezier(0.23,1,0.32,1), opacity 150ms ease\",\n        }}\n      />\n      {children}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-streaming-text",
      "type": "registry:block",
      "title": "Beautiful Original Streaming Text",
      "description": "Original Beautiful UI StreamingText",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/StreamingText.tsx",
          "target": "@components/beautiful-ui/original/primitives/StreamingText.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * STREAMING TEXT\n * Words resolve out of blur, inline citations appear in\n * context, then actions and follow-up prompts become usable.\n * ───────────────────────────────────────────────────────── */\n\nconst WORD_MS = 55;\nconst HOLD_MS = 3400;\n\n/* one streamed word, or a `cite` placeholder that renders an inline source chip */\nexport type StreamingToken = { text: string; cite?: boolean };\n\nconst TOKENS: StreamingToken[] = [\n  ...\"Pistachio is your fastest-growing flavor — sales are up 23% this month and margins beat vanilla by 8 points.\"\n    .split(\" \")\n    .map((text) => ({ text })),\n  { text: \"\", cite: true },\n  ...\"Stone-fruit flavors are trending in the same range.\"\n    .split(\" \")\n    .map((text) => ({ text })),\n];\n\nconst FOLLOW_UPS = [\n  \"Which flavors sell best in winter\",\n  \"Compare gelato and soft serve margins\",\n];\n\nconst SOURCE_IMAGES = {\n  scoop:\n    \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='16' fill='%231f7a5f'/%3E%3Cpath d='M20 36c0 7 5.4 12 12 12s12-5 12-12H20Z' fill='%23fff'/%3E%3Ccircle cx='32' cy='25' r='11' fill='%23bff3dd'/%3E%3Cpath d='M24 24c4-7 13-7 17 0' fill='none' stroke='%231f7a5f' stroke-width='4' stroke-linecap='round'/%3E%3C/svg%3E\",\n  trends:\n    \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='16' fill='%232f6fec'/%3E%3Cpath d='M15 43 27 31l8 7 14-18' fill='none' stroke='%23fff' stroke-width='7' stroke-linecap='round' stroke-linejoin='round'/%3E%3Ccircle cx='49' cy='20' r='5' fill='%23bfe0ff'/%3E%3C/svg%3E\",\n  market:\n    \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='16' fill='%23e56d24'/%3E%3Cpath d='M17 45V25h8v20h-8Zm11 0V16h8v29h-8Zm11 0V30h8v15h-8Z' fill='%23fff'/%3E%3Cpath d='M16 49h32' stroke='%23ffd6b8' stroke-width='4' stroke-linecap='round'/%3E%3C/svg%3E\",\n};\n\n/* one cited source rendered as an inline chip and in the sources list */\nexport type StreamingSource = { name: string; domain: string; href: string; image: string };\n\nconst SOURCES: StreamingSource[] = [\n  { name: \"Scoop Data\", domain: \"scoopdata.io\", href: \"https://scoopdata.io/\", image: SOURCE_IMAGES.scoop },\n  { name: \"Trends Index\", domain: \"trends.google.com\", href: \"https://trends.google.com/trends/\", image: SOURCE_IMAGES.trends },\n  { name: \"Market Basket\", domain: \"marketbasket.io\", href: \"https://marketbasket.io/\", image: SOURCE_IMAGES.market },\n];\n\nfunction sourceImage(source: StreamingSource) {\n  return source.image;\n}\n\nfunction SourceChip({ source }: { source?: StreamingSource }) {\n  if (!source) return null;\n  return (\n    <a\n      href={source.href}\n      target=\"_blank\"\n      rel=\"noreferrer\"\n      className=\"ml-0 mr-1 inline-flex h-4.5 translate-y-[-1px] items-center gap-1 rounded-[5px]\n        bg-inset pr-[3px] pl-[3px] align-middle font-mono text-[10.5px] text-ink-2 shadow-hairline\n        transition-colors duration-150 hover:bg-hover hover:text-ink\"\n      style={{ animation: \"beautiful-pop-in 250ms cubic-bezier(0.23,1,0.32,1) both\" }}\n    >\n      <img src={sourceImage(source)} alt=\"\" className=\"source-avatar size-3 rounded-[3px]\" />\n      <span>{source.domain}</span>\n    </a>\n  );\n}\n\nconst ACTION_ICONS: React.ReactNode[] = [\n  <g key=\"copy\"><rect x=\"9\" y=\"9\" width=\"12\" height=\"12\" rx=\"2.5\" /><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" /></g>,\n  <path key=\"retry\" d=\"M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6\" />,\n  <path key=\"up\" d=\"M7 10v12M15 5.88L14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88z\" />,\n  <path key=\"down\" d=\"M17 14V2M9 18.12L10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88z\" />,\n];\n\nexport type StreamingLabels = {\n  /** label on the collapsed sources toggle */\n  sources: string;\n  /** heading above the follow-up prompts */\n  followUps: string;\n};\n\nconst DEFAULT_LABELS: StreamingLabels = {\n  sources: \"10 sources\",\n  followUps: \"Follow-ups\",\n};\n\nexport default function StreamingText({\n  content = TOKENS,\n  sources = SOURCES,\n  followUps = FOLLOW_UPS,\n  labels,\n  loop = true,\n  fill = false,\n  onDone,\n  onFollowUp,\n}: {\n  variant?: string;\n  /** the streamed tokens; `cite` tokens render an inline source chip */\n  content?: StreamingToken[];\n  /** cited sources shown in the chip, avatar stack, and expanded list */\n  sources?: StreamingSource[];\n  /** follow-up prompt suggestions shown once the stream completes */\n  followUps?: string[];\n  /** prominent copy strings */\n  labels?: Partial<StreamingLabels>;\n  /** restart the stream after a hold; turn off when embedding in a real thread */\n  loop?: boolean;\n  /** fill the parent width instead of the gallery's fixed measure */\n  fill?: boolean;\n  onDone?: () => void;\n  /** fired when a follow-up prompt is chosen */\n  onFollowUp?: (text: string, index: number) => void;\n} = {}) {\n  const l = { ...DEFAULT_LABELS, ...labels };\n  const [count, setCount] = useState(0);\n  const [sourcesOpen, setSourcesOpen] = useState(false);\n  const done = count >= content.length;\n\n  useEffect(() => {\n    if (done && !loop) {\n      onDone?.();\n      return;\n    }\n    const t = setTimeout(\n      () => setCount((c) => (c >= content.length ? 0 : c + 1)),\n      done ? HOLD_MS : WORD_MS,\n    );\n    return () => clearTimeout(t);\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [count, done, loop]);\n\n  return (\n    <div className={fill ? \"w-full\" : \"min-h-[15.5rem] w-full max-w-95\"}>\n      <p className=\"text-[13px] leading-relaxed text-ink\">\n        {content.slice(0, count).map((token, i) =>\n          token.cite ? (\n            <SourceChip key={i} source={sources[0]} />\n          ) : (\n            <span key={i} className=\"inline\">\n              {token.text}{\" \"}\n            </span>\n          ),\n        )}\n        {!done && (\n          <span\n            className=\"ml-0.5 inline-block h-3 w-0.5 translate-y-0.5 rounded-full bg-ink\"\n            style={{ animation: \"beautiful-fade-in 150ms ease-out both\" }}\n          />\n        )}\n      </p>\n\n      {/* action icons row */}\n      <div\n        className=\"mt-2 flex items-center gap-0.5 transition-opacity duration-400\"\n        style={{ opacity: done ? 1 : 0, pointerEvents: done ? \"auto\" : \"none\" }}\n      >\n        {ACTION_ICONS.map((icon, i) => (\n          <button\n            key={i}\n            type=\"button\"\n            aria-label=\"Action\"\n            className=\"flex size-6 items-center justify-center rounded-[6px] text-ink-3\n              transition-colors duration-100 hover:bg-hover-2 hover:text-ink-2\"\n          >\n            <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n              {icon}\n            </svg>\n          </button>\n        ))}\n        <button\n          type=\"button\"\n          aria-expanded={sourcesOpen}\n          onClick={() => setSourcesOpen((current) => !current)}\n          className=\"ml-1.5 flex items-center gap-1.5 rounded-[6px] px-1 py-0.5 text-left transition-colors duration-150 hover:bg-hover\"\n        >\n          <span className=\"flex -space-x-1\">\n            {sources.map((source) => (\n              <img\n                key={source.domain}\n                src={sourceImage(source)}\n                alt=\"\"\n                className=\"source-avatar size-3.5 rounded-full bg-surface shadow-[0_0_0_1.5px_var(--canvas)]\"\n              />\n            ))}\n          </span>\n          <span className=\"text-[12px] text-ink-2\">{l.sources}</span>\n        </button>\n      </div>\n\n      <div\n        className=\"grid transition-[grid-template-rows,opacity] duration-300\"\n        style={{\n          gridTemplateRows: done && sourcesOpen ? \"1fr\" : \"0fr\",\n          opacity: done && sourcesOpen ? 1 : 0,\n          transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n        }}\n      >\n        <div className=\"overflow-hidden\">\n          <div className=\"mt-1.5 flex flex-col rounded-[10px] bg-inset p-1 shadow-hairline\">\n            {sources.map((source) => (\n              <a\n                key={source.domain}\n                href={source.href}\n                target=\"_blank\"\n                rel=\"noreferrer\"\n                className=\"flex items-center gap-2 rounded-[6px] px-1.5 py-1 text-[12px] text-ink-2 transition-colors duration-150 hover:bg-hover hover:text-ink\"\n              >\n                <img src={sourceImage(source)} alt=\"\" className=\"source-avatar size-4 rounded-[4px]\" />\n                <span className=\"animated-underline\">{source.name}</span>\n                <span className=\"ml-auto font-mono text-[10.5px] text-ink-3\">{source.domain}</span>\n              </a>\n            ))}\n          </div>\n        </div>\n      </div>\n\n      {/* follow-ups */}\n      <div\n        className=\"mt-2.5 transition-opacity duration-400\"\n        style={{ opacity: done ? 1 : 0, pointerEvents: done ? \"auto\" : \"none\" }}\n      >\n        <p className=\"text-[12px] font-medium text-ink-2\">{l.followUps}</p>\n        <div className=\"mt-0.5 flex flex-col\">\n          {followUps.map((text, i) => (\n            <button\n              key={text}\n              onClick={() => onFollowUp?.(text, i)}\n              className=\"-mx-1.5 flex items-center gap-2 rounded-[7px] border-b border-line\n                px-1.5 py-1.5 text-left text-[12.5px] text-ink transition-colors\n                duration-100 hover:bg-hover-2\"\n              style={\n                done\n                  ? { animation: `beautiful-fade-up 350ms cubic-bezier(0.23,1,0.32,1) ${i * 90}ms both` }\n                  : { opacity: 0 }\n              }\n            >\n              <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--ink-3)\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"shrink-0\">\n                <path d=\"M9 10l-5 5 5 5\" />\n                <path d=\"M20 4v7a4 4 0 0 1-4 4H4\" />\n              </svg>\n              {text}\n            </button>\n          ))}\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-task-rows",
      "type": "registry:block",
      "title": "Beautiful Original Task Rows",
      "description": "Original Beautiful UI TaskRows",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/TaskRows.tsx",
          "target": "@components/beautiful-ui/original/primitives/TaskRows.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * TASK ROWS\n *\n *     0ms   rows enter staggered (80ms apart)\n *   600ms   row 1 ring sweeps 0 → 66%\n *  1500ms   row 1 expands — detail steps drop down\n *  3900ms   row 1 collapses; row 2 flips to Failed + retry\n *  5300ms   row 2 resolves to Completed\n * The status run completes once; task details stay clickable.\n * ───────────────────────────────────────────────────────── */\n\nconst TICKS = [600, 900, 2400, 1400, 2400, 600];\n\nfunction useTick(intervals: number[]) {\n  const [tick, setTick] = useState(0);\n  useEffect(() => {\n    if (tick >= intervals.length - 1) return;\n    const t = setTimeout(() => setTick((x) => x + 1), intervals[tick]);\n    return () => clearTimeout(t);\n  }, [tick, intervals]);\n  return tick;\n}\n\nfunction SpinnerRing({ active, children }: { active?: boolean; children?: React.ReactNode }) {\n  const size = 24, stroke = 2;\n  const r = (size - stroke) / 2;\n  const c = 2 * Math.PI * r;\n  return (\n    <span className=\"relative inline-flex shrink-0 items-center justify-center\" style={{ width: size, height: size }}>\n      <svg\n        width={size} height={size} className=\"absolute inset-0\"\n        style={active ? { animation: \"beautiful-spin 1.1s linear infinite\" } : undefined}\n      >\n        <circle cx={size / 2} cy={size / 2} r={r} fill=\"none\" stroke=\"var(--line)\" strokeWidth={stroke} />\n        {active && (\n          <circle\n            cx={size / 2} cy={size / 2} r={r} fill=\"none\"\n            stroke=\"var(--ink-3)\" strokeWidth={stroke} strokeLinecap=\"round\"\n            strokeDasharray={`${c * 0.28} ${c * 0.72}`}\n          />\n        )}\n      </svg>\n      <span className=\"relative text-[10.5px] font-semibold tabular-nums text-ink\">{children}</span>\n    </span>\n  );\n}\n\nfunction Badge({ tone, children }: { tone: \"red\" | \"green\"; children: React.ReactNode }) {\n  return (\n    <span\n      className={`flex size-5.5 shrink-0 items-center justify-center rounded-full text-white\n        ${tone === \"red\" ? \"bg-red\" : \"bg-green\"}`}\n      style={{ animation: \"beautiful-pop-in 300ms cubic-bezier(0.23,1,0.32,1) both\" }}\n    >\n      {children}\n    </span>\n  );\n}\n\nconst XIcon = (\n  <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3.5\" strokeLinecap=\"round\"><path d=\"M18 6L6 18M6 6l12 12\" /></svg>\n);\nconst CheckIcon = (\n  <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M20 6L9 17l-5-5\" /></svg>\n);\nconst RetryIcon = (\n  <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6\" /></svg>\n);\n\n/* One detail line shown when a task row is expanded. */\nexport type TaskDetail = { label: string; meta: string };\n\n/* A single task row.\n *  - \"done\"     → green check badge + completed pill (static)\n *  - \"running\"  → active spinner showing `step`, no pill (static)\n *  - \"sequence\" → animation-driven: pending spinner → failed → completed\n */\nexport type TaskRow = {\n  key: string;\n  label: string;\n  amount: string;\n  status: \"done\" | \"running\" | \"sequence\";\n  step?: number;\n  details: TaskDetail[];\n};\n\nexport type TaskRowsLabels = {\n  completed: string;\n  failed: string;\n};\n\nconst DEFAULT_LABELS: TaskRowsLabels = {\n  completed: \"Completed\",\n  failed: \"Failed\",\n};\n\nconst TASK_ROWS: TaskRow[] = [\n  {\n    key: \"verify\",\n    label: \"Verified vendor records\",\n    amount: \"12 suppliers\",\n    status: \"done\",\n    details: [\n      { label: \"Matched tax and contact IDs\", meta: \"12/12\" },\n      { label: \"Flagged stale records\", meta: \"0\" },\n    ],\n  },\n  {\n    key: \"index\",\n    label: \"Build reorder task list\",\n    amount: \"7 SKUs\",\n    status: \"running\",\n    step: 2,\n    details: [\n      { label: \"Reading POS export\", meta: \"3 files\" },\n      { label: \"Scoring stockout risk\", meta: \"68%\" },\n    ],\n  },\n  {\n    key: \"draft\",\n    label: \"Draft supplier emails\",\n    amount: \"2 messages\",\n    status: \"sequence\",\n    step: 3,\n    details: [\n      { label: \"Cone supplier follow-up\", meta: \"draft\" },\n      { label: \"Pistachio reorder note\", meta: \"draft\" },\n    ],\n  },\n];\n\nexport default function TaskRows({\n  variant = \"Capsules\",\n  rows = TASK_ROWS,\n  labels,\n  className,\n  onToggleRow,\n}: {\n  variant?: string;\n  rows?: TaskRow[];\n  labels?: Partial<TaskRowsLabels>;\n  className?: string;\n  onToggleRow?: (key: string, open: boolean) => void;\n}) {\n  const tick = useTick(TICKS);\n  const [manualOpen, setManualOpen] = useState<Record<string, boolean>>({});\n  const row2: \"pending\" | \"failed\" | \"done\" = tick < 3 ? \"pending\" : tick === 3 ? \"failed\" : \"done\";\n  const copy = { ...DEFAULT_LABELS, ...labels };\n\n  const badgeFor = (row: TaskRow) => {\n    if (row.status === \"done\") return <Badge tone=\"green\">{CheckIcon}</Badge>;\n    if (row.status === \"running\") return <SpinnerRing active>{row.step}</SpinnerRing>;\n    return row2 === \"pending\" ? (\n      <SpinnerRing>{row.step}</SpinnerRing>\n    ) : row2 === \"failed\" ? (\n      <Badge tone=\"red\">{XIcon}</Badge>\n    ) : (\n      <Badge tone=\"green\">{CheckIcon}</Badge>\n    );\n  };\n\n  const pillFor = (row: TaskRow) => {\n    if (row.status === \"done\")\n      return (\n        <span className=\"inline-flex h-5.5 items-center rounded-full bg-green-tint px-2 text-[11.5px] font-medium text-green\">\n          {copy.completed}\n        </span>\n      );\n    if (row.status === \"running\") return null;\n    return row2 === \"failed\" ? (\n      <span className=\"inline-flex h-5.5 items-center gap-1.5 rounded-full bg-red-tint px-2 text-[11.5px] font-medium text-red\" style={{ animation: \"beautiful-fade-in 200ms ease-out both\" }}>\n        {copy.failed} <span style={{ animation: \"beautiful-spin 1.2s linear infinite\" }} className=\"flex\">{RetryIcon}</span>\n      </span>\n    ) : row2 === \"done\" ? (\n      <span className=\"inline-flex h-5.5 items-center gap-1.5 rounded-full bg-green-tint px-2 text-[11.5px] font-medium text-green\" style={{ animation: \"beautiful-fade-in 200ms ease-out both\" }}>\n        {copy.completed}\n      </span>\n    ) : null;\n  };\n\n  const list = variant === \"List\";\n  return (\n    <div\n      className={`flex w-full max-w-110 flex-col ${\n        list ? \"gap-0 self-start overflow-hidden rounded-card bg-surface shadow-card\" : \"min-h-[196px] gap-2\"\n      }${className ? ` ${className}` : \"\"}`}\n    >\n      {rows.map((row, i) => {\n        const open = manualOpen[row.key] ?? (row.key === \"index\" && tick === 2);\n        return (\n          <div\n            key={row.key}\n            className={`self-stretch overflow-hidden transition-[border-radius,background-color] duration-300 hover:bg-inset ${\n              list ? \"border-b border-line last:border-0\" : \"bg-surface shadow-card\"\n            }`}\n            style={{\n              borderRadius: list ? 0 : open ? 14 : 22,\n              animation: `beautiful-fade-up 450ms cubic-bezier(0.23,1,0.32,1) ${i * 80}ms both`,\n            }}\n          >\n            <button\n              type=\"button\"\n              aria-expanded={open}\n              onClick={() => {\n                setManualOpen((current) => ({ ...current, [row.key]: !open }));\n                onToggleRow?.(row.key, !open);\n              }}\n              className=\"flex h-11 w-full items-center gap-2.5 px-2.5 text-left\"\n            >\n              <span className=\"flex size-6 shrink-0 items-center justify-center\">\n                {badgeFor(row)}\n              </span>\n              <span className=\"min-w-0 flex-1 truncate text-[13px] font-medium text-ink\">\n                {row.label}\n              </span>\n              <span className=\"text-[12.5px] text-ink-2 tabular-nums\">{row.amount}</span>\n              {pillFor(row)}\n              <span\n                aria-hidden=\"true\"\n                className=\"-ml-2 flex size-7 shrink-0 items-center justify-center rounded-full text-ink-3\"\n              >\n                <svg\n                  width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"\n                  className=\"transition-transform duration-300\"\n                  style={{ transform: open ? \"rotate(180deg)\" : \"rotate(0)\" }}\n                >\n                  <path d=\"M6 9l6 6 6-6\" />\n                </svg>\n              </span>\n            </button>\n\n            {/* dropdown detail — same expandable grammar as Chain of Thought */}\n            <div\n              className=\"grid transition-[grid-template-rows,opacity] duration-300\"\n                style={{\n                  gridTemplateRows: open ? \"1fr\" : \"0fr\",\n                  opacity: open ? 1 : 0,\n                  transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n                }}\n              >\n                <div className=\"overflow-hidden\">\n                  <div className=\"mb-2.5 grid grid-cols-[24px_1fr] gap-2.5 px-2.5\">\n                    <span aria-hidden className=\"mx-auto h-full w-px bg-line\" />\n                    <div className=\"flex flex-col gap-1.5\">\n                      {row.details.map((d, j) => (\n                        <div\n                          key={d.label}\n                          className=\"flex items-center justify-between\"\n                          style={\n                            open\n                              ? { animation: `beautiful-fade-up 300ms cubic-bezier(0.23,1,0.32,1) ${120 + j * 100}ms both` }\n                              : undefined\n                          }\n                        >\n                          <span className=\"text-[12px] text-ink-2\">{d.label}</span>\n                          <span className=\"font-mono text-[11.5px] text-ink-3 tabular-nums\">\n                            {d.meta}\n                          </span>\n                        </div>\n                      ))}\n                    </div>\n                  </div>\n                </div>\n              </div>\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-thinking-state",
      "type": "registry:block",
      "title": "Beautiful Original Thinking State",
      "description": "Original Beautiful UI ThinkingState",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/ThinkingState.tsx",
          "target": "@components/beautiful-ui/original/primitives/ThinkingState.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * THINKING — expandable agent trace, four variants\n *\n *   Steps      step list with spinner → muted checks\n *   Reasoning  prose reasoning that expands, then settles\n *   Search     web-search trace: query + sources read\n *   Coding     tool trace: files read, edits, commands\n *\n * The trace runs once, settles, and remains expandable.\n * ───────────────────────────────────────────────────────── */\n\nconst STAGES = [800, 600, 1800, 2600, 1600];\n\nfunction useSequence(steps: number[]) {\n  const [stage, setStage] = useState(0);\n  useEffect(() => {\n    if (stage >= steps.length - 1) return;\n    const t = setTimeout(() => setStage((s) => s + 1), steps[stage]);\n    return () => clearTimeout(t);\n  }, [stage, steps]);\n  return stage;\n}\n\ntype Row = {\n  primary: string;\n  secondary?: string;\n  mono?: boolean;\n  add?: number;\n  del?: number;\n  href?: string;\n};\n\nconst VARIANTS: Record<\n  string,\n  { active: string; done: string; rows: Row[]; query?: string }\n> = {\n  Steps: {\n    active: \"Thinking\",\n    done: \"Thought for 4 seconds\",\n    rows: [\n      { primary: \"Reading flavor briefs\" },\n      { primary: \"Scanning supplier lists\" },\n      { primary: \"Comparing tasting notes\", secondary: \"6 flavors\" },\n      { primary: \"Writing the scoop report\" },\n    ],\n  },\n  Reasoning: {\n    active: \"Thinking\",\n    done: \"Thought for 4 seconds\",\n    rows: [\n      { primary: \"Summer demand spikes for stone-fruit flavors — peach and apricot lead.\" },\n      { primary: \"I should check cone inventory before promoting a waffle-bowl special.\" },\n    ],\n  },\n  Search: {\n    active: \"Searching the web\",\n    done: \"Searched the web\",\n    query: \"best waffle cone supplier\",\n    rows: [\n      { primary: \"Joy Cone\", secondary: \"joycone.com\", href: \"https://joycone.com/fs_products/waffle-cones/\" },\n      { primary: \"WebstaurantStore\", secondary: \"webstaurantstore.com\", href: \"https://www.webstaurantstore.com/ice-cream-shop-supplies.html\" },\n      { primary: \"The Konery\", secondary: \"thekonery.com\", href: \"https://www.thekonery.com/\" },\n    ],\n  },\n  Coding: {\n    active: \"Running tools\",\n    done: \"Ran 3 tools\",\n    rows: [\n      { primary: \"Read\", secondary: \"flavors.ts\", mono: true },\n      { primary: \"Edit\", secondary: \"ChurnSchedule.tsx\", mono: true, add: 74, del: 41 },\n      { primary: \"Run\", secondary: \"npm run freeze\", mono: true },\n    ],\n  },\n};\n\nfunction Dot({ tone }: { tone: string }) {\n  return (\n    <span className={`flex size-3.5 shrink-0 items-center justify-center rounded-full text-white ${tone}`}>\n      <svg width=\"9\" height=\"9\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n        <circle cx=\"12\" cy=\"12\" r=\"9\" />\n        <path d=\"M3.5 12h17M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18\" />\n      </svg>\n    </span>\n  );\n}\n\nconst TONES = [\"bg-accent\", \"bg-orange\", \"bg-green\"];\n\nexport default function ThinkingState({\n  variant = \"Steps\",\n  onSettled,\n  rows,\n  active,\n  done,\n  icon,\n}: {\n  variant?: string;\n  onSettled?: () => void;\n  /** override the built-in trace content (keeps the primitive reusable) */\n  rows?: Row[];\n  active?: string;\n  done?: string;\n  /** override the header glyph (defaults to the sparkle) */\n  icon?: ReactNode;\n}) {\n  const stage = useSequence(STAGES);\n  const [manualExpanded, setManualExpanded] = useState<boolean | null>(null);\n  const [selectedTool, setSelectedTool] = useState<string | null>(null);\n  const base = VARIANTS[variant] ?? VARIANTS.Steps;\n  const v = {\n    ...base,\n    rows: rows ?? base.rows,\n    active: active ?? base.active,\n    done: done ?? base.done,\n  };\n  const autoExpanded = stage >= 1 && stage < 4;\n  const expanded = manualExpanded ?? autoExpanded;\n  const working = stage < 3;\n  const visible = stage < 2 ? 0 : stage === 2 ? Math.min(2, v.rows.length) : v.rows.length;\n  const traceRef = useRef<HTMLDivElement>(null);\n  const [lineHeight, setLineHeight] = useState(0);\n  useLayoutEffect(() => {\n    if (traceRef.current) setLineHeight(traceRef.current.offsetHeight);\n  }, [visible, expanded, variant, stage]);\n\n  /* let embedders sequence content after the trace settles */\n  const settledRef = useRef(false);\n  useEffect(() => {\n    if (working || settledRef.current) return;\n    settledRef.current = true;\n    onSettled?.();\n  }, [working, onSettled]);\n\n  return (\n    <div\n      key={variant}\n      className=\"flex w-full max-w-95 flex-col\"\n      style={{\n        minHeight: working || expanded ? 176 : undefined,\n        transition: \"min-height 400ms cubic-bezier(0.23,1,0.32,1)\",\n      }}\n    >\n      {/* header — shared across variants */}\n      <button\n        type=\"button\"\n        aria-expanded={expanded}\n        onClick={() => setManualExpanded((current) => !(current ?? autoExpanded))}\n        className=\"-mx-1.5 flex w-fit items-center gap-2 rounded-control px-1.5 py-1\n          transition-colors duration-100 hover:bg-hover-2\"\n      >\n        {icon ? (\n          <span className=\"flex shrink-0 transition-colors duration-200\" style={{ color: working ? \"var(--ink-2)\" : \"var(--ink-3)\" }}>\n            {icon}\n          </span>\n        ) : (\n          <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill={working ? \"var(--ink-2)\" : \"var(--ink-3)\"}>\n            <path d=\"M12 2l2.4 7.2L22 12l-7.6 2.8L12 22l-2.4-7.2L2 12l7.6-2.8z\" />\n          </svg>\n        )}\n        <span role=\"status\" className=\"contents\">\n          {working ? (\n            <span\n              className=\"bg-clip-text text-[13px] font-medium whitespace-nowrap text-transparent\"\n              style={{\n                backgroundImage:\n                  \"linear-gradient(90deg, var(--ink-3) 35%, var(--ink) 50%, var(--ink-3) 65%)\",\n                backgroundSize: \"200% 100%\",\n                animation: \"beautiful-shimmer-text 1.4s linear infinite\",\n              }}\n            >\n              {v.active}\n            </span>\n          ) : (\n            <span\n              className=\"text-[13px] font-medium whitespace-nowrap text-ink-2\"\n              style={{ animation: \"beautiful-fade-in 350ms ease-out both\" }}\n            >\n              {v.done}\n            </span>\n          )}\n        </span>\n        <svg\n          width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--ink-3)\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"\n          className=\"transition-transform duration-300\"\n          style={{ transform: expanded ? \"rotate(180deg)\" : \"rotate(0)\" }}\n        >\n          <path d=\"M6 9l6 6 6-6\" />\n        </svg>\n      </button>\n\n      {/* expandable trace */}\n      <div\n        className=\"grid transition-[grid-template-rows,opacity] duration-400\"\n        style={{\n          gridTemplateRows: expanded ? \"1fr\" : \"0fr\",\n          opacity: expanded ? 1 : 0,\n          transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n        }}\n      >\n        <div className=\"overflow-hidden\">\n          <div className=\"relative mt-1 ml-[5px] pl-4\">\n            <span\n              aria-hidden\n              className=\"absolute left-[3px] w-px bg-line\"\n              style={{ top: -8, height: lineHeight ? lineHeight - 2 : 0, transition: \"height 500ms cubic-bezier(0.23,1,0.32,1)\" }}\n            />\n            <div ref={traceRef} className=\"flex flex-col gap-1 py-1\">\n            {v.query && (\n              <div className=\"flex h-6 items-center gap-2 px-1.5\" style={{ animation: expanded ? \"beautiful-fade-up 300ms cubic-bezier(0.23,1,0.32,1) both\" : undefined }}>\n                <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--ink-3)\" strokeWidth=\"2\" strokeLinecap=\"round\" className=\"shrink-0\">\n                  <circle cx=\"11\" cy=\"11\" r=\"7\" />\n                  <path d=\"M21 21l-4.3-4.3\" />\n                </svg>\n                <span className=\"text-[12.5px] text-ink-2\">{v.query}</span>\n              </div>\n            )}\n            {v.rows.slice(0, visible).map((row, i) => {\n              const content = (\n                <>\n                {variant === \"Search\" && <Dot tone={TONES[i % 3]} />}\n                {variant === \"Steps\" && (\n                  i < visible - 1 || !working ? (\n                    <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--ink-3)\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"shrink-0\">\n                      <path d=\"M20 6L9 17l-5-5\" />\n                    </svg>\n                  ) : (\n                    <span className=\"size-3 shrink-0 rounded-full border-[1.5px] border-line-strong border-t-ink-2\" style={{ animation: \"beautiful-spin 700ms linear infinite\" }} />\n                  )\n                )}\n                <span className={`min-w-0 truncate text-[12.5px] ${variant === \"Reasoning\" ? \"whitespace-normal leading-relaxed text-ink-2\" : \"font-medium text-ink\"} ${variant === \"Search\" ? \"animated-underline\" : \"\"}`}>\n                  {row.primary}\n                </span>\n                {row.secondary && (\n                  <span className={`shrink-0 text-[11.5px] text-ink-3 ${row.mono ? \"font-mono\" : \"\"}`}>\n                    {row.secondary}\n                  </span>\n                )}\n                {row.add !== undefined && (\n                  <span className=\"shrink-0 font-mono text-[11px] tabular-nums\">\n                    <span className=\"text-green\">+{row.add}</span>{\" \"}\n                    <span className=\"text-red\">−{row.del}</span>\n                  </span>\n                )}\n                </>\n              );\n              const rowClass = \"flex min-h-7 w-full items-center gap-2 rounded-[6px] px-1.5 py-0.5 text-left\";\n              const animation = { animation: `beautiful-fade-up 320ms cubic-bezier(0.23,1,0.32,1) ${i * 120}ms both` };\n\n              if (variant === \"Search\") {\n                return (\n                  <a\n                    key={row.primary}\n                    href={row.href}\n                    target=\"_blank\"\n                    rel=\"noreferrer\"\n                    className={`${rowClass} transition-colors duration-150 hover:bg-hover`}\n                    style={animation}\n                  >\n                    {content}\n                  </a>\n                );\n              }\n\n              if (variant === \"Coding\") {\n                const selected = selectedTool === row.primary;\n                return (\n                  <button\n                    key={row.primary}\n                    type=\"button\"\n                    aria-pressed={selected}\n                    onClick={() => setSelectedTool(selected ? null : row.primary)}\n                    className={`${rowClass} transition-colors duration-150 ${selected ? \"bg-inset\" : \"hover:bg-hover\"}`}\n                    style={animation}\n                  >\n                    {content}\n                  </button>\n                );\n              }\n\n              return (\n                <div key={row.primary} className={rowClass} style={animation}>\n                  {content}\n                </div>\n              );\n            })}\n            {variant === \"Search\" && stage >= 3 && (\n              <span className=\"text-[12px] text-ink-3\" style={{ animation: \"beautiful-fade-in 300ms ease-out both\" }}>\n                +7 more\n              </span>\n            )}\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beautiful-original-tool-chips",
      "type": "registry:block",
      "title": "Beautiful Original Tool Chips",
      "description": "Original Beautiful UI ToolChips",
      "dependencies": [
        "tailwindcss@^4.1.7"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beautiful-ui/original/primitives/ToolChips.tsx",
          "target": "@components/beautiful-ui/original/primitives/ToolChips.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/* ─────────────────────────────────────────────────────────\n * TOOL CHIPS\n * An agent run as compact rows: tool calls with inline\n * chips, then file-diff chips summarizing the edits.\n * Hover a row to reveal its chevron; every row expands\n * to show what the tool actually did.\n * ───────────────────────────────────────────────────────── */\n\nconst STEP_MS = 700;\n\nconst Icons: Record<string, React.ReactNode> = {\n  think: <path d=\"M12 2l2.4 7.2L22 12l-7.6 2.8L12 22l-2.4-7.2L2 12l7.6-2.8z\" />,\n  write: <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M17 3a2.8 2.8 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5z\" /></g>,\n  run: <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M4 17l6-5-6-5M12 19h8\" /></g>,\n  read: <g fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" /><path d=\"M14 2v6h6\" /></g>,\n};\n\nexport type ToolDetailLine = { text: string; tone?: \"add\" };\n\nexport type ToolStep = {\n  icon: string;\n  label: string;\n  chip: string;\n  mono: boolean;\n  detailMono: boolean;\n  detail: ToolDetailLine[];\n};\n\nexport type ToolDiff = { file: string; add: number; del: number };\n\nexport type ToolDiffLine = { text: string; tone: \"add\" | \"del\" | \"ctx\" };\n\nexport type ToolChipsLabels = {\n  header: string;\n  more: string;\n};\n\nconst DEFAULT_LABELS: ToolChipsLabels = {\n  header: \"4 tool calls, 2 messages\",\n  more: \"+2 more\",\n};\n\nconst ROWS: ToolStep[] = [\n  {\n    icon: \"think\", label: \"Thinking\", chip: \"Planning the churn schedule…\", mono: false, detailMono: false,\n    detail: [\n      { text: \"Weekend demand carries pistachio, so it churns first.\" },\n      { text: \"Batch capacity leaves two evening freezer windows.\" },\n    ],\n  },\n  {\n    icon: \"write\", label: \"Write 204 lines\", chip: \"ChurnSchedule.tsx\", mono: true, detailMono: true,\n    detail: [\n      { text: \"+ const windows = slots.filter((s) => s.temp <= -12)\", tone: \"add\" },\n      { text: \"+ return schedule(windows, { hero: \\\"pistachio\\\" })\", tone: \"add\" },\n    ],\n  },\n  {\n    icon: \"run\", label: \"Rebuild and verify\", chip: \"npm run freeze\", mono: true, detailMono: true,\n    detail: [\n      { text: \"✓ built in 1.2s\" },\n      { text: \"✓ 34 checks passed\" },\n    ],\n  },\n  {\n    icon: \"read\", label: \"Read image\", chip: \"flavor-chart.png\", mono: true, detailMono: false,\n    detail: [\n      { text: \"1280 × 720 · line chart, three summers.\" },\n      { text: \"Mint chip trends up 12% through July.\" },\n    ],\n  },\n];\n\nconst DIFFS: ToolDiff[] = [\n  { file: \"flavors.css\", add: 13, del: 0 },\n  { file: \"ChurnSchedule.tsx\", add: 74, del: 41 },\n  { file: \"menu.ts\", add: 8, del: 2 },\n];\n\n/* hovering a file chip opens its diff — green added, red removed */\nconst DIFF_LINES: Record<string, ToolDiffLine[]> = {\n  \"flavors.css\": [\n    { text: \".scoop-card {\", tone: \"ctx\" },\n    { text: \"  gap: 14px;\", tone: \"del\" },\n    { text: \"  gap: 12px;\", tone: \"add\" },\n    { text: \"  container-type: inline-size;\", tone: \"add\" },\n    { text: \"}\", tone: \"ctx\" },\n  ],\n  \"ChurnSchedule.tsx\": [\n    { text: \"const slots = coldSlots(week);\", tone: \"ctx\" },\n    { text: \"const windows = slots;\", tone: \"del\" },\n    { text: \"const windows = slots.filter(\", tone: \"add\" },\n    { text: \"  (s) => s.temp <= -12,\", tone: \"add\" },\n    { text: \");\", tone: \"add\" },\n  ],\n  \"menu.ts\": [\n    { text: \"export const hero = \\\"mint-chip\\\";\", tone: \"del\" },\n    { text: \"export const hero = \\\"pistachio\\\";\", tone: \"add\" },\n  ],\n};\n\nexport default function ToolChips({\n  steps = ROWS,\n  diffs = DIFFS,\n  diffLines = DIFF_LINES,\n  labels,\n  className,\n  onOpenChange,\n  onToggleRow,\n}: {\n  /** Accepted for gallery/registry parity; ToolChips has no visual variants. */\n  variant?: string;\n  steps?: ToolStep[];\n  diffs?: ToolDiff[];\n  diffLines?: Record<string, ToolDiffLine[]>;\n  labels?: Partial<ToolChipsLabels>;\n  className?: string;\n  onOpenChange?: (open: boolean) => void;\n  onToggleRow?: (label: string, open: boolean) => void;\n} = {}) {\n  const copy = { ...DEFAULT_LABELS, ...labels };\n  const [step, setStep] = useState(0);\n  const [open, setOpen] = useState(true);\n  const [openRows, setOpenRows] = useState<Set<string>>(new Set());\n  /* Rendered in a body portal so animated/translated reply wrappers cannot\n   * redefine the fixed-position coordinate system. */\n  const [preview, setPreview] = useState<{\n    file: string;\n    x: number;\n    top?: number;\n    bottom?: number;\n  } | null>(null);\n  const openPreview = (file: string) => (event: React.SyntheticEvent) => {\n    const rect = (event.currentTarget as Element).closest(\"[data-diffchip]\")!.getBoundingClientRect();\n    const previewHeight = 38 + (diffLines[file]?.length ?? 0) * 19;\n    const fitsBelow = rect.bottom + 6 + previewHeight <= window.innerHeight - 12;\n    setPreview({\n      file,\n      x: Math.max(12, Math.min(rect.left, window.innerWidth - 300)),\n      ...(fitsBelow\n        ? { top: rect.bottom + 6 }\n        : { bottom: window.innerHeight - rect.top + 6 }),\n    });\n  };\n  const closePreview = (file: string) => () =>\n    setPreview((current) => (current?.file === file ? null : current));\n  const total = steps.length + 1; // rows, then diff chips\n\n  useEffect(() => {\n    if (step >= total) return;\n    const t = setTimeout(() => setStep((s) => s + 1), STEP_MS);\n    return () => clearTimeout(t);\n  }, [step, total]);\n\n  const toggleRow = (label: string) =>\n    setOpenRows((current) => {\n      const next = new Set(current);\n      if (next.has(label)) next.delete(label);\n      else next.add(label);\n      onToggleRow?.(label, next.has(label));\n      return next;\n    });\n\n  return (\n    <div className={`min-h-[220px] w-full max-w-80 pb-1${className ? ` ${className}` : \"\"}`}>\n      {/* collapsed run header */}\n      <button\n        type=\"button\"\n        aria-expanded={open}\n        onClick={() =>\n          setOpen((current) => {\n            onOpenChange?.(!current);\n            return !current;\n          })\n        }\n        className=\"-mx-1.5 flex w-fit items-center gap-1.5 rounded-control px-1.5 py-1 text-[12.5px] text-ink-2 transition-colors duration-100 hover:bg-hover-2\"\n      >\n        <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"transition-transform duration-200\" style={{ transform: open ? \"rotate(0deg)\" : \"rotate(-90deg)\" }}>\n          <path d=\"M6 9l6 6 6-6\" />\n        </svg>\n        <span className=\"tabular-nums\">{copy.header}</span>\n      </button>\n\n      {/* tool call rows */}\n      <div className=\"grid transition-[grid-template-rows,opacity] duration-300\" style={{ gridTemplateRows: open ? \"1fr\" : \"0fr\", opacity: open ? 1 : 0 }}>\n        {/* -mx-1 + px-1.5 keeps content at the same x while giving the\n            row hover pills room inside this overflow-hidden clip box */}\n        <div className=\"-mx-1 overflow-hidden px-1.5 pb-1\">\n        <div className=\"mt-1.5 flex flex-col gap-1\">\n          {steps.slice(0, step).map((row) => {\n            const rowOpen = openRows.has(row.label);\n            return (\n            <div key={row.label} style={{ animation: \"beautiful-fade-up 300ms cubic-bezier(0.23,1,0.32,1) both\" }}>\n              <button\n                type=\"button\"\n                aria-expanded={rowOpen}\n                onClick={() => toggleRow(row.label)}\n                className=\"group/row -mx-[3px] flex h-7 w-[calc(100%+6px)] min-w-0 items-center gap-2 rounded-control px-[3px] text-left transition-colors duration-100 hover:bg-hover-2\"\n              >\n                <span className=\"relative flex size-4 shrink-0 items-center justify-center text-ink-3\">\n                  <svg\n                    width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill={row.icon === \"think\" ? \"currentColor\" : \"none\"} stroke=\"currentColor\"\n                    className={`transition-opacity duration-100 group-hover/row:opacity-0 ${rowOpen ? \"opacity-0\" : \"\"}`}\n                  >\n                    {Icons[row.icon]}\n                  </svg>\n                  <svg\n                    width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"\n                    className={`absolute transition-[opacity,transform] duration-150 group-hover/row:opacity-100 ${rowOpen ? \"opacity-100\" : \"opacity-0\"}`}\n                    style={{ transform: rowOpen ? \"rotate(0deg)\" : \"rotate(-90deg)\" }}\n                  >\n                    <path d=\"M6 9l6 6 6-6\" />\n                  </svg>\n                </span>\n                <span className=\"shrink-0 text-[12.5px] font-medium text-ink\">{row.label}</span>\n                <span\n                  className={`inline-flex h-5.5 min-w-0 flex-1 cursor-pointer items-center truncate rounded-chip bg-field px-1.5\n                    text-[11.5px] text-ink-2 shadow-hairline transition-colors duration-100 hover:bg-hover-2\n                    ${row.mono ? \"font-mono\" : \"\"}`}\n                >\n                  {row.chip}\n                </span>\n              </button>\n\n              {/* expanded detail */}\n              <div\n                className=\"grid transition-[grid-template-rows,opacity] duration-300\"\n                style={{ gridTemplateRows: rowOpen ? \"1fr\" : \"0fr\", opacity: rowOpen ? 1 : 0, transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\" }}\n              >\n                <div className=\"min-h-0 overflow-hidden\">\n                  <div className=\"mt-0.5 mb-1 ml-2 flex flex-col gap-0.5 border-l border-line py-0.5 pl-3.5\">\n                    {row.detail.map((line) => (\n                      <span\n                        key={line.text}\n                        className={`truncate text-[11.5px] leading-[1.6] ${row.detailMono ? \"font-mono\" : \"\"} ${line.tone === \"add\" ? \"text-green\" : \"text-ink-2\"}`}\n                      >\n                        {line.text}\n                      </span>\n                    ))}\n                  </div>\n                </div>\n              </div>\n            </div>\n            );\n          })}\n        </div>\n\n      {/* file-diff chips */}\n      {step >= total && (\n        <div className=\"mt-2.5 flex max-w-full flex-wrap gap-1.5 border-t border-line pt-2.5\">\n          {diffs.map((d, i) => (\n            <span\n              key={d.file}\n              data-diffchip\n              className=\"relative\"\n              onMouseEnter={openPreview(d.file)}\n              onMouseLeave={closePreview(d.file)}\n            >\n              <button\n                type=\"button\"\n                aria-expanded={preview?.file === d.file}\n                aria-label={`Show diff for ${d.file}`}\n                onFocus={openPreview(d.file)}\n                onBlur={closePreview(d.file)}\n                className=\"inline-flex h-7 max-w-full items-center gap-2 rounded-chip\n                  bg-surface px-2 font-mono text-[11.5px] text-ink shadow-btn\n                  transition-colors duration-100 hover:bg-hover\"\n                style={{ animation: `beautiful-pop-in 250ms cubic-bezier(0.23,1,0.32,1) ${i * 80}ms both` }}\n              >\n                <span className=\"min-w-0 truncate\">{d.file}</span>\n                <span className=\"shrink-0 text-green tabular-nums\">+{d.add}</span>\n                {d.del > 0 && <span className=\"shrink-0 text-red tabular-nums\">−{d.del}</span>}\n              </button>\n\n            </span>\n          ))}\n          <button\n            type=\"button\"\n            className=\"inline-flex h-7 items-center rounded-chip px-1.5 font-mono text-[11.5px] text-ink-3\n              underline decoration-transparent underline-offset-2 transition-colors duration-100\n              hover:text-ink-2 hover:decoration-current\"\n            style={{ animation: `beautiful-fade-in 300ms ease-out ${diffs.length * 80}ms both` }}\n          >\n            {copy.more}\n          </button>\n        </div>\n      )}\n        </div>\n      </div>\n      {preview && typeof document !== \"undefined\" && createPortal(\n        <div\n          className=\"beautiful-ui-scope fixed z-50 w-72 overflow-hidden rounded-[10px] bg-surface text-ink shadow-overlay\"\n          style={{\n            left: preview.x,\n            top: preview.top,\n            bottom: preview.bottom,\n            animation: \"beautiful-pop-in 160ms cubic-bezier(0.23,1,0.32,1) both\",\n            transformOrigin: preview.top === undefined ? \"bottom left\" : \"top left\",\n          }}\n        >\n          <div className=\"flex items-center justify-between border-b border-line px-2.5 py-1.5 font-mono text-[11px]\">\n            <span className=\"min-w-0 truncate text-ink-2\">{preview.file}</span>\n            <span className=\"shrink-0 tabular-nums\">\n              <span className=\"text-green\">+{diffs.find((diff) => diff.file === preview.file)?.add}</span>\n              {(diffs.find((diff) => diff.file === preview.file)?.del ?? 0) > 0 && (\n                <span className=\"text-red\"> −{diffs.find((diff) => diff.file === preview.file)?.del}</span>\n              )}\n            </span>\n          </div>\n          <div className=\"py-1 font-mono text-[11px] leading-[1.8]\">\n            {(diffLines[preview.file] ?? []).map((line, index) => (\n              <div\n                key={index}\n                className={`flex gap-2 px-2.5 whitespace-pre ${\n                  line.tone === \"add\"\n                    ? \"bg-green-tint text-green\"\n                    : line.tone === \"del\"\n                      ? \"bg-red-tint text-red\"\n                      : \"text-ink-2\"\n                }`}\n              >\n                <span className=\"w-3 shrink-0 select-none\">{line.tone === \"add\" ? \"+\" : line.tone === \"del\" ? \"−\" : \" \"}</span>\n                <span className=\"min-w-0 truncate\">{line.text}</span>\n              </div>\n            ))}\n          </div>\n        </div>,\n        document.body,\n      )}\n    </div>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beautiful-ui/original/beautiful-ui.css",
          "target": "@components/beautiful-ui/original/beautiful-ui.css",
          "type": "registry:file",
          "content": "/* GENERIC FOUNDATION — tokens, @theme, base rules, the primitive-*\n * spacing utilities, and shared keyframes below are needed by EVERY\n * component. Blocks tagged COMPONENT-SPECIFIC further down belong to\n * one primitive each. */\n/* ──────────────────────────────────────────────────────────\n * Beautiful UI — design tokens\n * Cool near-white canvas, white cards, hairline borders, layered\n * single-digit-opacity shadows, a neutral ink ramp, and semantic\n * color used sparingly as a condiment.\n * ────────────────────────────────────────────────────────── */\n\n.beautiful-ui-scope {\n  /* surfaces — cool, blue-tinted neutrals */\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.979 0.002 247.839);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.933 0.003 247.86);\n\n  /* ink ramp */\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  /* borders — solid and crisp, not alpha */\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.966 0.002 264.542);\n  --grid-line: color-mix(in srgb, var(--line) 78%, transparent);\n  --field: oklch(0.961 0.001 286.375);\n  --stripe: oklch(0.405 0 0 / 0.075);\n  --stripe-bg: oklch(0.97 0 0);\n\n  /* accent */\n  --accent: oklch(0.626 0.205 254.947);\n  --accent-ink: oklch(0.556 0.187 255.617);\n  --accent-tint: oklch(0.96 0.019 252.878);\n\n  /* semantic */\n  --green: oklch(0.603 0.155 150.883);\n  --green-tint: oklch(0.958 0.017 159.118);\n  --orange: oklch(0.689 0.179 49.902);\n  --orange-tint: oklch(0.964 0.021 67.581);\n  --red: oklch(0.621 0.192 23.042);\n  --red-tint: oklch(0.956 0.017 17.462);\n\n  /* chart overlays — neutral system colors with enough contrast on either theme */\n  --tooltip-bg: oklch(0.272 0.008 264.435);\n  --tooltip-fg: oklch(0.976 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.356 0.007 264.474);\n\n  /* shadows — our solid hairline ring + shadow-plugin's smooth layered stacks\n   * (--shadow-xs…lg come from shadow-plugin/unprefixed) so every surface reads\n   * consistently across the app. */\n  --shadow-hairline: 0 0 0 1px var(--line);\n  --shadow-xs: 0 0 4px 0 rgba(0, 0, 0, 0.04);\n  --shadow-sm: 0 18px 47px 0 rgba(0, 0, 0, 0.03), 0 7.5px 19px 0 rgba(0, 0, 0, 0.02), 0 4px 10.5px 0 rgba(0, 0, 0, 0.02), 0 2.3px 5.8px 0 rgba(0, 0, 0, 0.01), 0 1.2px 3.1px 0 rgba(0, 0, 0, 0.01), 0 0.5px 1.3px 0 rgba(0, 0, 0, 0.01);\n  --shadow-md: 0 17.54px 23.39px 0 rgba(0, 0, 0, 0.04), 0 9.4px 12.5px 0 rgba(0, 0, 0, 0.03), 0 5.25px 7px 0 rgba(0, 0, 0, 0.02), 0 2.79px 3.72px -2px rgba(0, 0, 0, 0.01), 0 1.16px 1.5px 0 rgba(0, 0, 0, 0.01);\n  --shadow-lg: 0 25px 50px 0 rgba(0, 0, 0, 0.05), 0 12px 24px 0 rgba(0, 0, 0, 0.04), 0 6px 12px 0 rgba(0, 0, 0, 0.03), 0 3px 6px 0 rgba(0, 0, 0, 0.02), 0 1.5px 3px 0 rgba(0, 0, 0, 0.02);\n  --shadow-btn: 0 0 0 1px var(--line-strong), var(--shadow-xs);\n  --shadow-card: 0 0 0 1px var(--line), var(--shadow-sm);\n  --shadow-raised: 0 0 0 1px var(--line), var(--shadow-md);\n  --shadow-overlay: 0 0 0 1px var(--line), var(--shadow-lg);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.12);\n}\n\n.beautiful-ui-scope :is(button:not(:disabled), [role=\"button\"]:not([aria-disabled=\"true\"]), label:has(input), a) {\n  cursor: pointer;\n}\n\n.beautiful-ui-scope :focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 2px;\n  border-radius: 4px;\n}\n\n.beautiful-ui-scope :is(input, textarea, select, [contenteditable]):focus-visible {\n  outline: none;\n}\n\n.dark .beautiful-ui-scope {\n  --page: var(--color-background-full);\n  --canvas: var(--color-background-secondary-default);\n  --surface: var(--color-background-primary-default);\n  --inset: oklch(0.243 0.004 264.492);\n  --hover: var(--color-background-primary-hover);\n  --hover-2: oklch(0.318 0.007 274.747);\n\n  --ink: var(--color-text-primary);\n  --ink-2: var(--color-text-secondary);\n  --ink-3: var(--color-text-tertiary);\n\n  --line: var(--color-separator-border);\n  --line-strong: var(--color-border-button-default);\n  --line-soft: oklch(0.278 0.006 258.354);\n  --field: oklch(0.293 0.006 271.223);\n  --stripe: oklch(1 0 0 / 0.055);\n  --stripe-bg: oklch(0.226 0.004 264.485);\n\n  --accent: oklch(0.68 0.173 253.301);\n  --accent-ink: oklch(0.788 0.113 248.33);\n  --accent-tint: oklch(0.68 0.173 253.301 / 0.16);\n\n  --green: oklch(0.705 0.154 153.814);\n  --green-tint: oklch(0.705 0.154 153.814 / 0.14);\n  --orange: oklch(0.746 0.156 55.642);\n  --orange-tint: oklch(0.746 0.156 55.642 / 0.14);\n  --red: oklch(0.666 0.18 21.433);\n  --red-tint: oklch(0.666 0.18 21.433 / 0.14);\n\n  --tooltip-bg: oklch(0.182 0.004 264.459);\n  --tooltip-fg: oklch(0.964 0.002 247.839);\n  --tooltip-muted: oklch(0.731 0.008 260.731);\n  --tooltip-border: oklch(0.308 0.006 258.354);\n\n  --shadow-hairline: 0 0 0 1px var(--line);\n  /* Elevation rings go to a subtle *light* hairline in dark mode: the ring\n   * paints over the surface behind the element, so a low-alpha white edge\n   * dissolves into the shadow as one continuous stroke (per smooth-shadow-ring),\n   * graduated by how far the surface floats. */\n  --shadow-btn: 0 0 0 1px oklch(1 0 0 / 0.1), 0 1px 2px oklch(0 0 0 / 0.3);\n  --shadow-card:\n    0 0 0 1px oklch(1 0 0 / 0.11), 0 1px 2px oklch(0 0 0 / 0.2),\n    0 2px 6px oklch(0 0 0 / 0.2);\n  --shadow-raised:\n    0 0 0 1px oklch(1 0 0 / 0.13), 0 2px 10px oklch(0 0 0 / 0.22);\n  --shadow-overlay:\n    0 0 0 1px oklch(1 0 0 / 0.15), 0 8px 28px oklch(0 0 0 / 0.34);\n  --shadow-inset-field: inset 0 1px 2px oklch(0 0 0 / 0.4);\n}\n\n@theme inline {\n  /* colors */\n  --color-page: var(--page);\n  --color-canvas: var(--canvas);\n  --color-surface: var(--surface);\n  --color-inset: var(--inset);\n  --color-ink: var(--ink);\n  --color-ink-2: var(--ink-2);\n  --color-ink-3: var(--ink-3);\n  --color-hover: var(--hover);\n  --color-hover-2: var(--hover-2);\n  --color-field: var(--field);\n  --color-line: var(--line);\n  --color-line-strong: var(--line-strong);\n  --color-accent: var(--accent);\n  --color-accent-ink: var(--accent-ink);\n  --color-accent-tint: var(--accent-tint);\n  --color-green: var(--green);\n  --color-green-tint: var(--green-tint);\n  --color-orange: var(--orange);\n  --color-orange-tint: var(--orange-tint);\n  --color-red: var(--red);\n  --color-red-tint: var(--red-tint);\n\n  /* shadows */\n  --shadow-hairline: var(--shadow-hairline);\n  --shadow-btn: var(--shadow-btn);\n  --shadow-inset-field: var(--shadow-inset-field);\n  --shadow-card: var(--shadow-card);\n  --shadow-raised: var(--shadow-raised);\n  --shadow-overlay: var(--shadow-overlay);\n\n  /* easing — strong curves; built-ins are too weak */\n  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);\n  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);\n  --ease-link: cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamingText / ContextCards\n * Favicon source avatars.\n * Copy this block only alongside StreamingText / ContextCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.source-avatar {\n  box-shadow: 0 0 0 1px oklch(0.21 0.034 263.436 / 0.1);\n}\n\n.dark .beautiful-ui-scope .source-avatar {\n  box-shadow: 0 0 0 1px oklch(1 0 0 / 0.08);\n}\n\n/* ── primitive spacing system ─────────────────────────────\n * Shared optical offsets for small demo cards. Use these\n * instead of hand-tuning 10/12/14px per component.\n */\n\n.primitive-card-pad {\n  padding: 12px;\n}\n\n.primitive-card-bar {\n  padding: 10px 12px;\n}\n\n.primitive-card-footer {\n  padding: 10px;\n}\n\n.primitive-table-cell {\n  padding: 10px 12px;\n}\n\n.primitive-icon-button {\n  display: inline-flex;\n  width: 28px;\n  height: 28px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-control);\n}\n\n/* ── shared keyframes ─────────────────────────────────── */\n\n@keyframes beautiful-shimmer-text {\n  from {\n    background-position: 150% center;\n  }\n  to {\n    background-position: -50% center;\n  }\n}\n\n@keyframes beautiful-fade-up {\n  from {\n    opacity: 0;\n    transform: translateY(8px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.home-reveal {\n  will-change: opacity, transform, filter;\n}\n\n/* The sidebar is one persistent 224px tree clipped by a 52px shell.\n * Every rail glyph remains centered at x=26 in both states. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — SidebarNav\n * The 52↔224px collapsible sidebar tree.\n * Copy this block only alongside SidebarNav; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.sidebar-row {\n  width: 208px;\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: var(--sidebar-easing);\n}\n\n.sidebar-copy {\n  opacity: 1;\n  transform: translateX(0);\n  transition:\n    opacity var(--sidebar-copy-duration) ease-out,\n    transform var(--sidebar-copy-duration) var(--sidebar-easing);\n}\n\n.sidebar-logo,\n.sidebar-collapse-control,\n.sidebar-expand-control {\n  transition-duration: var(--sidebar-copy-duration);\n  transition-timing-function: ease-out;\n}\n\n.sidebar-expand-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n.sidebar-glide-highlight {\n  right: 8px;\n  left: 8px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-row {\n  width: 36px;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-copy {\n  pointer-events: none;\n  opacity: 0;\n  transform: translateX(calc(var(--sidebar-copy-offset) * -1));\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-workspace-control {\n  pointer-events: none;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-logo,\n[data-sidebar-collapsed=\"true\"] .sidebar-collapse-control {\n  pointer-events: none;\n  opacity: 0;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-expand-control {\n  pointer-events: auto;\n  opacity: 1;\n}\n\n[data-sidebar-collapsed=\"true\"] .sidebar-glide-highlight {\n  right: auto;\n  width: 36px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .home-reveal {\n    opacity: 1 !important;\n    transform: none !important;\n    filter: none !important;\n  }\n}\n\n/* ── records table ────────────────────────────────────────\n * The grid is deliberately more architectural than card-like:\n * one quiet surface, precise rules, and color reserved for\n * meaning. The first column remains an anchor while both axes\n * can move independently inside the table viewport.\n */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — RecordsTable\n * The full CRM grid, spreadsheet gutter, and AI column (~800 lines).\n * Copy this block only alongside RecordsTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.records-shell {\n  width: 100%;\n  min-width: 0;\n  overflow: hidden;\n  border: 1px solid var(--line);\n  border-radius: 10px;\n  background: var(--surface);\n  box-shadow: 0 1px 2px oklch(0 0 0 / 0.06);\n}\n\n/* fill mode: the shell stretches to fill its container and drops its own\n * border/radius/shadow so it reads as part of the surrounding card rather\n * than a container-in-a-container. The grid body flexes to fill height. */\n.records-shell.is-fill {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  min-height: 0;\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.records-shell.is-fill .records-scroll {\n  max-height: none;\n  flex: 1;\n}\n\n.records-toolbar {\n  display: flex;\n  min-height: 52px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 8px 10px;\n  border-bottom: 1px solid var(--line-strong);\n  background: var(--surface);\n}\n\n.records-toolbar-left,\n.records-toolbar-right,\n.records-company-header,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button,\n.records-select-button,\n.records-strength,\n.records-link,\n.records-add-calculation {\n  display: inline-flex;\n  align-items: center;\n}\n\n.records-toolbar-left,\n.records-toolbar-right {\n  gap: 4px;\n}\n\n.records-toolbar-right {\n  flex-shrink: 0;\n}\n\n.records-select-button,\n.records-quiet-button,\n.records-secondary-button,\n.records-primary-button {\n  height: 32px;\n  gap: 7px;\n  border-radius: var(--radius-control);\n  padding: 0 10px;\n  font-size: 12px;\n  font-weight: 500;\n  white-space: nowrap;\n  transition: background-color 140ms var(--ease-out-strong), color 140ms var(--ease-out-strong), transform 140ms var(--ease-out-strong), box-shadow 140ms var(--ease-out-strong);\n}\n\n.records-select-button {\n  gap: 8px;\n  color: var(--ink);\n  border: 1px solid var(--line);\n  background: var(--surface);\n}\n\n.records-select-button:hover,\n.records-quiet-button:hover,\n.records-secondary-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-quiet-button {\n  color: var(--ink-2);\n}\n\n.records-quiet-button.is-active {\n  background: var(--accent-tint);\n  color: var(--accent-ink);\n}\n\n.records-secondary-button {\n  border: 1px solid var(--tooltip-border);\n  color: var(--ink-2);\n  box-shadow: none;\n}\n\n.records-primary-button {\n  margin-left: 3px;\n  background: var(--accent);\n  color: oklch(1 0 0);\n  box-shadow: none;\n}\n\n.records-primary-button:hover {\n  filter: saturate(0.9) brightness(1.04);\n}\n\n.records-quiet-button:active,\n.records-secondary-button:active,\n.records-primary-button:active,\n.records-select-button:active,\n.records-add-calculation:active {\n  transform: scale(0.96);\n}\n\n.records-database-icon {\n  display: inline-flex;\n  color: var(--green);\n}\n\n.records-filter-wrap {\n  position: relative;\n}\n\n.records-filter-dot {\n  width: 5px;\n  height: 5px;\n  margin-left: -2px;\n  border-radius: 99px;\n  background: var(--accent);\n}\n\n.records-filter-menu {\n  position: absolute;\n  z-index: 30;\n  top: calc(100% + 7px);\n  left: 0;\n  width: 190px;\n  padding: 6px;\n  border: 1px solid var(--line-strong);\n  border-radius: var(--radius-card);\n  background: var(--surface);\n  box-shadow: var(--shadow-overlay);\n  animation: beautiful-pop-in 160ms var(--ease-out-strong) both;\n  transform-origin: top left;\n}\n\n.records-sort-menu {\n  left: -48px;\n}\n\n.records-filter-label {\n  padding: 5px 8px 6px;\n  color: var(--ink-3);\n  font-size: 10.5px;\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: uppercase;\n}\n\n.records-filter-menu button {\n  display: flex;\n  width: 100%;\n  align-items: center;\n  gap: 7px;\n  border-radius: var(--radius-chip);\n  padding: 7px 8px;\n  color: var(--ink-2);\n  font-size: 12px;\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-filter-menu button:hover,\n.records-filter-menu button.is-selected {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-menu-check {\n  width: 13px;\n  color: var(--accent-ink);\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n}\n\n.records-scroll {\n  max-height: 438px;\n  overflow: auto;\n  overscroll-behavior: none;\n  scrollbar-color: var(--line-strong) transparent;\n  scrollbar-gutter: stable;\n}\n\n.records-scroll:focus-visible {\n  outline: 2px solid var(--accent);\n  outline-offset: -2px;\n}\n\n.records-table {\n  width: 100%;\n  min-width: 990px;\n  border-collapse: separate;\n  border-spacing: 0;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  table-layout: fixed;\n}\n\n.records-company-col { width: 270px; }\n.records-category-col { width: 275px; }\n.records-last-col { width: 190px; }\n.records-strength-col { width: 210px; }\n.records-link-col { width: 175px; }\n\n.records-table th,\n.records-table td {\n  border-right: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  border-bottom: 1px solid color-mix(in srgb, var(--line) 78%, transparent);\n  text-align: left;\n  vertical-align: middle;\n}\n\n.records-table tr > :last-child {\n  border-right: 0;\n}\n\n.records-table thead th {\n  position: sticky;\n  z-index: 5;\n  top: 0;\n  height: 35px;\n  background: var(--surface);\n  color: var(--ink-2);\n  font-size: 12.5px;\n  font-weight: 500;\n}\n\n.records-header-cell {\n  padding: 0;\n}\n\n.records-resize-handle {\n  position: absolute;\n  z-index: 12;\n  top: 0;\n  right: -6px;\n  width: 12px;\n  height: 100%;\n  cursor: col-resize;\n  touch-action: none;\n}\n\n.records-resize-handle::after {\n  position: absolute;\n  top: 7px;\n  bottom: 7px;\n  left: 5px;\n  width: 2px;\n  border-radius: 99px;\n  background: var(--accent);\n  content: \"\";\n  opacity: 0;\n  transform: scaleY(0.65);\n  transition: opacity 120ms ease-out, transform 150ms var(--ease-out-strong);\n}\n\n.records-resize-handle:hover::after,\n.records-resize-handle.is-resizing::after {\n  opacity: 1;\n  transform: scaleY(1);\n}\n\n.records-header-cell.records-sticky-cell {\n  z-index: 7;\n}\n\n.records-header-button,\n.records-company-header {\n  width: 100%;\n  height: 35px;\n  gap: 8px;\n  padding: 0 12px;\n}\n\n.records-company-header {\n  padding-left: 6px;\n}\n\n.records-header-button {\n  display: flex;\n  align-items: center;\n  color: var(--ink-2);\n  text-align: left;\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-header-button:hover {\n  background: var(--hover);\n  color: var(--ink);\n}\n\n.records-header-icon {\n  display: inline-flex;\n  flex-shrink: 0;\n  color: var(--ink-3);\n}\n\n.records-sort {\n  display: inline-flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  opacity: 0;\n  transition: opacity 120ms ease-out, transform 160ms var(--ease-out-strong);\n}\n\n.records-header-button:hover .records-sort,\n.records-sort.is-visible {\n  opacity: 1;\n}\n\n.records-company-header {\n  display: flex;\n}\n\n.records-company-header > span:not(.records-checkbox-box) {\n  white-space: nowrap;\n}\n\n.records-add-field {\n  display: inline-flex;\n  margin-left: auto;\n  color: var(--ink-3);\n  opacity: 0;\n  transition: opacity 120ms ease-out, color 120ms ease-out;\n}\n\n.records-company-header:hover .records-add-field,\n.records-add-field:focus-visible {\n  opacity: 1;\n}\n\n.records-add-field:hover {\n  color: var(--ink);\n}\n\n.records-checkbox {\n  position: relative;\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--radius-chip);\n}\n\n.records-checkbox input {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  opacity: 0;\n}\n\n.records-checkbox-box {\n  display: inline-flex;\n  width: 18px;\n  height: 18px;\n  align-items: center;\n  justify-content: center;\n  border: 1px solid oklch(0.845 0.011 247.953);\n  border-radius: 6px;\n  color: oklch(0.446 0.018 251.343);\n  background: oklch(1 0 0);\n  transition: border-color 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.773 0.016 251.194);\n  background: oklch(0.966 0.003 228.784);\n}\n\n.records-checkbox:active .records-checkbox-box {\n  transform: scale(0.96);\n}\n\n.records-checkbox input:focus-visible + .records-checkbox-box {\n  outline: 2px solid var(--accent);\n  outline-offset: 2px;\n}\n\n.records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n  box-shadow: none;\n}\n\n.records-checkbox-dash {\n  width: 8px;\n  height: 1.5px;\n  border-radius: 99px;\n  background: oklch(1 0 0);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box {\n  border-color: oklch(0.45 0.017 254.711);\n  color: oklch(0.917 0.007 247.901);\n  background: oklch(0.346 0.015 252.294);\n}\n\n.dark .beautiful-ui-scope .records-checkbox:hover .records-checkbox-box {\n  border-color: oklch(0.521 0.019 254);\n  background: oklch(0.391 0.016 251.761);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-box.is-active {\n  border-color: var(--accent);\n  color: oklch(1 0 0);\n  background: var(--accent);\n}\n\n.dark .beautiful-ui-scope .records-checkbox-dash {\n  background: oklch(1 0 0);\n}\n\n.records-cell {\n  height: 35px;\n  padding: 0 8px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.records-sticky-cell {\n  position: sticky;\n  left: 0;\n  z-index: 2;\n  background: var(--surface);\n  box-shadow: 5px 0 8px -10px oklch(0 0 0 / 0.4);\n}\n\n.records-company-cell {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding-left: 6px;\n  overflow: visible;\n}\n\n.records-row > .records-cell {\n  transition: background-color 120ms ease-out, color 120ms ease-out;\n}\n\n.records-row:hover > .records-cell {\n  background: var(--hover);\n}\n\n.records-row.is-selected > .records-cell {\n  background: color-mix(in srgb, var(--accent) 7%, var(--surface));\n}\n\n/* ── spreadsheet gutter ──────────────────────────────────\n * Row numbers at rest; the checkbox takes their place on\n * hover or once the row is selected. */\n.records-rownum {\n  display: inline-flex;\n  width: 24px;\n  height: 24px;\n  flex: 0 0 24px;\n  align-items: center;\n  justify-content: center;\n  color: var(--ink-3);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n}\n\n.records-row .records-checkbox {\n  display: none;\n}\n\n.records-row:hover .records-rownum,\n.records-row.is-selected .records-rownum {\n  display: none;\n}\n\n.records-row:hover .records-checkbox,\n.records-row.is-selected .records-checkbox {\n  display: inline-flex;\n}\n\n/* ── selected column — the property being configured ───── */\n.records-table th.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n  box-shadow: inset 0 2px 0 var(--accent);\n}\n\nth.is-colsel .records-header-button,\nth.is-colsel .records-company-header,\nth.is-colsel .records-header-icon {\n  color: var(--accent-ink);\n}\n\n.records-table td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 4%, var(--surface));\n}\n\n.records-row:hover > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 8%, var(--surface));\n}\n\n.records-row.is-selected > td.is-colsel {\n  background: color-mix(in srgb, var(--accent) 10%, var(--surface));\n}\n\n/* ── AI column calculating state ─────────────────────────── */\n.records-calc {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 8px;\n}\n\n.beautiful-records-pulse {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n  background: var(--accent);\n  animation: beautiful-records-pulse 1.1s ease-in-out infinite;\n}\n\n@keyframes beautiful-records-pulse {\n  0%,\n  100% {\n    opacity: 0.35;\n    transform: scale(0.8);\n  }\n  50% {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n/* agent-screen — a static decorative cursor sitting on the capture (for show) */\n.agent-cursor {\n  position: absolute;\n  pointer-events: none;\n  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));\n}\n\n.records-company-mark {\n  display: inline-flex;\n  width: 20px;\n  height: 20px;\n  flex: 0 0 20px;\n  align-items: center;\n  justify-content: center;\n  border: 0;\n  border-radius: 6px;\n  color: var(--ink-2);\n  background: var(--field);\n  font-size: 10px;\n  font-weight: 500;\n}\n\n.records-company-name {\n  min-width: 0;\n  overflow: hidden;\n  color: var(--ink);\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-company-name.has-link:hover,\n.records-company-name.has-link:focus-visible {\n  color: var(--accent-ink);\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\n.records-tags {\n  position: relative;\n  display: flex;\n  width: 100%;\n  min-width: 0;\n  align-items: center;\n  gap: 4px;\n  overflow: hidden;\n}\n\n.records-tags-measure {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: flex;\n  width: max-content;\n  gap: 4px;\n  pointer-events: none;\n  visibility: hidden;\n}\n\n.records-tags-measure > span {\n  display: inline-flex;\n}\n\n.records-tag {\n  display: inline-flex;\n  height: 23px;\n  max-width: 115px;\n  align-items: center;\n  flex-shrink: 0;\n  overflow: hidden;\n  cursor: pointer;\n  border: 1px solid color-mix(in srgb, var(--tag-base) 32%, var(--surface));\n  border-radius: 8px;\n  padding: 0 7px;\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 18%, var(--surface));\n  font-size: 13px;\n  font-weight: 500;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-more-tag {\n  display: inline-flex;\n  height: 23px;\n  align-items: center;\n  flex-shrink: 0;\n  border: 1px solid var(--line-strong);\n  border-radius: 6px;\n  padding: 0 7px;\n  color: var(--ink-3);\n  background: var(--inset);\n  font-size: 11px;\n  font-weight: 500;\n}\n\n.records-more-tag {\n  border-color: var(--line-strong);\n  color: var(--ink-3);\n  background: var(--inset);\n}\n\n.records-muted {\n  color: var(--ink-3);\n}\n\n.records-strength {\n  gap: 8px;\n  color: var(--ink-2);\n}\n\n.records-strength-dot {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n.records-link {\n  max-width: 100%;\n  gap: 5px;\n  overflow: hidden;\n  color: var(--accent-ink);\n  text-overflow: ellipsis;\n  text-decoration: underline;\n  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);\n  text-underline-offset: 3px;\n  transition: color 120ms ease-out, text-decoration-color 120ms ease-out;\n}\n\n.records-link-label {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.records-link svg {\n  flex-shrink: 0;\n}\n\n.records-link:hover,\n.records-link:focus-visible {\n  color: var(--ink);\n  text-decoration-color: currentColor;\n}\n\n.records-table tfoot td {\n  position: sticky;\n  z-index: 4;\n  bottom: 0;\n  height: 35px;\n  background: var(--inset);\n  color: var(--ink-2);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n}\n\n.records-table tfoot .records-sticky-cell {\n  z-index: 6;\n  background: var(--inset);\n}\n\n.records-calculation-label {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-value {\n  display: inline-flex;\n  height: 35px;\n  align-items: center;\n  vertical-align: middle;\n}\n\n.records-calculation-number {\n  margin-right: 3px;\n  color: var(--ink);\n  font-variant-numeric: tabular-nums;\n}\n\n.records-add-calculation {\n  height: 35px;\n  gap: 6px;\n  color: var(--ink-3);\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 1;\n  transition: color 120ms ease-out, transform 140ms var(--ease-out-strong);\n}\n\n.records-add-calculation:hover {\n  color: var(--ink);\n}\n\n.records-average {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  color: var(--ink-2);\n}\n\n.records-calculation-row-secondary td {\n  position: sticky;\n  bottom: 35px;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-calculation-row-secondary .records-sticky-cell {\n  position: sticky;\n  background: color-mix(in srgb, var(--inset) 70%, var(--surface));\n}\n\n.records-footer {\n  display: flex;\n  min-height: 35px;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  padding: 0 12px;\n  color: var(--ink-3);\n  font-size: 11.5px;\n}\n\n.records-footer strong {\n  color: var(--ink-2);\n  font-weight: 500;\n}\n\n.records-footer-hint {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  opacity: 0;\n  transition: opacity 160ms ease-out;\n}\n\n.records-shell:hover .records-footer-hint {\n  opacity: 1;\n}\n\n.records-scroll-cue {\n  display: inline-flex;\n  color: var(--ink-3);\n}\n\n@media (max-width: 640px) {\n  .records-toolbar {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  .records-toolbar-left,\n  .records-toolbar-right {\n    width: 100%;\n  }\n\n  .records-toolbar-right {\n    justify-content: flex-end;\n  }\n\n  .records-footer-hint {\n    display: none;\n  }\n}\n\n/* ── filter table electric status colors ─────────────────── */\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — FilterTable\n * Electric status-pill colors.\n * Copy this block only alongside FilterTable; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  border: 1px solid transparent;\n}\n\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — InsightCards\n * Liveline chart tooltip + cursor.\n * Copy this block only alongside InsightCards; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.insight-chart-stage {\n  overflow: hidden;\n}\n\n.insight-chart-cursor {\n  position: absolute;\n  z-index: 4;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--ink);\n  opacity: 0.26;\n  pointer-events: none;\n}\n\n.insight-chart-tooltip-anchor {\n  position: absolute;\n  z-index: 5;\n  top: 8px;\n  transform: translateX(-50%);\n  pointer-events: none;\n}\n\n.insight-chart-tooltip {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 5px 9px;\n  border: 1px solid var(--line-strong);\n  border-radius: 8px;\n  color: var(--tooltip-fg);\n  background: var(--tooltip-bg);\n  box-shadow: var(--shadow-overlay);\n  font-size: 11.5px;\n  font-variant-numeric: tabular-nums;\n  white-space: nowrap;\n}\n\n.insight-chart-tooltip-item {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n}\n\n.insight-chart-tooltip-dot {\n  width: 8px;\n  height: 8px;\n  flex: 0 0 8px;\n  border-radius: 50%;\n}\n\n/* Status pills share the same base-hue → color-mix derivation as .records-tag,\n * so both components stay consistent across light and dark. */\n.filter-status-todo {\n  --tag-base: oklch(0.757 0.153 66.401);\n}\n.filter-status-progress {\n  --tag-base: oklch(0.671 0.118 219.351);\n}\n.filter-status-done {\n  --tag-base: oklch(0.652 0.131 162.865);\n}\n\n.filter-status-todo,\n.filter-status-progress,\n.filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 92%, var(--ink));\n  background: color-mix(in srgb, var(--tag-base) 20%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n/* Dark mode — a richer, saturated same-hue fill\n * with bright same-hue text and no visible border (light mode keeps the soft\n * tinted pastels above). Applies to both the records grid and status pills. */\n.dark .beautiful-ui-scope .records-tag,\n.dark .beautiful-ui-scope .filter-status-todo,\n.dark .beautiful-ui-scope .filter-status-progress,\n.dark .beautiful-ui-scope .filter-status-done {\n  color: color-mix(in srgb, var(--tag-base) 86%, white);\n  background: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n  border-color: color-mix(in srgb, var(--tag-base) 34%, var(--surface));\n}\n\n@keyframes beautiful-fade-in {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes beautiful-eq-bounce {\n  0%,\n  100% {\n    transform: scaleY(0.35);\n  }\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n/* ── StreamText primitive ─────────────────────────────────\n * Fast character reveal: the newest few characters carry a\n * soft, masked blur so the leading edge resolves smoothly as\n * text flows in. The caret holds solid while streaming, then\n * blinks once the string settles. */\n/* ══════════════════════════════════════════════════════════\n * COMPONENT-SPECIFIC — StreamText\n * The streaming caret + tail.\n * Copy this block only alongside StreamText; it is not part of the\n * generic foundation above.\n * ══════════════════════════════════════════════════════════ */\n.stream-tail {\n  filter: blur(1.6px);\n  -webkit-mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n  mask-image: linear-gradient(to right, oklch(0 0 0) 20%, oklch(0 0 0 / 0.2));\n}\n\n.stream-caret {\n  display: inline-block;\n  width: 2px;\n  height: 1.05em;\n  margin-left: 1.5px;\n  translate: 0 -0.5px;\n  border-radius: 1px;\n  background: var(--ink);\n  vertical-align: text-bottom;\n  animation: beautiful-caret-blink 1s step-end infinite;\n}\n\n.stream-caret.is-streaming {\n  animation: none;\n}\n\n@keyframes beautiful-caret-blink {\n  0%,\n  100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stream-caret {\n    animation: none;\n  }\n  .stream-tail {\n    filter: none;\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n}\n\n@keyframes beautiful-pop-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@keyframes beautiful-spin {\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* pixel-grid loader — brighten plateau, staggered per cell */\n@keyframes beautiful-pixel-on {\n  0%, 100% {\n    opacity: 0.15;\n  }\n  18%, 42% {\n    opacity: 1;\n  }\n  62% {\n    opacity: 0.15;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .beautiful-ui-scope *,\n  .beautiful-ui-scope *::before,\n  .beautiful-ui-scope *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n  }\n}\n"
        }
      ],
      "categories": [
        "Beautiful UI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-message-bubble",
      "type": "registry:block",
      "title": "Beui Message Bubble",
      "description": "Message Bubble",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/message-bubble.tsx",
          "target": "@components/beui/components/agents/message-bubble.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { ChevronDown } from \"lucide-react\";\nimport {\n  type HTMLMotionProps,\n  motion,\n  useReducedMotion,\n} from \"motion/react\";\nimport {\n  cloneElement,\n  type ComponentPropsWithRef,\n  createContext,\n  type ReactElement,\n  type ReactNode,\n  type Ref,\n  useCallback,\n  useContext,\n  useId,\n  useState,\n} from \"react\";\nimport {\n  EASE_OUT,\n  SPRING_LAYOUT,\n  SPRING_SWAP,\n} from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport { MessageSideContext } from \"@/components/beui/components/agents/message-context\";\n\nexport type MessageBubbleVariant =\n  | \"solid\"\n  | \"soft\"\n  | \"tint\"\n  | \"outline\"\n  | \"ghost\"\n  | \"danger\";\nexport type MessageBubbleAlign = \"start\" | \"end\";\n\ninterface MessageBubbleContextValue {\n  align?: MessageBubbleAlign;\n  animateIn: boolean;\n  variant: MessageBubbleVariant;\n}\n\nconst MessageBubbleContext = createContext<MessageBubbleContextValue>({\n  animateIn: true,\n  variant: \"soft\",\n});\nconst MessageBubbleLayoutContext = createContext<() => void>(() => {});\n\nexport interface MessageBubbleProps\n  extends Omit<HTMLMotionProps<\"div\">, \"children\"> {\n  variant?: MessageBubbleVariant;\n  /** Defaults to the surrounding Message alignment when omitted. */\n  align?: MessageBubbleAlign;\n  /** Plays the bubble entrance once when this component mounts. */\n  animateIn?: boolean;\n  children?: ReactNode;\n}\n\nexport interface MessageBubbleContentProps\n  extends ComponentPropsWithRef<\"div\"> {\n  /** Replaces the content element while preserving bubble styling. */\n  render?: ReactElement;\n}\n\nexport interface MessageBubbleGroupProps extends ComponentPropsWithRef<\"div\"> {\n  spacing?: \"compact\" | \"default\";\n}\n\nexport interface MessageBubbleCollapsibleProps\n  extends ComponentPropsWithRef<\"div\"> {\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  collapsedLines?: 2 | 3 | 4 | 5 | 6;\n  moreLabel?: ReactNode;\n  lessLabel?: ReactNode;\n  contentClassName?: string;\n  triggerClassName?: string;\n  children?: ReactNode;\n}\n\nfunction mergeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n  return (node: T | null) => {\n    for (const ref of refs) {\n      if (typeof ref === \"function\") ref(node);\n      else if (ref) ref.current = node;\n    }\n  };\n}\n\nconst BUBBLE_CONTENT_REVEAL = {\n  duration: 0.12,\n  ease: EASE_OUT,\n  delay: 0.04,\n} as const;\n\n// Sent bubbles should pop into place quickly with one restrained overshoot.\nconst BUBBLE_POP = {\n  type: \"spring\",\n  stiffness: 520,\n  damping: 27,\n  mass: 0.52,\n} as const;\n\nexport function MessageBubble({\n  variant = \"soft\",\n  align,\n  animateIn = false,\n  className,\n  children,\n  initial,\n  animate,\n  exit,\n  transition,\n  layout,\n  ...props\n}: MessageBubbleProps) {\n  const reduce = useReducedMotion() ?? false;\n  const messageSide = useContext(MessageSideContext);\n  const resolvedAlign = align ?? messageSide ?? \"start\";\n\n  return (\n    <MessageBubbleContext.Provider\n      value={{ align: resolvedAlign, animateIn, variant }}\n    >\n      <motion.div\n        data-slot=\"message-bubble\"\n        data-align={resolvedAlign}\n        data-variant={variant}\n        layout={layout}\n        initial={initial ?? false}\n        animate={animate}\n        exit={\n          exit ??\n          (reduce ? { opacity: 0 } : { opacity: 0, y: -3, scale: 0.99 })\n        }\n        transition={transition ?? (reduce ? { duration: 0.12 } : SPRING_LAYOUT)}\n        className={cn(\n          \"group/bubble flex w-full flex-col\",\n          resolvedAlign === \"end\" ? \"items-end\" : \"items-start\",\n          className,\n        )}\n        {...props}\n      >\n        {children}\n      </motion.div>\n    </MessageBubbleContext.Provider>\n  );\n}\n\nfunction bubbleContentClass(\n  variant: MessageBubbleVariant,\n  interactive: boolean,\n) {\n  return cn(\n    \"relative z-0 min-w-9 max-w-[82%] rounded-2xl px-3.5 py-2.5 text-sm leading-6 text-foreground\",\n    \"[&_a]:font-medium [&_a]:underline [&_a]:underline-offset-4 [&_code]:rounded [&_code]:bg-background/60 [&_code]:px-1 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.9em] [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_p+p]:mt-2 [&_pre]:my-2 [&_pre]:overflow-x-auto [&_pre]:rounded-xl [&_pre]:bg-background/60 [&_pre]:p-3 [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5\",\n    variant === \"solid\" && \"text-background\",\n    variant === \"ghost\" && \"w-full max-w-none rounded-none px-0 py-0\",\n    variant === \"danger\" && \"text-destructive\",\n    interactive &&\n      \"cursor-pointer text-left outline-none transition-[background-color,color,transform] duration-150 hover:brightness-[0.98] focus-visible:ring-2 focus-visible:ring-ring active:scale-[0.99]\",\n  );\n}\n\nfunction bubbleSurfaceClass(\n  variant: MessageBubbleVariant,\n  align: MessageBubbleAlign,\n) {\n  return cn(\n    \"pointer-events-none absolute inset-0 -z-10 rounded-[inherit]\",\n    align === \"end\" ? \"origin-bottom-right\" : \"origin-bottom-left\",\n    variant === \"solid\" && \"bg-foreground\",\n    variant === \"soft\" && \"bg-muted\",\n    variant === \"tint\" && \"bg-primary/10\",\n    variant === \"outline\" && \"border border-border/70 bg-background\",\n    variant === \"danger\" && \"bg-destructive/10\",\n  );\n}\n\nexport function MessageBubbleContent({\n  render,\n  className,\n  children,\n  ref,\n  ...props\n}: MessageBubbleContentProps) {\n  const reduce = useReducedMotion() ?? false;\n  const { align = \"start\", animateIn, variant } =\n    useContext(MessageBubbleContext);\n  const [layoutVersion, setLayoutVersion] = useState(0);\n  const notifyLayout = useCallback(\n    () => setLayoutVersion((version) => version + 1),\n    [],\n  );\n  const interactive =\n    render?.type === \"button\" || render?.type === \"a\";\n  const classes = cn(bubbleContentClass(variant, interactive), className);\n  const composedChildren = (\n    <>\n      {variant !== \"ghost\" ? (\n        <motion.span\n          aria-hidden=\"true\"\n          layout={reduce ? false : \"size\"}\n          layoutDependency={layoutVersion}\n          initial={\n            animateIn && !reduce\n              ? {\n                  opacity: 0,\n                  scale: 0.92,\n                }\n              : false\n          }\n          animate={{ opacity: 1, scale: 1 }}\n          transition={\n            reduce\n              ? { duration: 0 }\n              : {\n                  opacity: { duration: 0.12, ease: EASE_OUT },\n                  scale: BUBBLE_POP,\n                  layout: SPRING_LAYOUT,\n                }\n          }\n          className={bubbleSurfaceClass(variant, align)}\n        />\n      ) : null}\n      <MessageBubbleLayoutContext.Provider value={notifyLayout}>\n        <motion.div\n          initial={\n            animateIn\n              ? reduce\n                ? { opacity: 0 }\n                : { opacity: 0 }\n              : false\n          }\n          animate={{ opacity: 1 }}\n          transition={\n            reduce ? { duration: 0.12, ease: EASE_OUT } : BUBBLE_CONTENT_REVEAL\n          }\n          className=\"relative\"\n        >\n          {children}\n        </motion.div>\n      </MessageBubbleLayoutContext.Provider>\n    </>\n  );\n\n  if (render) {\n    const child = render as ReactElement<\n      Record<string, unknown> & { className?: string; ref?: Ref<HTMLElement> }\n    >;\n\n    return cloneElement(child, {\n      ...props,\n      ref: mergeRefs(child.props.ref, ref as Ref<HTMLElement> | undefined),\n      className: cn(classes, child.props.className),\n      children: composedChildren,\n      \"data-slot\": \"message-bubble-content\",\n    });\n  }\n\n  return (\n    <div\n      ref={ref}\n      data-slot=\"message-bubble-content\"\n      className={classes}\n      {...props}\n    >\n      {composedChildren}\n    </div>\n  );\n}\n\nexport function MessageBubbleGroup({\n  spacing = \"compact\",\n  className,\n  ...props\n}: MessageBubbleGroupProps) {\n  return (\n    <div\n      data-slot=\"message-bubble-group\"\n      className={cn(\n        \"flex w-full flex-col\",\n        spacing === \"compact\" ? \"gap-1.5\" : \"gap-3\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nconst LINE_CLAMP_CLASS = {\n  2: \"line-clamp-2\",\n  3: \"line-clamp-3\",\n  4: \"line-clamp-4\",\n  5: \"line-clamp-5\",\n  6: \"line-clamp-6\",\n} as const;\n\nexport function MessageBubbleCollapsible({\n  open,\n  defaultOpen = false,\n  onOpenChange,\n  collapsedLines = 4,\n  moreLabel = \"Show more\",\n  lessLabel = \"Show less\",\n  contentClassName,\n  triggerClassName,\n  className,\n  children,\n  ...props\n}: MessageBubbleCollapsibleProps) {\n  const reduce = useReducedMotion() ?? false;\n  const contentId = useId();\n  const notifyLayout = useContext(MessageBubbleLayoutContext);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const currentOpen = open ?? internalOpen;\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      notifyLayout();\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [notifyLayout, onOpenChange, open],\n  );\n\n  return (\n    <div\n      data-slot=\"message-bubble-collapsible\"\n      data-state={currentOpen ? \"open\" : \"closed\"}\n      className={cn(\"w-full\", className)}\n      {...props}\n    >\n      <div\n        id={contentId}\n        className={cn(\n          \"transition-[mask-image] duration-200\",\n          !currentOpen && LINE_CLAMP_CLASS[collapsedLines],\n          !currentOpen &&\n            \"[mask-image:linear-gradient(to_bottom,#000_68%,transparent_100%)]\",\n          contentClassName,\n        )}\n      >\n        {children}\n      </div>\n      <button\n        type=\"button\"\n        aria-expanded={currentOpen}\n        aria-controls={contentId}\n        onClick={() => setOpen(!currentOpen)}\n        className={cn(\n          \"mt-2 inline-flex h-7 items-center gap-1 rounded-full px-2 text-xs font-medium text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\",\n          triggerClassName,\n        )}\n      >\n        <span>{currentOpen ? lessLabel : moreLabel}</span>\n        <motion.span\n          aria-hidden=\"true\"\n          animate={{ rotate: currentOpen ? 180 : 0 }}\n          transition={reduce ? { duration: 0 } : SPRING_SWAP}\n        >\n          <ChevronDown className=\"size-3.5\" />\n        </motion.span>\n      </button>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/agents/message-context.tsx",
          "target": "@components/beui/components/agents/message-context.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\n\nimport { createContext } from \"react\";\n\nexport type MessageSide = \"start\" | \"end\";\n\nexport const MessageSideContext = createContext<MessageSide | undefined>(\n  undefined,\n);\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-message",
      "type": "registry:block",
      "title": "Beui Message",
      "description": "Message",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/message.tsx",
          "target": "@components/beui/components/agents/message.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ComponentPropsWithRef,\n  createContext,\n  type ReactNode,\n  useContext,\n} from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport { MessageSideContext } from \"@/components/beui/components/agents/message-context\";\n\nexport {\n  MessageBubble,\n  MessageBubbleCollapsible,\n  MessageBubbleContent,\n  MessageBubbleGroup,\n} from \"@/components/beui/components/agents/message-bubble\";\nexport { MessageScroller } from \"@/components/beui/components/agents/message-scroller\";\nexport type { MessageScrollerProps } from \"@/components/beui/components/agents/message-scroller\";\n\nexport type MessageFrom = \"user\" | \"assistant\";\n\ninterface MessageContextValue {\n  from: MessageFrom;\n}\n\nconst MessageContext = createContext<MessageContextValue>({\n  from: \"assistant\",\n});\n\nexport interface MessageProps\n  extends Omit<ComponentPropsWithRef<typeof motion.article>, \"children\"> {\n  from: MessageFrom;\n  /** Plays a trailing-edge pop-up once when this message row mounts. */\n  animateIn?: boolean;\n  children: ReactNode;\n}\n\nexport interface MessageGroupProps extends ComponentPropsWithRef<\"div\"> {\n  spacing?: \"compact\" | \"default\";\n}\n\nexport interface MessageAvatarProps extends ComponentPropsWithRef<\"div\"> {\n  /** Keep an empty avatar slot so grouped messages remain aligned. */\n  placeholder?: boolean;\n}\n\nexport type MessageContentProps = ComponentPropsWithRef<\"div\">;\nexport type MessageHeaderProps = ComponentPropsWithRef<\"div\">;\nexport type MessageFooterProps = ComponentPropsWithRef<\"div\">;\n\nexport type MessageMarkerProps = ComponentPropsWithRef<\"div\">;\n\nexport interface MessageTypingProps extends ComponentPropsWithRef<\"span\"> {\n  label?: string;\n}\n\n// A sent row should rise from the live edge without changing measured layout.\nconst MESSAGE_POP_UP = {\n  type: \"spring\",\n  stiffness: 480,\n  damping: 32,\n  mass: 0.62,\n} as const;\n\nexport function Message({\n  from,\n  animateIn = false,\n  children,\n  className,\n  initial,\n  animate,\n  transition,\n  exit,\n  style,\n  ...props\n}: MessageProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <MessageSideContext.Provider value={from === \"user\" ? \"end\" : \"start\"}>\n      <MessageContext.Provider value={{ from }}>\n        <motion.article\n          data-slot=\"message\"\n          data-from={from}\n          aria-label={props[\"aria-label\"] ?? `${from} message`}\n          initial={\n            initial ??\n            (animateIn && !reduce\n              ? {\n                  opacity: 0,\n                  transform: \"translateY(8px) scale(0.95)\",\n                }\n              : false)\n          }\n          animate={\n            animate ??\n            (animateIn && !reduce\n              ? {\n                  opacity: 1,\n                  transform: \"translateY(0px) scale(1)\",\n                }\n              : { opacity: 1 })\n          }\n          exit={\n            exit ??\n            (reduce\n              ? { opacity: 0 }\n              : {\n                  opacity: 0,\n                  transform: \"translateY(-3px) scale(0.99)\",\n                })\n          }\n          transition={\n            transition ?? (reduce ? { duration: 0.12 } : MESSAGE_POP_UP)\n          }\n          style={{\n            transformOrigin: from === \"user\" ? \"100% 100%\" : \"0% 100%\",\n            ...style,\n          }}\n          className={cn(\n            \"group/message flex w-full items-start gap-2\",\n            from === \"user\" ? \"flex-row-reverse\" : \"flex-row\",\n            className,\n          )}\n          {...props}\n        >\n          {children}\n        </motion.article>\n      </MessageContext.Provider>\n    </MessageSideContext.Provider>\n  );\n}\n\nexport function MessageGroup({\n  spacing = \"compact\",\n  className,\n  ...props\n}: MessageGroupProps) {\n  return (\n    <div\n      data-slot=\"message-group\"\n      className={cn(\n        \"flex w-full flex-col\",\n        spacing === \"compact\" ? \"gap-1.5\" : \"gap-4\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function MessageAvatar({\n  placeholder = false,\n  children,\n  className,\n  ...props\n}: MessageAvatarProps) {\n  return (\n    <div\n      data-slot=\"message-avatar\"\n      aria-hidden={placeholder || undefined}\n      className={cn(\n        \"grid size-7 shrink-0 place-items-center overflow-hidden rounded-full bg-muted text-xs font-medium text-muted-foreground [&_img]:size-full [&_img]:object-cover [&_svg]:size-3.5\",\n        placeholder && \"invisible\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  );\n}\n\nexport function MessageContent({ className, ...props }: MessageContentProps) {\n  const { from } = useContext(MessageContext);\n\n  return (\n    <div\n      data-slot=\"message-content\"\n      className={cn(\n        \"flex min-w-0 flex-1 flex-col gap-1.5\",\n        from === \"user\" ? \"items-end\" : \"items-start\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function MessageHeader({ className, ...props }: MessageHeaderProps) {\n  const { from } = useContext(MessageContext);\n\n  return (\n    <div\n      data-slot=\"message-header\"\n      className={cn(\n        \"flex items-center gap-1.5 px-1 text-[11px] leading-none text-muted-foreground\",\n        from === \"user\" ? \"justify-end\" : \"justify-start\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function MessageFooter({ className, ...props }: MessageFooterProps) {\n  const { from } = useContext(MessageContext);\n\n  return (\n    <div\n      data-slot=\"message-footer\"\n      className={cn(\n        \"flex min-h-5 items-center gap-1 px-1 text-[11px] text-muted-foreground\",\n        from === \"user\" ? \"justify-end\" : \"justify-start\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function MessageMarker({ className, ...props }: MessageMarkerProps) {\n  return (\n    <div\n      data-slot=\"message-marker\"\n      className={cn(\n        \"mx-auto flex w-fit max-w-[88%] items-center gap-1.5 rounded-full bg-muted/70 px-2.5 py-1 text-center text-xs text-muted-foreground\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function MessageTyping({\n  label = \"Responding\",\n  className,\n  ...props\n}: MessageTypingProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <span\n      data-slot=\"message-typing\"\n      className={cn(\"inline-flex h-5 items-center gap-1\", className)}\n      {...props}\n    >\n      <span className=\"sr-only\">{label}</span>\n      {[0, 1, 2].map((index) => (\n        <motion.span\n          key={index}\n          aria-hidden=\"true\"\n          className=\"size-1 rounded-full bg-current\"\n          animate={\n            reduce\n              ? { opacity: 0.45 }\n              : { opacity: [0.28, 0.85, 0.28], y: [0, -2, 0] }\n          }\n          transition={{\n            duration: 1.05,\n            ease: EASE_OUT,\n            repeat: Number.POSITIVE_INFINITY,\n            delay: index * 0.14,\n          }}\n        />\n      ))}\n    </span>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/agents/message-context.tsx",
          "target": "@components/beui/components/agents/message-context.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\n\nimport { createContext } from \"react\";\n\nexport type MessageSide = \"start\" | \"end\";\n\nexport const MessageSideContext = createContext<MessageSide | undefined>(\n  undefined,\n);\n"
        },
        {
          "path": "components/beui/components/agents/message-bubble.tsx",
          "target": "@components/beui/components/agents/message-bubble.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { ChevronDown } from \"lucide-react\";\nimport {\n  type HTMLMotionProps,\n  motion,\n  useReducedMotion,\n} from \"motion/react\";\nimport {\n  cloneElement,\n  type ComponentPropsWithRef,\n  createContext,\n  type ReactElement,\n  type ReactNode,\n  type Ref,\n  useCallback,\n  useContext,\n  useId,\n  useState,\n} from \"react\";\nimport {\n  EASE_OUT,\n  SPRING_LAYOUT,\n  SPRING_SWAP,\n} from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport { MessageSideContext } from \"@/components/beui/components/agents/message-context\";\n\nexport type MessageBubbleVariant =\n  | \"solid\"\n  | \"soft\"\n  | \"tint\"\n  | \"outline\"\n  | \"ghost\"\n  | \"danger\";\nexport type MessageBubbleAlign = \"start\" | \"end\";\n\ninterface MessageBubbleContextValue {\n  align?: MessageBubbleAlign;\n  animateIn: boolean;\n  variant: MessageBubbleVariant;\n}\n\nconst MessageBubbleContext = createContext<MessageBubbleContextValue>({\n  animateIn: true,\n  variant: \"soft\",\n});\nconst MessageBubbleLayoutContext = createContext<() => void>(() => {});\n\nexport interface MessageBubbleProps\n  extends Omit<HTMLMotionProps<\"div\">, \"children\"> {\n  variant?: MessageBubbleVariant;\n  /** Defaults to the surrounding Message alignment when omitted. */\n  align?: MessageBubbleAlign;\n  /** Plays the bubble entrance once when this component mounts. */\n  animateIn?: boolean;\n  children?: ReactNode;\n}\n\nexport interface MessageBubbleContentProps\n  extends ComponentPropsWithRef<\"div\"> {\n  /** Replaces the content element while preserving bubble styling. */\n  render?: ReactElement;\n}\n\nexport interface MessageBubbleGroupProps extends ComponentPropsWithRef<\"div\"> {\n  spacing?: \"compact\" | \"default\";\n}\n\nexport interface MessageBubbleCollapsibleProps\n  extends ComponentPropsWithRef<\"div\"> {\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  collapsedLines?: 2 | 3 | 4 | 5 | 6;\n  moreLabel?: ReactNode;\n  lessLabel?: ReactNode;\n  contentClassName?: string;\n  triggerClassName?: string;\n  children?: ReactNode;\n}\n\nfunction mergeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n  return (node: T | null) => {\n    for (const ref of refs) {\n      if (typeof ref === \"function\") ref(node);\n      else if (ref) ref.current = node;\n    }\n  };\n}\n\nconst BUBBLE_CONTENT_REVEAL = {\n  duration: 0.12,\n  ease: EASE_OUT,\n  delay: 0.04,\n} as const;\n\n// Sent bubbles should pop into place quickly with one restrained overshoot.\nconst BUBBLE_POP = {\n  type: \"spring\",\n  stiffness: 520,\n  damping: 27,\n  mass: 0.52,\n} as const;\n\nexport function MessageBubble({\n  variant = \"soft\",\n  align,\n  animateIn = false,\n  className,\n  children,\n  initial,\n  animate,\n  exit,\n  transition,\n  layout,\n  ...props\n}: MessageBubbleProps) {\n  const reduce = useReducedMotion() ?? false;\n  const messageSide = useContext(MessageSideContext);\n  const resolvedAlign = align ?? messageSide ?? \"start\";\n\n  return (\n    <MessageBubbleContext.Provider\n      value={{ align: resolvedAlign, animateIn, variant }}\n    >\n      <motion.div\n        data-slot=\"message-bubble\"\n        data-align={resolvedAlign}\n        data-variant={variant}\n        layout={layout}\n        initial={initial ?? false}\n        animate={animate}\n        exit={\n          exit ??\n          (reduce ? { opacity: 0 } : { opacity: 0, y: -3, scale: 0.99 })\n        }\n        transition={transition ?? (reduce ? { duration: 0.12 } : SPRING_LAYOUT)}\n        className={cn(\n          \"group/bubble flex w-full flex-col\",\n          resolvedAlign === \"end\" ? \"items-end\" : \"items-start\",\n          className,\n        )}\n        {...props}\n      >\n        {children}\n      </motion.div>\n    </MessageBubbleContext.Provider>\n  );\n}\n\nfunction bubbleContentClass(\n  variant: MessageBubbleVariant,\n  interactive: boolean,\n) {\n  return cn(\n    \"relative z-0 min-w-9 max-w-[82%] rounded-2xl px-3.5 py-2.5 text-sm leading-6 text-foreground\",\n    \"[&_a]:font-medium [&_a]:underline [&_a]:underline-offset-4 [&_code]:rounded [&_code]:bg-background/60 [&_code]:px-1 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.9em] [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_p+p]:mt-2 [&_pre]:my-2 [&_pre]:overflow-x-auto [&_pre]:rounded-xl [&_pre]:bg-background/60 [&_pre]:p-3 [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5\",\n    variant === \"solid\" && \"text-background\",\n    variant === \"ghost\" && \"w-full max-w-none rounded-none px-0 py-0\",\n    variant === \"danger\" && \"text-destructive\",\n    interactive &&\n      \"cursor-pointer text-left outline-none transition-[background-color,color,transform] duration-150 hover:brightness-[0.98] focus-visible:ring-2 focus-visible:ring-ring active:scale-[0.99]\",\n  );\n}\n\nfunction bubbleSurfaceClass(\n  variant: MessageBubbleVariant,\n  align: MessageBubbleAlign,\n) {\n  return cn(\n    \"pointer-events-none absolute inset-0 -z-10 rounded-[inherit]\",\n    align === \"end\" ? \"origin-bottom-right\" : \"origin-bottom-left\",\n    variant === \"solid\" && \"bg-foreground\",\n    variant === \"soft\" && \"bg-muted\",\n    variant === \"tint\" && \"bg-primary/10\",\n    variant === \"outline\" && \"border border-border/70 bg-background\",\n    variant === \"danger\" && \"bg-destructive/10\",\n  );\n}\n\nexport function MessageBubbleContent({\n  render,\n  className,\n  children,\n  ref,\n  ...props\n}: MessageBubbleContentProps) {\n  const reduce = useReducedMotion() ?? false;\n  const { align = \"start\", animateIn, variant } =\n    useContext(MessageBubbleContext);\n  const [layoutVersion, setLayoutVersion] = useState(0);\n  const notifyLayout = useCallback(\n    () => setLayoutVersion((version) => version + 1),\n    [],\n  );\n  const interactive =\n    render?.type === \"button\" || render?.type === \"a\";\n  const classes = cn(bubbleContentClass(variant, interactive), className);\n  const composedChildren = (\n    <>\n      {variant !== \"ghost\" ? (\n        <motion.span\n          aria-hidden=\"true\"\n          layout={reduce ? false : \"size\"}\n          layoutDependency={layoutVersion}\n          initial={\n            animateIn && !reduce\n              ? {\n                  opacity: 0,\n                  scale: 0.92,\n                }\n              : false\n          }\n          animate={{ opacity: 1, scale: 1 }}\n          transition={\n            reduce\n              ? { duration: 0 }\n              : {\n                  opacity: { duration: 0.12, ease: EASE_OUT },\n                  scale: BUBBLE_POP,\n                  layout: SPRING_LAYOUT,\n                }\n          }\n          className={bubbleSurfaceClass(variant, align)}\n        />\n      ) : null}\n      <MessageBubbleLayoutContext.Provider value={notifyLayout}>\n        <motion.div\n          initial={\n            animateIn\n              ? reduce\n                ? { opacity: 0 }\n                : { opacity: 0 }\n              : false\n          }\n          animate={{ opacity: 1 }}\n          transition={\n            reduce ? { duration: 0.12, ease: EASE_OUT } : BUBBLE_CONTENT_REVEAL\n          }\n          className=\"relative\"\n        >\n          {children}\n        </motion.div>\n      </MessageBubbleLayoutContext.Provider>\n    </>\n  );\n\n  if (render) {\n    const child = render as ReactElement<\n      Record<string, unknown> & { className?: string; ref?: Ref<HTMLElement> }\n    >;\n\n    return cloneElement(child, {\n      ...props,\n      ref: mergeRefs(child.props.ref, ref as Ref<HTMLElement> | undefined),\n      className: cn(classes, child.props.className),\n      children: composedChildren,\n      \"data-slot\": \"message-bubble-content\",\n    });\n  }\n\n  return (\n    <div\n      ref={ref}\n      data-slot=\"message-bubble-content\"\n      className={classes}\n      {...props}\n    >\n      {composedChildren}\n    </div>\n  );\n}\n\nexport function MessageBubbleGroup({\n  spacing = \"compact\",\n  className,\n  ...props\n}: MessageBubbleGroupProps) {\n  return (\n    <div\n      data-slot=\"message-bubble-group\"\n      className={cn(\n        \"flex w-full flex-col\",\n        spacing === \"compact\" ? \"gap-1.5\" : \"gap-3\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nconst LINE_CLAMP_CLASS = {\n  2: \"line-clamp-2\",\n  3: \"line-clamp-3\",\n  4: \"line-clamp-4\",\n  5: \"line-clamp-5\",\n  6: \"line-clamp-6\",\n} as const;\n\nexport function MessageBubbleCollapsible({\n  open,\n  defaultOpen = false,\n  onOpenChange,\n  collapsedLines = 4,\n  moreLabel = \"Show more\",\n  lessLabel = \"Show less\",\n  contentClassName,\n  triggerClassName,\n  className,\n  children,\n  ...props\n}: MessageBubbleCollapsibleProps) {\n  const reduce = useReducedMotion() ?? false;\n  const contentId = useId();\n  const notifyLayout = useContext(MessageBubbleLayoutContext);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const currentOpen = open ?? internalOpen;\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      notifyLayout();\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [notifyLayout, onOpenChange, open],\n  );\n\n  return (\n    <div\n      data-slot=\"message-bubble-collapsible\"\n      data-state={currentOpen ? \"open\" : \"closed\"}\n      className={cn(\"w-full\", className)}\n      {...props}\n    >\n      <div\n        id={contentId}\n        className={cn(\n          \"transition-[mask-image] duration-200\",\n          !currentOpen && LINE_CLAMP_CLASS[collapsedLines],\n          !currentOpen &&\n            \"[mask-image:linear-gradient(to_bottom,#000_68%,transparent_100%)]\",\n          contentClassName,\n        )}\n      >\n        {children}\n      </div>\n      <button\n        type=\"button\"\n        aria-expanded={currentOpen}\n        aria-controls={contentId}\n        onClick={() => setOpen(!currentOpen)}\n        className={cn(\n          \"mt-2 inline-flex h-7 items-center gap-1 rounded-full px-2 text-xs font-medium text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\",\n          triggerClassName,\n        )}\n      >\n        <span>{currentOpen ? lessLabel : moreLabel}</span>\n        <motion.span\n          aria-hidden=\"true\"\n          animate={{ rotate: currentOpen ? 180 : 0 }}\n          transition={reduce ? { duration: 0 } : SPRING_SWAP}\n        >\n          <ChevronDown className=\"size-3.5\" />\n        </motion.span>\n      </button>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/message-scroller.tsx",
          "target": "@components/beui/components/agents/message-scroller.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useReducedMotion } from \"motion/react\";\nimport {\n  type ComponentPropsWithRef,\n  type Ref,\n  useCallback,\n  useEffect,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  PreviewRail,\n  type PreviewRailItem,\n} from \"@/components/beui/components/motion/preview-rail\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nconst PREVIEW_TITLE_LENGTH = 56;\nconst PREVIEW_DESCRIPTION_LENGTH = 88;\n\nfunction truncateMessageText(text: string, limit: number) {\n  if (text.length <= limit) return text;\n  const excerpt = text.slice(0, limit);\n  const boundary = excerpt.lastIndexOf(\" \");\n  return `${excerpt.slice(0, boundary > limit * 0.65 ? boundary : limit).trim()}…`;\n}\n\nfunction getMessageText(message: HTMLElement) {\n  const surface =\n    message.querySelector<HTMLElement>('[data-slot=\"message-bubble-content\"]') ??\n    message.querySelector<HTMLElement>('[data-slot=\"message-content\"]') ??\n    message;\n  return (surface.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n}\n\nfunction getMessagePreview(\n  message: HTMLElement,\n  assistantResponse?: HTMLElement,\n) {\n  const text = getMessageText(message);\n  if (!text) {\n    return { label: \"Message\", description: undefined };\n  }\n\n  if (text.length <= PREVIEW_TITLE_LENGTH) {\n    const responseText = assistantResponse\n      ? getMessageText(assistantResponse)\n      : \"\";\n    return {\n      label: text,\n      description: responseText\n        ? truncateMessageText(responseText, PREVIEW_DESCRIPTION_LENGTH)\n        : undefined,\n    };\n  }\n\n  const titleExcerpt = text.slice(0, PREVIEW_TITLE_LENGTH);\n  const titleBoundary = titleExcerpt.lastIndexOf(\" \");\n  const titleEnd =\n    titleBoundary > PREVIEW_TITLE_LENGTH * 0.65\n      ? titleBoundary\n      : PREVIEW_TITLE_LENGTH;\n  const label = `${text.slice(0, titleEnd).trim()}…`;\n  const responseText = assistantResponse\n    ? getMessageText(assistantResponse)\n    : text.slice(titleEnd).trim();\n  return {\n    label,\n    description: responseText\n      ? truncateMessageText(responseText, PREVIEW_DESCRIPTION_LENGTH)\n      : undefined,\n  };\n}\n\nexport interface MessageScrollerProps extends ComponentPropsWithRef<\"div\"> {\n  /** Keep streamed output pinned while the reader remains near the end. */\n  followOutput?: boolean;\n  /** Distance from the end that still counts as following the output. */\n  followThreshold?: number;\n  /** Smoothly follow growing content. */\n  smooth?: boolean;\n  /** Reports when the reader leaves or returns to the live edge. */\n  onFollowChange?: (following: boolean) => void;\n  /** Accessible label for the scrollable transcript. */\n  label?: string;\n  /** Marks the transcript as waiting for more streamed content. */\n  busy?: boolean;\n  /** Adds a compact rail for navigating between rendered Message rows. */\n  navigation?: \"rail\";\n  /** Accessible label for the optional message navigation rail. */\n  navigationLabel?: string;\n  viewportClassName?: string;\n  contentClassName?: string;\n  railClassName?: string;\n  viewportRef?: Ref<HTMLElement>;\n  viewportProps?: Omit<\n    ComponentPropsWithRef<\"section\">,\n    \"children\" | \"className\" | \"ref\"\n  >;\n  contentProps?: Omit<\n    ComponentPropsWithRef<\"div\">,\n    \"children\" | \"className\" | \"ref\"\n  >;\n}\n\nexport function MessageScroller({\n  followOutput = true,\n  followThreshold = 56,\n  smooth = true,\n  onFollowChange,\n  label = \"Conversation\",\n  busy,\n  navigation,\n  navigationLabel = \"Message navigation\",\n  viewportClassName,\n  contentClassName,\n  railClassName,\n  viewportRef: externalViewportRef,\n  viewportProps,\n  contentProps,\n  className,\n  children,\n  ...props\n}: MessageScrollerProps) {\n  const reduce = useReducedMotion() ?? false;\n  const viewportRef = useRef<HTMLElement>(null);\n  const contentRef = useRef<HTMLDivElement>(null);\n  const followingRef = useRef(followOutput);\n  const programmaticScrollRef = useRef(false);\n  const scrollTimerRef = useRef<number | undefined>(undefined);\n  const frameRef = useRef<number | undefined>(undefined);\n  const railFrameRef = useRef<number | undefined>(undefined);\n  const railIdRef = useRef(new WeakMap<HTMLElement, string>());\n  const railIdCounterRef = useRef(0);\n  const railTargetsRef = useRef(new Map<string, HTMLElement>());\n  const [railItems, setRailItems] = useState<PreviewRailItem[]>([]);\n  const [activeRailId, setActiveRailId] = useState(\"\");\n  const [railOverflowing, setRailOverflowing] = useState(false);\n  const {\n    onScroll: onViewportScroll,\n    onWheel: onViewportWheel,\n    onTouchStart: onViewportTouchStart,\n    onKeyDown: onViewportKeyDown,\n    ...restViewportProps\n  } = viewportProps ?? {};\n\n  const setViewportRef = useCallback(\n    (node: HTMLElement | null) => {\n      viewportRef.current = node;\n      if (typeof externalViewportRef === \"function\") {\n        externalViewportRef(node);\n      } else if (externalViewportRef) {\n        externalViewportRef.current = node;\n      }\n    },\n    [externalViewportRef],\n  );\n\n  const setFollowing = useCallback(\n    (next: boolean) => {\n      if (followingRef.current === next) return;\n      followingRef.current = next;\n      onFollowChange?.(next);\n    },\n    [onFollowChange],\n  );\n\n  const updateActiveRailItem = useCallback(() => {\n    if (navigation !== \"rail\") return;\n    const viewport = viewportRef.current;\n    const targets = [...railTargetsRef.current.entries()];\n    if (!viewport || targets.length === 0) return;\n\n    const viewportRect = viewport.getBoundingClientRect();\n    if (viewport.scrollTop <= followThreshold) {\n      const firstId = targets[0]?.[0] ?? \"\";\n      setActiveRailId((current) => (current === firstId ? current : firstId));\n      return;\n    }\n\n    const distanceFromEnd =\n      viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;\n    if (distanceFromEnd <= followThreshold) {\n      const lastId = targets.at(-1)?.[0] ?? \"\";\n      setActiveRailId((current) => (current === lastId ? current : lastId));\n      return;\n    }\n\n    const viewportCenter = viewportRect.top + viewportRect.height / 2;\n    let nearestId = targets[0]?.[0] ?? \"\";\n    let nearestDistance = Number.POSITIVE_INFINITY;\n\n    for (const [id, element] of targets) {\n      const rect = element.getBoundingClientRect();\n      const messageCenter = rect.top + rect.height / 2;\n      const distance = Math.abs(messageCenter - viewportCenter);\n      if (distance < nearestDistance) {\n        nearestDistance = distance;\n        nearestId = id;\n      }\n    }\n\n    setActiveRailId((current) =>\n      current === nearestId ? current : nearestId,\n    );\n  }, [followThreshold, navigation]);\n\n  const syncRailItems = useCallback(() => {\n    if (navigation !== \"rail\") return;\n    const content = contentRef.current;\n    const viewport = viewportRef.current;\n    if (!content || !viewport) return;\n\n    const messages = Array.from(\n      content.querySelectorAll<HTMLElement>('[data-slot=\"message\"]'),\n    );\n    const targets = new Map<string, HTMLElement>();\n    const nextItems = messages.map((message, index) => {\n      let id = railIdRef.current.get(message);\n      if (!id) {\n        railIdCounterRef.current += 1;\n        id = `message-rail-${railIdCounterRef.current}`;\n        railIdRef.current.set(message, id);\n      }\n      targets.set(id, message);\n      const sender = message.dataset.from ?? \"conversation\";\n      const assistantResponse =\n        sender === \"user\"\n          ? messages\n              .slice(index + 1)\n              .find((candidate) => candidate.dataset.from === \"assistant\")\n          : undefined;\n      const preview = getMessagePreview(message, assistantResponse);\n\n      return {\n        id,\n        label: preview.label,\n        description: preview.description,\n        ariaLabel: `Go to ${sender} message ${index + 1} of ${messages.length}`,\n      };\n    });\n\n    railTargetsRef.current = targets;\n    setRailItems((current) => {\n      const unchanged =\n        current.length === nextItems.length &&\n        current.every(\n          (item, index) =>\n            item.id === nextItems[index]?.id &&\n            item.label === nextItems[index]?.label &&\n            item.description === nextItems[index]?.description &&\n            item.ariaLabel === nextItems[index]?.ariaLabel,\n        );\n      return unchanged ? current : nextItems;\n    });\n    setRailOverflowing(\n      viewport.scrollHeight > viewport.clientHeight + 1 && messages.length > 1,\n    );\n  }, [navigation]);\n\n  const scheduleRailSync = useCallback(() => {\n    if (navigation !== \"rail\") return;\n    if (railFrameRef.current) cancelAnimationFrame(railFrameRef.current);\n    railFrameRef.current = requestAnimationFrame(() => {\n      syncRailItems();\n      updateActiveRailItem();\n    });\n  }, [navigation, syncRailItems, updateActiveRailItem]);\n\n  const scrollToEnd = useCallback((behavior: ScrollBehavior) => {\n    const viewport = viewportRef.current;\n    if (!viewport) return;\n\n    programmaticScrollRef.current = true;\n    if (typeof viewport.scrollTo === \"function\") {\n      viewport.scrollTo({ top: viewport.scrollHeight, behavior });\n    } else {\n      viewport.scrollTop = viewport.scrollHeight;\n    }\n    if (scrollTimerRef.current) window.clearTimeout(scrollTimerRef.current);\n    scrollTimerRef.current = window.setTimeout(() => {\n      programmaticScrollRef.current = false;\n    }, behavior === \"smooth\" ? 320 : 0);\n  }, []);\n\n  const handleScroll = useCallback(() => {\n    const viewport = viewportRef.current;\n    if (!viewport || programmaticScrollRef.current) return;\n\n    const distance =\n      viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;\n    setFollowing(distance <= followThreshold);\n    updateActiveRailItem();\n  }, [followThreshold, setFollowing, updateActiveRailItem]);\n\n  const leaveLiveEdge = useCallback(() => {\n    programmaticScrollRef.current = false;\n  }, []);\n\n  useLayoutEffect(() => {\n    followingRef.current = followOutput;\n    if (!followOutput) return;\n\n    frameRef.current = requestAnimationFrame(() => scrollToEnd(\"auto\"));\n    return () => {\n      if (frameRef.current) cancelAnimationFrame(frameRef.current);\n    };\n  }, [followOutput, scrollToEnd]);\n\n  useEffect(() => {\n    const content = contentRef.current;\n    if (!content || typeof ResizeObserver === \"undefined\") return;\n\n    const observer = new ResizeObserver(() => {\n      scheduleRailSync();\n      if (!followOutput || !followingRef.current) return;\n      scrollToEnd(reduce || !smooth ? \"auto\" : \"smooth\");\n    });\n    observer.observe(content);\n\n    return () => observer.disconnect();\n  }, [followOutput, reduce, scheduleRailSync, scrollToEnd, smooth]);\n\n  useEffect(() => {\n    if (navigation !== \"rail\") {\n      railTargetsRef.current.clear();\n      setRailItems([]);\n      setRailOverflowing(false);\n      return;\n    }\n\n    const content = contentRef.current;\n    const viewport = viewportRef.current;\n    if (!content || !viewport) return;\n\n    scheduleRailSync();\n    const mutationObserver =\n      typeof MutationObserver === \"undefined\"\n        ? null\n        : new MutationObserver(scheduleRailSync);\n    mutationObserver?.observe(content, {\n      childList: true,\n      characterData: true,\n      subtree: true,\n    });\n\n    const resizeObserver =\n      typeof ResizeObserver === \"undefined\"\n        ? null\n        : new ResizeObserver(scheduleRailSync);\n    resizeObserver?.observe(content);\n    resizeObserver?.observe(viewport);\n\n    return () => {\n      mutationObserver?.disconnect();\n      resizeObserver?.disconnect();\n    };\n  }, [navigation, scheduleRailSync]);\n\n  useEffect(\n    () => () => {\n      if (scrollTimerRef.current) window.clearTimeout(scrollTimerRef.current);\n      if (frameRef.current) cancelAnimationFrame(frameRef.current);\n      if (railFrameRef.current) cancelAnimationFrame(railFrameRef.current);\n    },\n    [],\n  );\n\n  const scrollToRailItem = useCallback(\n    (item: PreviewRailItem) => {\n      const viewport = viewportRef.current;\n      const target = railTargetsRef.current.get(item.id);\n      if (!viewport || !target) return;\n\n      const lastItem = railItems.at(-1)?.id === item.id;\n      setActiveRailId(item.id);\n      if (lastItem) {\n        setFollowing(true);\n        scrollToEnd(reduce || !smooth ? \"auto\" : \"smooth\");\n        return;\n      }\n\n      setFollowing(false);\n      programmaticScrollRef.current = true;\n      const viewportRect = viewport.getBoundingClientRect();\n      const targetRect = target.getBoundingClientRect();\n      const top =\n        viewport.scrollTop +\n        targetRect.top -\n        viewportRect.top -\n        (viewport.clientHeight - targetRect.height) / 2;\n      const behavior = reduce || !smooth ? \"auto\" : \"smooth\";\n\n      if (typeof viewport.scrollTo === \"function\") {\n        viewport.scrollTo({ top, behavior });\n      } else {\n        viewport.scrollTop = top;\n      }\n      if (scrollTimerRef.current) window.clearTimeout(scrollTimerRef.current);\n      scrollTimerRef.current = window.setTimeout(() => {\n        programmaticScrollRef.current = false;\n      }, behavior === \"smooth\" ? 320 : 0);\n    },\n    [railItems, reduce, scrollToEnd, setFollowing, smooth],\n  );\n\n  const viewport = (\n    <section\n      ref={setViewportRef}\n      aria-label={label}\n      {...restViewportProps}\n      onScroll={(event) => {\n        handleScroll();\n        onViewportScroll?.(event);\n      }}\n      onWheel={(event) => {\n        leaveLiveEdge();\n        onViewportWheel?.(event);\n      }}\n      onTouchStart={(event) => {\n        leaveLiveEdge();\n        onViewportTouchStart?.(event);\n      }}\n      onKeyDown={(event) => {\n        if ([\"ArrowUp\", \"PageUp\", \"Home\"].includes(event.key)) {\n          leaveLiveEdge();\n        }\n        onViewportKeyDown?.(event);\n      }}\n      className={cn(\n        \"h-full overflow-y-auto overscroll-contain outline-none [overflow-anchor:none] focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n        navigation === \"rail\"\n          ? \"[-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\"\n          : \"[scrollbar-gutter:stable]\",\n        viewportClassName,\n        navigation === \"rail\" && railOverflowing && \"pr-10\",\n      )}\n    >\n      <div\n        ref={contentRef}\n        role=\"log\"\n        aria-live=\"polite\"\n        aria-relevant=\"additions text\"\n        aria-busy={busy}\n        className={contentClassName}\n        {...contentProps}\n      >\n        {children}\n      </div>\n    </section>\n  );\n\n  return (\n    <div\n      data-slot=\"message-scroller\"\n      className={cn(\"min-h-0\", className)}\n      {...props}\n    >\n      {navigation === \"rail\" ? (\n        <PreviewRail\n          items={railOverflowing ? railItems : []}\n          label={navigationLabel}\n          activeId={activeRailId}\n          onItemSelect={scrollToRailItem}\n          previewSide=\"before\"\n          highlightActive\n          itemSize={14}\n          className=\"h-full min-h-0 overflow-hidden\"\n          previewContainerClassName=\"right-8 left-3\"\n          previewClassName=\"mr-1 w-64 max-w-full [&_[data-slot=preview-rail-card]]:h-20 [&_[data-slot=preview-rail-card]]:overflow-hidden [&_[data-slot=preview-rail-card]]:p-3 [&_[data-slot=preview-rail-title]]:line-clamp-1 [&_[data-slot=preview-rail-title]]:text-xs [&_[data-slot=preview-rail-title]]:leading-4 [&_[data-slot=preview-rail-description]]:line-clamp-2 [&_[data-slot=preview-rail-description]]:text-xs [&_[data-slot=preview-rail-description]]:leading-4\"\n          railClassName={cn(\n            \"absolute inset-y-3 right-1 w-7 content-center py-1 [&_[data-slot=preview-rail-item]]:w-7 [&_[data-slot=preview-rail-item]]:justify-end [&_[data-slot=preview-rail-tick]]:h-px [&_[data-slot=preview-rail-tick]]:w-4 [&_[data-slot=preview-rail-tick]]:origin-right\",\n            railOverflowing\n              ? \"pointer-events-auto opacity-100\"\n              : \"pointer-events-none opacity-0\",\n            railClassName,\n          )}\n        >\n          {viewport}\n        </PreviewRail>\n      ) : (\n        viewport\n      )}\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/preview-rail.tsx",
          "target": "@components/beui/components/motion/preview-rail.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type MouseEvent,\n  type PointerEvent,\n  type ReactNode,\n  useCallback,\n  useId,\n  useRef,\n  useState,\n} from \"react\";\nimport { EASE_OUT, SPRING_LAYOUT } from \"@/components/beui/lib/ease\";\nimport { useDismiss } from \"@/components/beui/lib/hooks/use-dismiss\";\nimport { useHoverGesture } from \"@/components/beui/lib/hooks/use-hover-gesture\";\nimport { useTapGesture } from \"@/components/beui/lib/hooks/use-tap-gesture\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface PreviewRailItem {\n  id: string;\n  label: string;\n  ariaLabel?: string;\n  description?: ReactNode;\n  href?: string;\n  target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\";\n  rel?: string;\n}\n\nexport interface PreviewRailProps {\n  items: PreviewRailItem[];\n  label?: string;\n  orientation?: \"vertical\" | \"horizontal\";\n  activeId?: string;\n  defaultActiveId?: string;\n  onActiveChange?: (id: string) => void;\n  onItemSelect?: (item: PreviewRailItem) => void;\n  renderPreview?: (item: PreviewRailItem) => ReactNode;\n  showPreview?: boolean;\n  previewSide?: \"before\" | \"after\";\n  highlightActive?: boolean;\n  itemSize?: number;\n  children?: ReactNode;\n  className?: string;\n  railClassName?: string;\n  previewContainerClassName?: string;\n  previewClassName?: string;\n}\n\nfunction DefaultPreview({ item }: { item: PreviewRailItem }) {\n  return (\n    <div\n      data-slot=\"preview-rail-card\"\n      className=\"rounded-2xl border border-border bg-card p-4 shadow-sm\"\n    >\n      <p\n        data-slot=\"preview-rail-title\"\n        className=\"font-medium text-card-foreground\"\n      >\n        {item.label}\n      </p>\n      {item.description ? (\n        <div\n          data-slot=\"preview-rail-description\"\n          className=\"mt-1 text-sm leading-6 text-muted-foreground\"\n        >\n          {item.description}\n        </div>\n      ) : null}\n    </div>\n  );\n}\n\nexport function PreviewRail({\n  items,\n  label = \"Section navigation\",\n  orientation = \"vertical\",\n  activeId,\n  defaultActiveId,\n  onActiveChange,\n  onItemSelect,\n  renderPreview,\n  showPreview = true,\n  previewSide = \"after\",\n  highlightActive = false,\n  itemSize = 24,\n  children,\n  className,\n  railClassName,\n  previewContainerClassName,\n  previewClassName,\n}: PreviewRailProps) {\n  const uid = useId();\n  const reduce = useReducedMotion();\n  const rootRef = useRef<HTMLDivElement>(null);\n  const [internalActiveId, setInternalActiveId] = useState(\n    defaultActiveId ?? items[0]?.id ?? \"\",\n  );\n  const [hoveredId, setHoveredId] = useState<string | null>(null);\n  // A finger cannot hover, so a tap lights the tick instead. Kept apart from\n  // the hovered one: they end in different ways, and a stray mouse move must\n  // not clear a tick the keyboard or a tap chose.\n  const [pinnedId, setPinnedId] = useState<string | null>(null);\n  const [focusedId, setFocusedId] = useState<string | null>(null);\n  // A click carries no pointerType, so the pointerdown before it is what says\n  // whether the activation was a tap. Keyboard activation has none at all.\n  const tap = useTapGesture<boolean>();\n  const hover = useHoverGesture();\n\n  const clearPinned = useCallback(() => setPinnedId(null), []);\n\n  // The next tap outside the rail stands in for the pointer leaving it. The\n  // card is a preview, so that tap passes through to whatever it landed on.\n  useDismiss(pinnedId !== null, clearPinned, rootRef);\n\n  const requestedActiveId = activeId ?? internalActiveId;\n  const selectedId = items.some((item) => item.id === requestedActiveId)\n    ? requestedActiveId\n    : (items[0]?.id ?? \"\");\n  const displayedId = hoveredId ?? pinnedId ?? focusedId ?? \"\";\n  const highlightedId = displayedId || (highlightActive ? selectedId : \"\");\n  const displayedIndex = items.findIndex((item) => item.id === highlightedId);\n  const rowTemplate = items.length\n    ? `repeat(${items.length}, ${itemSize}px)`\n    : undefined;\n  const isHorizontal = orientation === \"horizontal\";\n\n  const selectItem = (id: string) => {\n    if (activeId === undefined) setInternalActiveId(id);\n    onActiveChange?.(id);\n  };\n\n  return (\n    <motion.div\n      layoutRoot\n      ref={rootRef}\n      onBlur={(event) => {\n        // Both tick sources leave with the focus: a tap does not always land\n        // focus, but when it does, tabbing away must not strand the card.\n        if (!event.currentTarget.contains(event.relatedTarget)) {\n          setFocusedId(null);\n          setPinnedId(null);\n        }\n      }}\n      className={cn(\n        \"isolate relative flex w-full overflow-visible\",\n        isHorizontal\n          ? \"min-h-64 flex-col items-center justify-center\"\n          : \"min-h-80\",\n        className,\n      )}\n    >\n      <nav\n        aria-label={label}\n        onPointerLeave={(event) => {\n          // A touch pointer leaves on lift, which would clear the tick the tap\n          // just chose — that one is cleared by the outside tap instead.\n          if (hover.leave(event)) setHoveredId(null);\n        }}\n        style={\n          isHorizontal\n            ? { gridTemplateColumns: rowTemplate }\n            : { gridTemplateRows: rowTemplate }\n        }\n        className={cn(\n          \"relative z-10 grid shrink-0\",\n          isHorizontal\n            ? \"h-12 w-fit max-w-full self-center justify-center\"\n            : \"w-12 content-center\",\n          railClassName,\n        )}\n      >\n        {items.map((item, index) => {\n          const selected = item.id === selectedId;\n          const highlighted = item.id === highlightedId;\n          const distance =\n            displayedIndex < 0 ? Number.POSITIVE_INFINITY : Math.abs(index - displayedIndex);\n          const scale = highlighted\n            ? 1\n            : distance === 1\n              ? 0.68\n              : distance === 2\n                ? 0.44\n                : 0.25;\n\n          const itemContent = (\n            <>\n              <motion.span\n                data-slot=\"preview-rail-tick\"\n                aria-hidden=\"true\"\n                animate={isHorizontal ? { scaleY: scale } : { scaleX: scale }}\n                transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n                className={cn(\n                  \"block bg-current\",\n                  isHorizontal\n                    ? \"h-12 w-0.5 origin-bottom\"\n                    : \"h-0.5 w-12 origin-left\",\n                  highlighted ? \"text-foreground\" : undefined,\n                )}\n              />\n            </>\n          );\n\n          const sharedClassName = cn(\n            \"relative flex text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n            isHorizontal\n              ? \"h-12 w-6 items-end justify-center\"\n              : \"h-6 w-12 items-center\",\n          );\n          const sharedStyle = isHorizontal\n            ? { width: itemSize }\n            : { height: itemSize };\n          const handlePointerEnter = (event: PointerEvent<HTMLElement>) => {\n            if (hover.enter(event)) setHoveredId(item.id);\n          };\n          const handlePointerDown = (event: PointerEvent<HTMLElement>) => {\n            tap.start(event, pinnedId === item.id);\n            setFocusedId(null);\n          };\n          // A gesture the platform takes away sends no click, and a key press\n          // starts an activation that never had a pointer behind it: either\n          // one leaves a record the next click would read as a tap of its own.\n          const dropGesture = () => tap.drop();\n          const handleFocus = (currentTarget: HTMLElement) => {\n            if (currentTarget.matches(\":focus-visible\")) {\n              setFocusedId(item.id);\n            }\n          };\n          const handleSelect = (event: MouseEvent<HTMLElement>) => {\n            const gesture = tap.take();\n            const tapped =\n              gesture !== null && gesture.pointerType !== \"mouse\";\n\n            if (tapped) {\n              // A link would otherwise show its preview and leave the page in\n              // the same tap, so the card is never read: the first tap lights\n              // the tick, the second follows the link.\n              if (item.href && !gesture.state) {\n                event.preventDefault();\n                setPinnedId(item.id);\n                return;\n              }\n              setPinnedId(item.id);\n            }\n\n            selectItem(item.id);\n            onItemSelect?.(item);\n          };\n\n          return item.href ? (\n            <a\n              key={item.id}\n              data-slot=\"preview-rail-item\"\n              href={item.href}\n              target={item.target}\n              rel={\n                item.rel ??\n                (item.target === \"_blank\" ? \"noreferrer noopener\" : undefined)\n              }\n              aria-label={item.ariaLabel ?? item.label}\n              aria-current={selected ? \"page\" : undefined}\n              onPointerEnter={handlePointerEnter}\n              onPointerDown={handlePointerDown}\n              onPointerCancel={dropGesture}\n              onKeyDown={dropGesture}\n              onFocus={(event) => handleFocus(event.currentTarget)}\n              onClick={handleSelect}\n              style={sharedStyle}\n              className={sharedClassName}\n            >\n              {itemContent}\n            </a>\n          ) : (\n            <button\n              key={item.id}\n              data-slot=\"preview-rail-item\"\n              type=\"button\"\n              aria-label={item.ariaLabel ?? item.label}\n              aria-current={selected ? \"location\" : undefined}\n              onPointerEnter={handlePointerEnter}\n              onPointerDown={handlePointerDown}\n              onPointerCancel={dropGesture}\n              onKeyDown={dropGesture}\n              onFocus={(event) => handleFocus(event.currentTarget)}\n              onClick={handleSelect}\n              style={sharedStyle}\n              className={sharedClassName}\n            >\n              {itemContent}\n            </button>\n          );\n        })}\n      </nav>\n\n      {showPreview ? (\n        <div\n          aria-hidden=\"true\"\n          style={\n            isHorizontal\n              ? { gridTemplateColumns: rowTemplate }\n              : { gridTemplateRows: rowTemplate }\n          }\n          className={cn(\n            \"pointer-events-none absolute z-50 grid\",\n            isHorizontal\n              ? \"top-1/2 left-1/2 h-5 w-fit max-w-full -translate-x-1/2 -translate-y-1/2 justify-center\"\n              : previewSide === \"before\"\n                ? \"inset-y-0 right-16 left-4 content-center\"\n                : \"inset-y-0 right-4 left-16 content-center\",\n            previewContainerClassName,\n          )}\n        >\n          {items.map((item) => (\n            <div\n              key={item.id}\n              style={\n                isHorizontal ? { width: itemSize } : { height: itemSize }\n              }\n              className={cn(\n                \"relative flex items-center\",\n                isHorizontal ? \"justify-center\" : undefined,\n              )}\n            >\n              {item.id === displayedId ? (\n                <div\n                  className={cn(\n                    isHorizontal\n                      ? \"absolute bottom-12 left-1/2 w-72 -translate-x-1/2\"\n                      : cn(\n                          \"w-full max-w-sm\",\n                          previewSide === \"before\" && \"ml-auto\",\n                        ),\n                    previewClassName,\n                  )}\n                >\n                  <motion.div\n                    layoutId={`preview-rail-card-${uid}`}\n                    transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n                  >\n                    <AnimatePresence mode=\"wait\" initial={false}>\n                      <motion.div\n                        key={item.id}\n                        initial={\n                          reduce\n                            ? { opacity: 0 }\n                            : { opacity: 0, y: 4, filter: \"blur(6px)\" }\n                        }\n                        animate={\n                          reduce\n                            ? { opacity: 1 }\n                            : { opacity: 1, y: 0, filter: \"blur(0px)\" }\n                        }\n                        exit={\n                          reduce\n                            ? { opacity: 0 }\n                            : {\n                                opacity: 0,\n                                y: -2,\n                                filter: \"blur(4px)\",\n                                transition: {\n                                  duration: 0.12,\n                                  ease: EASE_OUT,\n                                },\n                              }\n                        }\n                        transition={{\n                          duration: reduce ? 0 : 0.18,\n                          ease: EASE_OUT,\n                        }}\n                      >\n                        {renderPreview ? (\n                          renderPreview(item)\n                        ) : (\n                          <DefaultPreview item={item} />\n                        )}\n                      </motion.div>\n                    </AnimatePresence>\n                  </motion.div>\n                </div>\n              ) : null}\n            </div>\n          ))}\n        </div>\n      ) : null}\n\n      {children ? (\n        <div className=\"min-h-0 min-w-0 flex-1\">{children}</div>\n      ) : null}\n    </motion.div>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/hooks/use-dismiss.ts",
          "target": "@components/beui/lib/hooks/use-dismiss.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { type RefObject, useEffect } from \"react\";\n\n/**\n * What the dismissing gesture does to the control it landed on.\n *\n * `\"pass-through\"` is the platform norm (native popover light-dismiss): the\n * tap closes the overlay *and* activates whatever was under it. Use\n * `\"consume\"` where the open overlay sits over or beside controls that would\n * be costly to trigger by accident — the dismissal then swallows the\n * activation too, so the gesture only closes.\n */\nexport type DismissBehavior = \"pass-through\" | \"consume\";\n\nexport interface DismissOptions {\n  /** Default `\"pass-through\"`. */\n  behavior?: DismissBehavior;\n  /** Dismiss on Escape as well. Default true. */\n  escape?: boolean;\n  /** Return true for an outside target that should *not* dismiss. Must be stable. */\n  ignore?: (target: Element) => boolean;\n}\n\n/**\n * What every currently open dismiss scope counts as inside itself. A consumed\n * dismissal reads this to tell a stray gesture from one that belongs to an\n * overlay in front of it: overlays have no shared z-order to consult, but the\n * one the gesture landed in has said as much by registering it.\n */\nconst openScopes = new Set<(target: Element) => boolean>();\n\nfunction claimedByAnotherScope(\n  self: (target: Element) => boolean,\n  target: Element,\n) {\n  for (const scope of openScopes) {\n    if (scope !== self && scope(target)) return true;\n  }\n  return false;\n}\n\n// preventDefault on pointerdown does not suppress the click that follows, so\n// consuming a gesture means swallowing that click itself. The swallower\n// deliberately outlives the effect that installed it — the dismissal it\n// belongs to has already unmounted or re-rendered by the time the click lands.\n// It releases on that click, or on the next gesture if the pointer is dragged\n// away and no click ever arrives, so it can never eat a later one. A keydown\n// releases it too: a gesture that ends with neither a click nor a cancel would\n// otherwise leave it armed, and the click Enter synthesizes on some focused\n// control is not the one this dismissal was owed.\nfunction consumeActivation(source: Event) {\n  const swallow = (event: MouseEvent) => {\n    event.preventDefault();\n    event.stopPropagation();\n    release();\n  };\n  const restart = (event: Event) => {\n    if (event !== source) release();\n  };\n  const release = () => {\n    window.removeEventListener(\"click\", swallow, true);\n    window.removeEventListener(\"pointerdown\", restart, true);\n    window.removeEventListener(\"pointercancel\", restart, true);\n    window.removeEventListener(\"keydown\", release, true);\n  };\n  window.addEventListener(\"click\", swallow, true);\n  window.addEventListener(\"pointerdown\", restart, true);\n  window.addEventListener(\"pointercancel\", restart, true);\n  window.addEventListener(\"keydown\", release, true);\n}\n\n/**\n * Close an open overlay on Escape or a pointerdown outside `ref`. Pass `null`\n * for `ref` when what counts as inside isn't one element, and say so with\n * `ignore` instead.\n *\n * The pointerdown listener is capture-phase: a bubble-phase one is blinded by\n * any handler in between that stops propagation, and an overlay cannot know\n * what it is layered over. `onDismiss` and `ignore` must be stable (wrap in\n * useCallback) so the listeners aren't re-bound every render while open.\n */\nexport function useDismiss(\n  open: boolean,\n  onDismiss: () => void,\n  ref: RefObject<HTMLElement | null> | null,\n  {\n    behavior = \"pass-through\",\n    escape: dismissOnEscape = true,\n    ignore,\n  }: DismissOptions = {},\n) {\n  useEffect(() => {\n    if (!open) return;\n    const inside = (target: Element) =>\n      Boolean(ref?.current?.contains(target)) || Boolean(ignore?.(target));\n    const onKey = (event: KeyboardEvent) => {\n      if (dismissOnEscape && event.key === \"Escape\") onDismiss();\n    };\n    const onPointer = (event: PointerEvent) => {\n      const target = event.target as Element | null;\n      if (!target || inside(target)) return;\n      // Outside this overlay, but inside one that is also open: the gesture is\n      // that overlay's to answer, and swallowing its click from behind would\n      // cost the user the control they actually aimed at.\n      if (behavior === \"consume\" && !claimedByAnotherScope(inside, target)) {\n        consumeActivation(event);\n      }\n      onDismiss();\n    };\n    openScopes.add(inside);\n    window.addEventListener(\"keydown\", onKey);\n    window.addEventListener(\"pointerdown\", onPointer, true);\n    return () => {\n      openScopes.delete(inside);\n      window.removeEventListener(\"keydown\", onKey);\n      window.removeEventListener(\"pointerdown\", onPointer, true);\n    };\n  }, [open, onDismiss, ref, behavior, dismissOnEscape, ignore]);\n}\n"
        },
        {
          "path": "components/beui/lib/hooks/use-hover-gesture.ts",
          "target": "@components/beui/lib/hooks/use-hover-gesture.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useMemo, useRef } from \"react\";\nimport { isHoveringPointer } from \"@/components/beui/lib/touch\";\n\ninterface BoundaryEvent {\n  pointerId: number;\n  pointerType: string;\n  buttons: number;\n}\n\nexport interface HoverGesture {\n  /** True when this enter starts a hover: the pointer arrived resting, not pressing. */\n  enter: (event: BoundaryEvent) => boolean;\n  /** True when this leave ends a hover that entered as one. */\n  leave: (event: BoundaryEvent) => boolean;\n}\n\n/**\n * Pairs a surface's enter with its leave, per pointer.\n *\n * `isHoveringPointer` answers the question the *enter* asks — is this pointer\n * resting on the surface or pressing it — and both boundary cases go wrong if\n * the leave is asked the same question again:\n *\n * - A pen with no hover never rests. It arrives in contact, taps, and the spec\n *   then requires its boundary events after `pointerup`, so the leave carries\n *   `buttons: 0` and reads as a mouse gliding off. Hover teardown then undid\n *   the tap — the panel the pen had just opened closed under it.\n * - A mouse pressed on the surface and dragged off leaves with `buttons: 1`.\n *   Skipping teardown there strands the surface open: the release happens\n *   outside, and no second leave ever comes.\n *\n * So the state a hover holds is released by the pointer that took it, whatever\n * the buttons say at the boundary, and a pointer that arrived in contact never\n * took it in the first place. Contact is the exception tracked here, not\n * hover: a leave from a pointer this surface never saw enter — mounted under\n * the cursor, say — still counts, since the alternative is state with no way\n * out.\n */\nexport function useHoverGesture(): HoverGesture {\n  const contact = useRef(new Set<number>());\n\n  return useMemo(\n    () => ({\n      enter: (event) => {\n        if (isHoveringPointer(event)) {\n          contact.current.delete(event.pointerId);\n          return true;\n        }\n        contact.current.add(event.pointerId);\n        return false;\n      },\n      leave: (event) => {\n        const arrivedInContact = contact.current.delete(event.pointerId);\n        return !arrivedInContact && event.pointerType !== \"touch\";\n      },\n    }),\n    [],\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/touch.ts",
          "target": "@components/beui/lib/touch.ts",
          "type": "registry:component",
          "content": "// Shared touch primitives. iOS and iPadOS run their own gestures on top of the\n// page — the long-press selection callout and the selection it drags in with\n// it — and they win: once the platform claims a touch it cancels ours\n// mid-gesture, so a press-and-hold or a drag simply dies. Surfaces that own\n// their gesture have to opt out.\n//\n// What the two classes below cover, precisely:\n// - `-webkit-touch-callout: none` stops iOS's long-press callout. WebKit-only:\n//   it is not a property other engines have, so it is inert everywhere else.\n// - `user-select: none` stops the long-press selection on every engine,\n//   Android included, and stops a drag from painting a selection under the\n//   cursor. It is inherited, so it reaches every descendant — which is why the\n//   two classes differ only in whether they apply it unconditionally.\n// What neither covers:\n// - Chrome for Android's long-press menu on a link or an image. No CSS\n//   suppresses it; a gesture surface that wraps one needs its own\n//   `onContextMenu` with `preventDefault()`.\n// - The native drag of an `<img>` or `<a>` descendant. `-webkit-user-drag` is\n//   not inherited and plain divs and buttons are not drag sources, so setting\n//   it on the surface does nothing — the child itself needs `draggable={false}`.\n\n/**\n * Classes for a surface that *is* the control: a thumb, a drum, a stage, a\n * handle, a hold button. Selection is suppressed on every input, because a\n * drag that highlights the control's own label is wrong on a mouse too.\n * Compose with `touch-none` when the surface also owns the scroll axis — leave\n * it off when the page must still scroll from there.\n */\nexport const TOUCH_GESTURE_CLASS = \"select-none [-webkit-touch-callout:none]\";\n\n/**\n * The same opt-out for a gesture surface that wraps content the consumer owns:\n * a scroller, a context-menu trigger, a sheet header, a list row. Selection is\n * suppressed only where the platform runs its own press gestures — a coarse\n * pointer — so a mouse user can still select and copy that content. If the\n * gesture itself would paint a selection under the cursor, add `select-none`\n * for the duration of the gesture rather than reaching for\n * `TOUCH_GESTURE_CLASS`.\n *\n * `pointer: coarse` describes the *primary* pointer and nothing else, so a\n * hybrid machine reads it wrong in both directions: a tablet with a mouse\n * plugged in keeps touch as primary and loses mouse selection, and a laptop\n * with a touchscreen keeps the mouse as primary and leaves selection live\n * under a finger. No media query can answer per interaction — the query is\n * about the device, and the question is about the gesture in progress. The\n * default stays here because it is right on the machines that are one thing or\n * the other, and losing a selection is a nuisance; where the miss costs a\n * *gesture* instead, the surface pairs it with `holdSelection` on the press.\n */\nexport const TOUCH_GESTURE_CONTENT_CLASS =\n  \"[-webkit-touch-callout:none] pointer-coarse:select-none\";\n\n/**\n * Suppress selection on `element` for as long as a gesture is running on it,\n * whatever the primary pointer of the machine happens to be. Returns the\n * release. Inline, so it wins over the class above and is gone again the\n * moment the gesture ends.\n *\n * For the press gestures a native selection would otherwise steal — a\n * long-press that opens a menu. Elsewhere prefer the classes: a surface that\n * takes selection away for the whole session is a surface whose text nobody\n * can copy.\n */\nexport function holdSelection(element: HTMLElement) {\n  element.style.setProperty(\"user-select\", \"none\");\n  element.style.setProperty(\"-webkit-user-select\", \"none\");\n  return () => {\n    element.style.removeProperty(\"user-select\");\n    element.style.removeProperty(\"-webkit-user-select\");\n  };\n}\n\n/**\n * Pointer capture, best effort. WebKit throws `NotFoundError` when the pointer\n * is already gone by the time the handler runs — routine on iOS, where the\n * system can claim the touch first — and an uncaught throw takes the rest of\n * the handler, the gesture included, down with it. Touch pointers carry\n * implicit capture anyway, so losing it is never fatal.\n */\nexport function capturePointer(element: Element, pointerId: number) {\n  try {\n    element.setPointerCapture(pointerId);\n  } catch {\n    // Pointer is no longer active — implicit capture still applies on touch.\n  }\n}\n\n/** Release a capture taken with `capturePointer`, ignoring a stale pointer. */\nexport function releasePointer(element: Element, pointerId: number) {\n  try {\n    if (element.hasPointerCapture(pointerId)) {\n      element.releasePointerCapture(pointerId);\n    }\n  } catch {\n    // Capture was already dropped by the browser.\n  }\n}\n\n/**\n * Whether this event came from a pointer that is *hovering*: not a touch, and\n * not currently pressed. Which input the user is holding right now is not\n * something a device capability can answer — a touchscreen laptop hovers and\n * taps, and iPadOS reports a fine hovering pointer for a finger — so both\n * paths stay live and each handler branches on the event it was given.\n *\n * A pen resting on the glass is making contact, not hovering: `buttons` is the\n * tell, and it sends a pen tap down the same route a finger takes.\n *\n * This answers what an *enter* asks. A leave is the other half of a pair and\n * has to be read against the enter that started it — `useHoverGesture` in\n * `lib/hooks/use-hover-gesture` does that, and hover surfaces should use it\n * rather than asking this question twice.\n */\nexport const isHoveringPointer = (event: {\n  pointerType: string;\n  buttons: number;\n}) => event.pointerType !== \"touch\" && event.buttons === 0;\n"
        },
        {
          "path": "components/beui/lib/hooks/use-tap-gesture.ts",
          "target": "@components/beui/lib/hooks/use-tap-gesture.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useMemo, useRef } from \"react\";\n\n/** What a pointerdown recorded, read back by the click that ends its gesture. */\nexport interface TapRecord<S> {\n  /** Which input started the gesture. */\n  pointerType: string;\n  /** What the surface was showing when it started. */\n  state: S;\n}\n\nexport interface TapGesture<S> {\n  /** Record the gesture a pointerdown starts, with the state it starts in. */\n  start: (event: { pointerType: string }, state: S) => void;\n  /** Read the record and clear it. `null` when no pointer is behind this click. */\n  take: () => TapRecord<S> | null;\n  /** Drop the record: this gesture will never spend it on a click. */\n  drop: () => void;\n}\n\n/**\n * The pointer gesture behind a click, recorded where the click cannot report\n * it. A `click` carries no `pointerType` in the engines that matter, so the\n * `pointerdown` before it is the only thing that says which input activated\n * the control — and whether one did at all, since keyboard activation\n * synthesizes a click with no pointer behind it.\n *\n * State goes in with the record because a click reports that no better: a\n * browser that focuses a control on contact can open the very panel the tap\n * was meant to open, and reading \"is it open\" at click time then undoes it.\n * What the gesture started against is what it acts on.\n *\n * The record is spent by one click and dropped by everything else, because a\n * record that outlives its gesture is worse than none:\n *\n * - A scroll or an OS gesture takes the touch away — `pointercancel`, no click\n *   ever — and the finger would sit in the record until some later click.\n * - That later click is often `Enter` on a keyboard, which arrives with no\n *   pointerdown of its own and would inherit the abandoned finger. A keydown\n *   is the start of a keyboard activation and never part of a tap, so it drops\n *   the record too.\n *\n * Both ends have to be wired by the surface: `drop` on `onPointerCancel` and\n * on `onKeyDown`.\n */\nexport function useTapGesture<S>(): TapGesture<S> {\n  const record = useRef<TapRecord<S> | null>(null);\n\n  return useMemo(\n    () => ({\n      start: (event, state) => {\n        record.current = { pointerType: event.pointerType, state };\n      },\n      take: () => {\n        const spent = record.current;\n        record.current = null;\n        return spent;\n      },\n      drop: () => {\n        record.current = null;\n      },\n    }),\n    [],\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-message-scroller",
      "type": "registry:block",
      "title": "Beui Message Scroller",
      "description": "Message Scroller",
      "dependencies": [
        "clsx@^2.1.1",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/message-scroller.tsx",
          "target": "@components/beui/components/agents/message-scroller.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useReducedMotion } from \"motion/react\";\nimport {\n  type ComponentPropsWithRef,\n  type Ref,\n  useCallback,\n  useEffect,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  PreviewRail,\n  type PreviewRailItem,\n} from \"@/components/beui/components/motion/preview-rail\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nconst PREVIEW_TITLE_LENGTH = 56;\nconst PREVIEW_DESCRIPTION_LENGTH = 88;\n\nfunction truncateMessageText(text: string, limit: number) {\n  if (text.length <= limit) return text;\n  const excerpt = text.slice(0, limit);\n  const boundary = excerpt.lastIndexOf(\" \");\n  return `${excerpt.slice(0, boundary > limit * 0.65 ? boundary : limit).trim()}…`;\n}\n\nfunction getMessageText(message: HTMLElement) {\n  const surface =\n    message.querySelector<HTMLElement>('[data-slot=\"message-bubble-content\"]') ??\n    message.querySelector<HTMLElement>('[data-slot=\"message-content\"]') ??\n    message;\n  return (surface.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n}\n\nfunction getMessagePreview(\n  message: HTMLElement,\n  assistantResponse?: HTMLElement,\n) {\n  const text = getMessageText(message);\n  if (!text) {\n    return { label: \"Message\", description: undefined };\n  }\n\n  if (text.length <= PREVIEW_TITLE_LENGTH) {\n    const responseText = assistantResponse\n      ? getMessageText(assistantResponse)\n      : \"\";\n    return {\n      label: text,\n      description: responseText\n        ? truncateMessageText(responseText, PREVIEW_DESCRIPTION_LENGTH)\n        : undefined,\n    };\n  }\n\n  const titleExcerpt = text.slice(0, PREVIEW_TITLE_LENGTH);\n  const titleBoundary = titleExcerpt.lastIndexOf(\" \");\n  const titleEnd =\n    titleBoundary > PREVIEW_TITLE_LENGTH * 0.65\n      ? titleBoundary\n      : PREVIEW_TITLE_LENGTH;\n  const label = `${text.slice(0, titleEnd).trim()}…`;\n  const responseText = assistantResponse\n    ? getMessageText(assistantResponse)\n    : text.slice(titleEnd).trim();\n  return {\n    label,\n    description: responseText\n      ? truncateMessageText(responseText, PREVIEW_DESCRIPTION_LENGTH)\n      : undefined,\n  };\n}\n\nexport interface MessageScrollerProps extends ComponentPropsWithRef<\"div\"> {\n  /** Keep streamed output pinned while the reader remains near the end. */\n  followOutput?: boolean;\n  /** Distance from the end that still counts as following the output. */\n  followThreshold?: number;\n  /** Smoothly follow growing content. */\n  smooth?: boolean;\n  /** Reports when the reader leaves or returns to the live edge. */\n  onFollowChange?: (following: boolean) => void;\n  /** Accessible label for the scrollable transcript. */\n  label?: string;\n  /** Marks the transcript as waiting for more streamed content. */\n  busy?: boolean;\n  /** Adds a compact rail for navigating between rendered Message rows. */\n  navigation?: \"rail\";\n  /** Accessible label for the optional message navigation rail. */\n  navigationLabel?: string;\n  viewportClassName?: string;\n  contentClassName?: string;\n  railClassName?: string;\n  viewportRef?: Ref<HTMLElement>;\n  viewportProps?: Omit<\n    ComponentPropsWithRef<\"section\">,\n    \"children\" | \"className\" | \"ref\"\n  >;\n  contentProps?: Omit<\n    ComponentPropsWithRef<\"div\">,\n    \"children\" | \"className\" | \"ref\"\n  >;\n}\n\nexport function MessageScroller({\n  followOutput = true,\n  followThreshold = 56,\n  smooth = true,\n  onFollowChange,\n  label = \"Conversation\",\n  busy,\n  navigation,\n  navigationLabel = \"Message navigation\",\n  viewportClassName,\n  contentClassName,\n  railClassName,\n  viewportRef: externalViewportRef,\n  viewportProps,\n  contentProps,\n  className,\n  children,\n  ...props\n}: MessageScrollerProps) {\n  const reduce = useReducedMotion() ?? false;\n  const viewportRef = useRef<HTMLElement>(null);\n  const contentRef = useRef<HTMLDivElement>(null);\n  const followingRef = useRef(followOutput);\n  const programmaticScrollRef = useRef(false);\n  const scrollTimerRef = useRef<number | undefined>(undefined);\n  const frameRef = useRef<number | undefined>(undefined);\n  const railFrameRef = useRef<number | undefined>(undefined);\n  const railIdRef = useRef(new WeakMap<HTMLElement, string>());\n  const railIdCounterRef = useRef(0);\n  const railTargetsRef = useRef(new Map<string, HTMLElement>());\n  const [railItems, setRailItems] = useState<PreviewRailItem[]>([]);\n  const [activeRailId, setActiveRailId] = useState(\"\");\n  const [railOverflowing, setRailOverflowing] = useState(false);\n  const {\n    onScroll: onViewportScroll,\n    onWheel: onViewportWheel,\n    onTouchStart: onViewportTouchStart,\n    onKeyDown: onViewportKeyDown,\n    ...restViewportProps\n  } = viewportProps ?? {};\n\n  const setViewportRef = useCallback(\n    (node: HTMLElement | null) => {\n      viewportRef.current = node;\n      if (typeof externalViewportRef === \"function\") {\n        externalViewportRef(node);\n      } else if (externalViewportRef) {\n        externalViewportRef.current = node;\n      }\n    },\n    [externalViewportRef],\n  );\n\n  const setFollowing = useCallback(\n    (next: boolean) => {\n      if (followingRef.current === next) return;\n      followingRef.current = next;\n      onFollowChange?.(next);\n    },\n    [onFollowChange],\n  );\n\n  const updateActiveRailItem = useCallback(() => {\n    if (navigation !== \"rail\") return;\n    const viewport = viewportRef.current;\n    const targets = [...railTargetsRef.current.entries()];\n    if (!viewport || targets.length === 0) return;\n\n    const viewportRect = viewport.getBoundingClientRect();\n    if (viewport.scrollTop <= followThreshold) {\n      const firstId = targets[0]?.[0] ?? \"\";\n      setActiveRailId((current) => (current === firstId ? current : firstId));\n      return;\n    }\n\n    const distanceFromEnd =\n      viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;\n    if (distanceFromEnd <= followThreshold) {\n      const lastId = targets.at(-1)?.[0] ?? \"\";\n      setActiveRailId((current) => (current === lastId ? current : lastId));\n      return;\n    }\n\n    const viewportCenter = viewportRect.top + viewportRect.height / 2;\n    let nearestId = targets[0]?.[0] ?? \"\";\n    let nearestDistance = Number.POSITIVE_INFINITY;\n\n    for (const [id, element] of targets) {\n      const rect = element.getBoundingClientRect();\n      const messageCenter = rect.top + rect.height / 2;\n      const distance = Math.abs(messageCenter - viewportCenter);\n      if (distance < nearestDistance) {\n        nearestDistance = distance;\n        nearestId = id;\n      }\n    }\n\n    setActiveRailId((current) =>\n      current === nearestId ? current : nearestId,\n    );\n  }, [followThreshold, navigation]);\n\n  const syncRailItems = useCallback(() => {\n    if (navigation !== \"rail\") return;\n    const content = contentRef.current;\n    const viewport = viewportRef.current;\n    if (!content || !viewport) return;\n\n    const messages = Array.from(\n      content.querySelectorAll<HTMLElement>('[data-slot=\"message\"]'),\n    );\n    const targets = new Map<string, HTMLElement>();\n    const nextItems = messages.map((message, index) => {\n      let id = railIdRef.current.get(message);\n      if (!id) {\n        railIdCounterRef.current += 1;\n        id = `message-rail-${railIdCounterRef.current}`;\n        railIdRef.current.set(message, id);\n      }\n      targets.set(id, message);\n      const sender = message.dataset.from ?? \"conversation\";\n      const assistantResponse =\n        sender === \"user\"\n          ? messages\n              .slice(index + 1)\n              .find((candidate) => candidate.dataset.from === \"assistant\")\n          : undefined;\n      const preview = getMessagePreview(message, assistantResponse);\n\n      return {\n        id,\n        label: preview.label,\n        description: preview.description,\n        ariaLabel: `Go to ${sender} message ${index + 1} of ${messages.length}`,\n      };\n    });\n\n    railTargetsRef.current = targets;\n    setRailItems((current) => {\n      const unchanged =\n        current.length === nextItems.length &&\n        current.every(\n          (item, index) =>\n            item.id === nextItems[index]?.id &&\n            item.label === nextItems[index]?.label &&\n            item.description === nextItems[index]?.description &&\n            item.ariaLabel === nextItems[index]?.ariaLabel,\n        );\n      return unchanged ? current : nextItems;\n    });\n    setRailOverflowing(\n      viewport.scrollHeight > viewport.clientHeight + 1 && messages.length > 1,\n    );\n  }, [navigation]);\n\n  const scheduleRailSync = useCallback(() => {\n    if (navigation !== \"rail\") return;\n    if (railFrameRef.current) cancelAnimationFrame(railFrameRef.current);\n    railFrameRef.current = requestAnimationFrame(() => {\n      syncRailItems();\n      updateActiveRailItem();\n    });\n  }, [navigation, syncRailItems, updateActiveRailItem]);\n\n  const scrollToEnd = useCallback((behavior: ScrollBehavior) => {\n    const viewport = viewportRef.current;\n    if (!viewport) return;\n\n    programmaticScrollRef.current = true;\n    if (typeof viewport.scrollTo === \"function\") {\n      viewport.scrollTo({ top: viewport.scrollHeight, behavior });\n    } else {\n      viewport.scrollTop = viewport.scrollHeight;\n    }\n    if (scrollTimerRef.current) window.clearTimeout(scrollTimerRef.current);\n    scrollTimerRef.current = window.setTimeout(() => {\n      programmaticScrollRef.current = false;\n    }, behavior === \"smooth\" ? 320 : 0);\n  }, []);\n\n  const handleScroll = useCallback(() => {\n    const viewport = viewportRef.current;\n    if (!viewport || programmaticScrollRef.current) return;\n\n    const distance =\n      viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;\n    setFollowing(distance <= followThreshold);\n    updateActiveRailItem();\n  }, [followThreshold, setFollowing, updateActiveRailItem]);\n\n  const leaveLiveEdge = useCallback(() => {\n    programmaticScrollRef.current = false;\n  }, []);\n\n  useLayoutEffect(() => {\n    followingRef.current = followOutput;\n    if (!followOutput) return;\n\n    frameRef.current = requestAnimationFrame(() => scrollToEnd(\"auto\"));\n    return () => {\n      if (frameRef.current) cancelAnimationFrame(frameRef.current);\n    };\n  }, [followOutput, scrollToEnd]);\n\n  useEffect(() => {\n    const content = contentRef.current;\n    if (!content || typeof ResizeObserver === \"undefined\") return;\n\n    const observer = new ResizeObserver(() => {\n      scheduleRailSync();\n      if (!followOutput || !followingRef.current) return;\n      scrollToEnd(reduce || !smooth ? \"auto\" : \"smooth\");\n    });\n    observer.observe(content);\n\n    return () => observer.disconnect();\n  }, [followOutput, reduce, scheduleRailSync, scrollToEnd, smooth]);\n\n  useEffect(() => {\n    if (navigation !== \"rail\") {\n      railTargetsRef.current.clear();\n      setRailItems([]);\n      setRailOverflowing(false);\n      return;\n    }\n\n    const content = contentRef.current;\n    const viewport = viewportRef.current;\n    if (!content || !viewport) return;\n\n    scheduleRailSync();\n    const mutationObserver =\n      typeof MutationObserver === \"undefined\"\n        ? null\n        : new MutationObserver(scheduleRailSync);\n    mutationObserver?.observe(content, {\n      childList: true,\n      characterData: true,\n      subtree: true,\n    });\n\n    const resizeObserver =\n      typeof ResizeObserver === \"undefined\"\n        ? null\n        : new ResizeObserver(scheduleRailSync);\n    resizeObserver?.observe(content);\n    resizeObserver?.observe(viewport);\n\n    return () => {\n      mutationObserver?.disconnect();\n      resizeObserver?.disconnect();\n    };\n  }, [navigation, scheduleRailSync]);\n\n  useEffect(\n    () => () => {\n      if (scrollTimerRef.current) window.clearTimeout(scrollTimerRef.current);\n      if (frameRef.current) cancelAnimationFrame(frameRef.current);\n      if (railFrameRef.current) cancelAnimationFrame(railFrameRef.current);\n    },\n    [],\n  );\n\n  const scrollToRailItem = useCallback(\n    (item: PreviewRailItem) => {\n      const viewport = viewportRef.current;\n      const target = railTargetsRef.current.get(item.id);\n      if (!viewport || !target) return;\n\n      const lastItem = railItems.at(-1)?.id === item.id;\n      setActiveRailId(item.id);\n      if (lastItem) {\n        setFollowing(true);\n        scrollToEnd(reduce || !smooth ? \"auto\" : \"smooth\");\n        return;\n      }\n\n      setFollowing(false);\n      programmaticScrollRef.current = true;\n      const viewportRect = viewport.getBoundingClientRect();\n      const targetRect = target.getBoundingClientRect();\n      const top =\n        viewport.scrollTop +\n        targetRect.top -\n        viewportRect.top -\n        (viewport.clientHeight - targetRect.height) / 2;\n      const behavior = reduce || !smooth ? \"auto\" : \"smooth\";\n\n      if (typeof viewport.scrollTo === \"function\") {\n        viewport.scrollTo({ top, behavior });\n      } else {\n        viewport.scrollTop = top;\n      }\n      if (scrollTimerRef.current) window.clearTimeout(scrollTimerRef.current);\n      scrollTimerRef.current = window.setTimeout(() => {\n        programmaticScrollRef.current = false;\n      }, behavior === \"smooth\" ? 320 : 0);\n    },\n    [railItems, reduce, scrollToEnd, setFollowing, smooth],\n  );\n\n  const viewport = (\n    <section\n      ref={setViewportRef}\n      aria-label={label}\n      {...restViewportProps}\n      onScroll={(event) => {\n        handleScroll();\n        onViewportScroll?.(event);\n      }}\n      onWheel={(event) => {\n        leaveLiveEdge();\n        onViewportWheel?.(event);\n      }}\n      onTouchStart={(event) => {\n        leaveLiveEdge();\n        onViewportTouchStart?.(event);\n      }}\n      onKeyDown={(event) => {\n        if ([\"ArrowUp\", \"PageUp\", \"Home\"].includes(event.key)) {\n          leaveLiveEdge();\n        }\n        onViewportKeyDown?.(event);\n      }}\n      className={cn(\n        \"h-full overflow-y-auto overscroll-contain outline-none [overflow-anchor:none] focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\",\n        navigation === \"rail\"\n          ? \"[-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\"\n          : \"[scrollbar-gutter:stable]\",\n        viewportClassName,\n        navigation === \"rail\" && railOverflowing && \"pr-10\",\n      )}\n    >\n      <div\n        ref={contentRef}\n        role=\"log\"\n        aria-live=\"polite\"\n        aria-relevant=\"additions text\"\n        aria-busy={busy}\n        className={contentClassName}\n        {...contentProps}\n      >\n        {children}\n      </div>\n    </section>\n  );\n\n  return (\n    <div\n      data-slot=\"message-scroller\"\n      className={cn(\"min-h-0\", className)}\n      {...props}\n    >\n      {navigation === \"rail\" ? (\n        <PreviewRail\n          items={railOverflowing ? railItems : []}\n          label={navigationLabel}\n          activeId={activeRailId}\n          onItemSelect={scrollToRailItem}\n          previewSide=\"before\"\n          highlightActive\n          itemSize={14}\n          className=\"h-full min-h-0 overflow-hidden\"\n          previewContainerClassName=\"right-8 left-3\"\n          previewClassName=\"mr-1 w-64 max-w-full [&_[data-slot=preview-rail-card]]:h-20 [&_[data-slot=preview-rail-card]]:overflow-hidden [&_[data-slot=preview-rail-card]]:p-3 [&_[data-slot=preview-rail-title]]:line-clamp-1 [&_[data-slot=preview-rail-title]]:text-xs [&_[data-slot=preview-rail-title]]:leading-4 [&_[data-slot=preview-rail-description]]:line-clamp-2 [&_[data-slot=preview-rail-description]]:text-xs [&_[data-slot=preview-rail-description]]:leading-4\"\n          railClassName={cn(\n            \"absolute inset-y-3 right-1 w-7 content-center py-1 [&_[data-slot=preview-rail-item]]:w-7 [&_[data-slot=preview-rail-item]]:justify-end [&_[data-slot=preview-rail-tick]]:h-px [&_[data-slot=preview-rail-tick]]:w-4 [&_[data-slot=preview-rail-tick]]:origin-right\",\n            railOverflowing\n              ? \"pointer-events-auto opacity-100\"\n              : \"pointer-events-none opacity-0\",\n            railClassName,\n          )}\n        >\n          {viewport}\n        </PreviewRail>\n      ) : (\n        viewport\n      )}\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/preview-rail.tsx",
          "target": "@components/beui/components/motion/preview-rail.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type MouseEvent,\n  type PointerEvent,\n  type ReactNode,\n  useCallback,\n  useId,\n  useRef,\n  useState,\n} from \"react\";\nimport { EASE_OUT, SPRING_LAYOUT } from \"@/components/beui/lib/ease\";\nimport { useDismiss } from \"@/components/beui/lib/hooks/use-dismiss\";\nimport { useHoverGesture } from \"@/components/beui/lib/hooks/use-hover-gesture\";\nimport { useTapGesture } from \"@/components/beui/lib/hooks/use-tap-gesture\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface PreviewRailItem {\n  id: string;\n  label: string;\n  ariaLabel?: string;\n  description?: ReactNode;\n  href?: string;\n  target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\";\n  rel?: string;\n}\n\nexport interface PreviewRailProps {\n  items: PreviewRailItem[];\n  label?: string;\n  orientation?: \"vertical\" | \"horizontal\";\n  activeId?: string;\n  defaultActiveId?: string;\n  onActiveChange?: (id: string) => void;\n  onItemSelect?: (item: PreviewRailItem) => void;\n  renderPreview?: (item: PreviewRailItem) => ReactNode;\n  showPreview?: boolean;\n  previewSide?: \"before\" | \"after\";\n  highlightActive?: boolean;\n  itemSize?: number;\n  children?: ReactNode;\n  className?: string;\n  railClassName?: string;\n  previewContainerClassName?: string;\n  previewClassName?: string;\n}\n\nfunction DefaultPreview({ item }: { item: PreviewRailItem }) {\n  return (\n    <div\n      data-slot=\"preview-rail-card\"\n      className=\"rounded-2xl border border-border bg-card p-4 shadow-sm\"\n    >\n      <p\n        data-slot=\"preview-rail-title\"\n        className=\"font-medium text-card-foreground\"\n      >\n        {item.label}\n      </p>\n      {item.description ? (\n        <div\n          data-slot=\"preview-rail-description\"\n          className=\"mt-1 text-sm leading-6 text-muted-foreground\"\n        >\n          {item.description}\n        </div>\n      ) : null}\n    </div>\n  );\n}\n\nexport function PreviewRail({\n  items,\n  label = \"Section navigation\",\n  orientation = \"vertical\",\n  activeId,\n  defaultActiveId,\n  onActiveChange,\n  onItemSelect,\n  renderPreview,\n  showPreview = true,\n  previewSide = \"after\",\n  highlightActive = false,\n  itemSize = 24,\n  children,\n  className,\n  railClassName,\n  previewContainerClassName,\n  previewClassName,\n}: PreviewRailProps) {\n  const uid = useId();\n  const reduce = useReducedMotion();\n  const rootRef = useRef<HTMLDivElement>(null);\n  const [internalActiveId, setInternalActiveId] = useState(\n    defaultActiveId ?? items[0]?.id ?? \"\",\n  );\n  const [hoveredId, setHoveredId] = useState<string | null>(null);\n  // A finger cannot hover, so a tap lights the tick instead. Kept apart from\n  // the hovered one: they end in different ways, and a stray mouse move must\n  // not clear a tick the keyboard or a tap chose.\n  const [pinnedId, setPinnedId] = useState<string | null>(null);\n  const [focusedId, setFocusedId] = useState<string | null>(null);\n  // A click carries no pointerType, so the pointerdown before it is what says\n  // whether the activation was a tap. Keyboard activation has none at all.\n  const tap = useTapGesture<boolean>();\n  const hover = useHoverGesture();\n\n  const clearPinned = useCallback(() => setPinnedId(null), []);\n\n  // The next tap outside the rail stands in for the pointer leaving it. The\n  // card is a preview, so that tap passes through to whatever it landed on.\n  useDismiss(pinnedId !== null, clearPinned, rootRef);\n\n  const requestedActiveId = activeId ?? internalActiveId;\n  const selectedId = items.some((item) => item.id === requestedActiveId)\n    ? requestedActiveId\n    : (items[0]?.id ?? \"\");\n  const displayedId = hoveredId ?? pinnedId ?? focusedId ?? \"\";\n  const highlightedId = displayedId || (highlightActive ? selectedId : \"\");\n  const displayedIndex = items.findIndex((item) => item.id === highlightedId);\n  const rowTemplate = items.length\n    ? `repeat(${items.length}, ${itemSize}px)`\n    : undefined;\n  const isHorizontal = orientation === \"horizontal\";\n\n  const selectItem = (id: string) => {\n    if (activeId === undefined) setInternalActiveId(id);\n    onActiveChange?.(id);\n  };\n\n  return (\n    <motion.div\n      layoutRoot\n      ref={rootRef}\n      onBlur={(event) => {\n        // Both tick sources leave with the focus: a tap does not always land\n        // focus, but when it does, tabbing away must not strand the card.\n        if (!event.currentTarget.contains(event.relatedTarget)) {\n          setFocusedId(null);\n          setPinnedId(null);\n        }\n      }}\n      className={cn(\n        \"isolate relative flex w-full overflow-visible\",\n        isHorizontal\n          ? \"min-h-64 flex-col items-center justify-center\"\n          : \"min-h-80\",\n        className,\n      )}\n    >\n      <nav\n        aria-label={label}\n        onPointerLeave={(event) => {\n          // A touch pointer leaves on lift, which would clear the tick the tap\n          // just chose — that one is cleared by the outside tap instead.\n          if (hover.leave(event)) setHoveredId(null);\n        }}\n        style={\n          isHorizontal\n            ? { gridTemplateColumns: rowTemplate }\n            : { gridTemplateRows: rowTemplate }\n        }\n        className={cn(\n          \"relative z-10 grid shrink-0\",\n          isHorizontal\n            ? \"h-12 w-fit max-w-full self-center justify-center\"\n            : \"w-12 content-center\",\n          railClassName,\n        )}\n      >\n        {items.map((item, index) => {\n          const selected = item.id === selectedId;\n          const highlighted = item.id === highlightedId;\n          const distance =\n            displayedIndex < 0 ? Number.POSITIVE_INFINITY : Math.abs(index - displayedIndex);\n          const scale = highlighted\n            ? 1\n            : distance === 1\n              ? 0.68\n              : distance === 2\n                ? 0.44\n                : 0.25;\n\n          const itemContent = (\n            <>\n              <motion.span\n                data-slot=\"preview-rail-tick\"\n                aria-hidden=\"true\"\n                animate={isHorizontal ? { scaleY: scale } : { scaleX: scale }}\n                transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n                className={cn(\n                  \"block bg-current\",\n                  isHorizontal\n                    ? \"h-12 w-0.5 origin-bottom\"\n                    : \"h-0.5 w-12 origin-left\",\n                  highlighted ? \"text-foreground\" : undefined,\n                )}\n              />\n            </>\n          );\n\n          const sharedClassName = cn(\n            \"relative flex text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n            isHorizontal\n              ? \"h-12 w-6 items-end justify-center\"\n              : \"h-6 w-12 items-center\",\n          );\n          const sharedStyle = isHorizontal\n            ? { width: itemSize }\n            : { height: itemSize };\n          const handlePointerEnter = (event: PointerEvent<HTMLElement>) => {\n            if (hover.enter(event)) setHoveredId(item.id);\n          };\n          const handlePointerDown = (event: PointerEvent<HTMLElement>) => {\n            tap.start(event, pinnedId === item.id);\n            setFocusedId(null);\n          };\n          // A gesture the platform takes away sends no click, and a key press\n          // starts an activation that never had a pointer behind it: either\n          // one leaves a record the next click would read as a tap of its own.\n          const dropGesture = () => tap.drop();\n          const handleFocus = (currentTarget: HTMLElement) => {\n            if (currentTarget.matches(\":focus-visible\")) {\n              setFocusedId(item.id);\n            }\n          };\n          const handleSelect = (event: MouseEvent<HTMLElement>) => {\n            const gesture = tap.take();\n            const tapped =\n              gesture !== null && gesture.pointerType !== \"mouse\";\n\n            if (tapped) {\n              // A link would otherwise show its preview and leave the page in\n              // the same tap, so the card is never read: the first tap lights\n              // the tick, the second follows the link.\n              if (item.href && !gesture.state) {\n                event.preventDefault();\n                setPinnedId(item.id);\n                return;\n              }\n              setPinnedId(item.id);\n            }\n\n            selectItem(item.id);\n            onItemSelect?.(item);\n          };\n\n          return item.href ? (\n            <a\n              key={item.id}\n              data-slot=\"preview-rail-item\"\n              href={item.href}\n              target={item.target}\n              rel={\n                item.rel ??\n                (item.target === \"_blank\" ? \"noreferrer noopener\" : undefined)\n              }\n              aria-label={item.ariaLabel ?? item.label}\n              aria-current={selected ? \"page\" : undefined}\n              onPointerEnter={handlePointerEnter}\n              onPointerDown={handlePointerDown}\n              onPointerCancel={dropGesture}\n              onKeyDown={dropGesture}\n              onFocus={(event) => handleFocus(event.currentTarget)}\n              onClick={handleSelect}\n              style={sharedStyle}\n              className={sharedClassName}\n            >\n              {itemContent}\n            </a>\n          ) : (\n            <button\n              key={item.id}\n              data-slot=\"preview-rail-item\"\n              type=\"button\"\n              aria-label={item.ariaLabel ?? item.label}\n              aria-current={selected ? \"location\" : undefined}\n              onPointerEnter={handlePointerEnter}\n              onPointerDown={handlePointerDown}\n              onPointerCancel={dropGesture}\n              onKeyDown={dropGesture}\n              onFocus={(event) => handleFocus(event.currentTarget)}\n              onClick={handleSelect}\n              style={sharedStyle}\n              className={sharedClassName}\n            >\n              {itemContent}\n            </button>\n          );\n        })}\n      </nav>\n\n      {showPreview ? (\n        <div\n          aria-hidden=\"true\"\n          style={\n            isHorizontal\n              ? { gridTemplateColumns: rowTemplate }\n              : { gridTemplateRows: rowTemplate }\n          }\n          className={cn(\n            \"pointer-events-none absolute z-50 grid\",\n            isHorizontal\n              ? \"top-1/2 left-1/2 h-5 w-fit max-w-full -translate-x-1/2 -translate-y-1/2 justify-center\"\n              : previewSide === \"before\"\n                ? \"inset-y-0 right-16 left-4 content-center\"\n                : \"inset-y-0 right-4 left-16 content-center\",\n            previewContainerClassName,\n          )}\n        >\n          {items.map((item) => (\n            <div\n              key={item.id}\n              style={\n                isHorizontal ? { width: itemSize } : { height: itemSize }\n              }\n              className={cn(\n                \"relative flex items-center\",\n                isHorizontal ? \"justify-center\" : undefined,\n              )}\n            >\n              {item.id === displayedId ? (\n                <div\n                  className={cn(\n                    isHorizontal\n                      ? \"absolute bottom-12 left-1/2 w-72 -translate-x-1/2\"\n                      : cn(\n                          \"w-full max-w-sm\",\n                          previewSide === \"before\" && \"ml-auto\",\n                        ),\n                    previewClassName,\n                  )}\n                >\n                  <motion.div\n                    layoutId={`preview-rail-card-${uid}`}\n                    transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n                  >\n                    <AnimatePresence mode=\"wait\" initial={false}>\n                      <motion.div\n                        key={item.id}\n                        initial={\n                          reduce\n                            ? { opacity: 0 }\n                            : { opacity: 0, y: 4, filter: \"blur(6px)\" }\n                        }\n                        animate={\n                          reduce\n                            ? { opacity: 1 }\n                            : { opacity: 1, y: 0, filter: \"blur(0px)\" }\n                        }\n                        exit={\n                          reduce\n                            ? { opacity: 0 }\n                            : {\n                                opacity: 0,\n                                y: -2,\n                                filter: \"blur(4px)\",\n                                transition: {\n                                  duration: 0.12,\n                                  ease: EASE_OUT,\n                                },\n                              }\n                        }\n                        transition={{\n                          duration: reduce ? 0 : 0.18,\n                          ease: EASE_OUT,\n                        }}\n                      >\n                        {renderPreview ? (\n                          renderPreview(item)\n                        ) : (\n                          <DefaultPreview item={item} />\n                        )}\n                      </motion.div>\n                    </AnimatePresence>\n                  </motion.div>\n                </div>\n              ) : null}\n            </div>\n          ))}\n        </div>\n      ) : null}\n\n      {children ? (\n        <div className=\"min-h-0 min-w-0 flex-1\">{children}</div>\n      ) : null}\n    </motion.div>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/hooks/use-dismiss.ts",
          "target": "@components/beui/lib/hooks/use-dismiss.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { type RefObject, useEffect } from \"react\";\n\n/**\n * What the dismissing gesture does to the control it landed on.\n *\n * `\"pass-through\"` is the platform norm (native popover light-dismiss): the\n * tap closes the overlay *and* activates whatever was under it. Use\n * `\"consume\"` where the open overlay sits over or beside controls that would\n * be costly to trigger by accident — the dismissal then swallows the\n * activation too, so the gesture only closes.\n */\nexport type DismissBehavior = \"pass-through\" | \"consume\";\n\nexport interface DismissOptions {\n  /** Default `\"pass-through\"`. */\n  behavior?: DismissBehavior;\n  /** Dismiss on Escape as well. Default true. */\n  escape?: boolean;\n  /** Return true for an outside target that should *not* dismiss. Must be stable. */\n  ignore?: (target: Element) => boolean;\n}\n\n/**\n * What every currently open dismiss scope counts as inside itself. A consumed\n * dismissal reads this to tell a stray gesture from one that belongs to an\n * overlay in front of it: overlays have no shared z-order to consult, but the\n * one the gesture landed in has said as much by registering it.\n */\nconst openScopes = new Set<(target: Element) => boolean>();\n\nfunction claimedByAnotherScope(\n  self: (target: Element) => boolean,\n  target: Element,\n) {\n  for (const scope of openScopes) {\n    if (scope !== self && scope(target)) return true;\n  }\n  return false;\n}\n\n// preventDefault on pointerdown does not suppress the click that follows, so\n// consuming a gesture means swallowing that click itself. The swallower\n// deliberately outlives the effect that installed it — the dismissal it\n// belongs to has already unmounted or re-rendered by the time the click lands.\n// It releases on that click, or on the next gesture if the pointer is dragged\n// away and no click ever arrives, so it can never eat a later one. A keydown\n// releases it too: a gesture that ends with neither a click nor a cancel would\n// otherwise leave it armed, and the click Enter synthesizes on some focused\n// control is not the one this dismissal was owed.\nfunction consumeActivation(source: Event) {\n  const swallow = (event: MouseEvent) => {\n    event.preventDefault();\n    event.stopPropagation();\n    release();\n  };\n  const restart = (event: Event) => {\n    if (event !== source) release();\n  };\n  const release = () => {\n    window.removeEventListener(\"click\", swallow, true);\n    window.removeEventListener(\"pointerdown\", restart, true);\n    window.removeEventListener(\"pointercancel\", restart, true);\n    window.removeEventListener(\"keydown\", release, true);\n  };\n  window.addEventListener(\"click\", swallow, true);\n  window.addEventListener(\"pointerdown\", restart, true);\n  window.addEventListener(\"pointercancel\", restart, true);\n  window.addEventListener(\"keydown\", release, true);\n}\n\n/**\n * Close an open overlay on Escape or a pointerdown outside `ref`. Pass `null`\n * for `ref` when what counts as inside isn't one element, and say so with\n * `ignore` instead.\n *\n * The pointerdown listener is capture-phase: a bubble-phase one is blinded by\n * any handler in between that stops propagation, and an overlay cannot know\n * what it is layered over. `onDismiss` and `ignore` must be stable (wrap in\n * useCallback) so the listeners aren't re-bound every render while open.\n */\nexport function useDismiss(\n  open: boolean,\n  onDismiss: () => void,\n  ref: RefObject<HTMLElement | null> | null,\n  {\n    behavior = \"pass-through\",\n    escape: dismissOnEscape = true,\n    ignore,\n  }: DismissOptions = {},\n) {\n  useEffect(() => {\n    if (!open) return;\n    const inside = (target: Element) =>\n      Boolean(ref?.current?.contains(target)) || Boolean(ignore?.(target));\n    const onKey = (event: KeyboardEvent) => {\n      if (dismissOnEscape && event.key === \"Escape\") onDismiss();\n    };\n    const onPointer = (event: PointerEvent) => {\n      const target = event.target as Element | null;\n      if (!target || inside(target)) return;\n      // Outside this overlay, but inside one that is also open: the gesture is\n      // that overlay's to answer, and swallowing its click from behind would\n      // cost the user the control they actually aimed at.\n      if (behavior === \"consume\" && !claimedByAnotherScope(inside, target)) {\n        consumeActivation(event);\n      }\n      onDismiss();\n    };\n    openScopes.add(inside);\n    window.addEventListener(\"keydown\", onKey);\n    window.addEventListener(\"pointerdown\", onPointer, true);\n    return () => {\n      openScopes.delete(inside);\n      window.removeEventListener(\"keydown\", onKey);\n      window.removeEventListener(\"pointerdown\", onPointer, true);\n    };\n  }, [open, onDismiss, ref, behavior, dismissOnEscape, ignore]);\n}\n"
        },
        {
          "path": "components/beui/lib/hooks/use-hover-gesture.ts",
          "target": "@components/beui/lib/hooks/use-hover-gesture.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useMemo, useRef } from \"react\";\nimport { isHoveringPointer } from \"@/components/beui/lib/touch\";\n\ninterface BoundaryEvent {\n  pointerId: number;\n  pointerType: string;\n  buttons: number;\n}\n\nexport interface HoverGesture {\n  /** True when this enter starts a hover: the pointer arrived resting, not pressing. */\n  enter: (event: BoundaryEvent) => boolean;\n  /** True when this leave ends a hover that entered as one. */\n  leave: (event: BoundaryEvent) => boolean;\n}\n\n/**\n * Pairs a surface's enter with its leave, per pointer.\n *\n * `isHoveringPointer` answers the question the *enter* asks — is this pointer\n * resting on the surface or pressing it — and both boundary cases go wrong if\n * the leave is asked the same question again:\n *\n * - A pen with no hover never rests. It arrives in contact, taps, and the spec\n *   then requires its boundary events after `pointerup`, so the leave carries\n *   `buttons: 0` and reads as a mouse gliding off. Hover teardown then undid\n *   the tap — the panel the pen had just opened closed under it.\n * - A mouse pressed on the surface and dragged off leaves with `buttons: 1`.\n *   Skipping teardown there strands the surface open: the release happens\n *   outside, and no second leave ever comes.\n *\n * So the state a hover holds is released by the pointer that took it, whatever\n * the buttons say at the boundary, and a pointer that arrived in contact never\n * took it in the first place. Contact is the exception tracked here, not\n * hover: a leave from a pointer this surface never saw enter — mounted under\n * the cursor, say — still counts, since the alternative is state with no way\n * out.\n */\nexport function useHoverGesture(): HoverGesture {\n  const contact = useRef(new Set<number>());\n\n  return useMemo(\n    () => ({\n      enter: (event) => {\n        if (isHoveringPointer(event)) {\n          contact.current.delete(event.pointerId);\n          return true;\n        }\n        contact.current.add(event.pointerId);\n        return false;\n      },\n      leave: (event) => {\n        const arrivedInContact = contact.current.delete(event.pointerId);\n        return !arrivedInContact && event.pointerType !== \"touch\";\n      },\n    }),\n    [],\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/touch.ts",
          "target": "@components/beui/lib/touch.ts",
          "type": "registry:component",
          "content": "// Shared touch primitives. iOS and iPadOS run their own gestures on top of the\n// page — the long-press selection callout and the selection it drags in with\n// it — and they win: once the platform claims a touch it cancels ours\n// mid-gesture, so a press-and-hold or a drag simply dies. Surfaces that own\n// their gesture have to opt out.\n//\n// What the two classes below cover, precisely:\n// - `-webkit-touch-callout: none` stops iOS's long-press callout. WebKit-only:\n//   it is not a property other engines have, so it is inert everywhere else.\n// - `user-select: none` stops the long-press selection on every engine,\n//   Android included, and stops a drag from painting a selection under the\n//   cursor. It is inherited, so it reaches every descendant — which is why the\n//   two classes differ only in whether they apply it unconditionally.\n// What neither covers:\n// - Chrome for Android's long-press menu on a link or an image. No CSS\n//   suppresses it; a gesture surface that wraps one needs its own\n//   `onContextMenu` with `preventDefault()`.\n// - The native drag of an `<img>` or `<a>` descendant. `-webkit-user-drag` is\n//   not inherited and plain divs and buttons are not drag sources, so setting\n//   it on the surface does nothing — the child itself needs `draggable={false}`.\n\n/**\n * Classes for a surface that *is* the control: a thumb, a drum, a stage, a\n * handle, a hold button. Selection is suppressed on every input, because a\n * drag that highlights the control's own label is wrong on a mouse too.\n * Compose with `touch-none` when the surface also owns the scroll axis — leave\n * it off when the page must still scroll from there.\n */\nexport const TOUCH_GESTURE_CLASS = \"select-none [-webkit-touch-callout:none]\";\n\n/**\n * The same opt-out for a gesture surface that wraps content the consumer owns:\n * a scroller, a context-menu trigger, a sheet header, a list row. Selection is\n * suppressed only where the platform runs its own press gestures — a coarse\n * pointer — so a mouse user can still select and copy that content. If the\n * gesture itself would paint a selection under the cursor, add `select-none`\n * for the duration of the gesture rather than reaching for\n * `TOUCH_GESTURE_CLASS`.\n *\n * `pointer: coarse` describes the *primary* pointer and nothing else, so a\n * hybrid machine reads it wrong in both directions: a tablet with a mouse\n * plugged in keeps touch as primary and loses mouse selection, and a laptop\n * with a touchscreen keeps the mouse as primary and leaves selection live\n * under a finger. No media query can answer per interaction — the query is\n * about the device, and the question is about the gesture in progress. The\n * default stays here because it is right on the machines that are one thing or\n * the other, and losing a selection is a nuisance; where the miss costs a\n * *gesture* instead, the surface pairs it with `holdSelection` on the press.\n */\nexport const TOUCH_GESTURE_CONTENT_CLASS =\n  \"[-webkit-touch-callout:none] pointer-coarse:select-none\";\n\n/**\n * Suppress selection on `element` for as long as a gesture is running on it,\n * whatever the primary pointer of the machine happens to be. Returns the\n * release. Inline, so it wins over the class above and is gone again the\n * moment the gesture ends.\n *\n * For the press gestures a native selection would otherwise steal — a\n * long-press that opens a menu. Elsewhere prefer the classes: a surface that\n * takes selection away for the whole session is a surface whose text nobody\n * can copy.\n */\nexport function holdSelection(element: HTMLElement) {\n  element.style.setProperty(\"user-select\", \"none\");\n  element.style.setProperty(\"-webkit-user-select\", \"none\");\n  return () => {\n    element.style.removeProperty(\"user-select\");\n    element.style.removeProperty(\"-webkit-user-select\");\n  };\n}\n\n/**\n * Pointer capture, best effort. WebKit throws `NotFoundError` when the pointer\n * is already gone by the time the handler runs — routine on iOS, where the\n * system can claim the touch first — and an uncaught throw takes the rest of\n * the handler, the gesture included, down with it. Touch pointers carry\n * implicit capture anyway, so losing it is never fatal.\n */\nexport function capturePointer(element: Element, pointerId: number) {\n  try {\n    element.setPointerCapture(pointerId);\n  } catch {\n    // Pointer is no longer active — implicit capture still applies on touch.\n  }\n}\n\n/** Release a capture taken with `capturePointer`, ignoring a stale pointer. */\nexport function releasePointer(element: Element, pointerId: number) {\n  try {\n    if (element.hasPointerCapture(pointerId)) {\n      element.releasePointerCapture(pointerId);\n    }\n  } catch {\n    // Capture was already dropped by the browser.\n  }\n}\n\n/**\n * Whether this event came from a pointer that is *hovering*: not a touch, and\n * not currently pressed. Which input the user is holding right now is not\n * something a device capability can answer — a touchscreen laptop hovers and\n * taps, and iPadOS reports a fine hovering pointer for a finger — so both\n * paths stay live and each handler branches on the event it was given.\n *\n * A pen resting on the glass is making contact, not hovering: `buttons` is the\n * tell, and it sends a pen tap down the same route a finger takes.\n *\n * This answers what an *enter* asks. A leave is the other half of a pair and\n * has to be read against the enter that started it — `useHoverGesture` in\n * `lib/hooks/use-hover-gesture` does that, and hover surfaces should use it\n * rather than asking this question twice.\n */\nexport const isHoveringPointer = (event: {\n  pointerType: string;\n  buttons: number;\n}) => event.pointerType !== \"touch\" && event.buttons === 0;\n"
        },
        {
          "path": "components/beui/lib/hooks/use-tap-gesture.ts",
          "target": "@components/beui/lib/hooks/use-tap-gesture.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useMemo, useRef } from \"react\";\n\n/** What a pointerdown recorded, read back by the click that ends its gesture. */\nexport interface TapRecord<S> {\n  /** Which input started the gesture. */\n  pointerType: string;\n  /** What the surface was showing when it started. */\n  state: S;\n}\n\nexport interface TapGesture<S> {\n  /** Record the gesture a pointerdown starts, with the state it starts in. */\n  start: (event: { pointerType: string }, state: S) => void;\n  /** Read the record and clear it. `null` when no pointer is behind this click. */\n  take: () => TapRecord<S> | null;\n  /** Drop the record: this gesture will never spend it on a click. */\n  drop: () => void;\n}\n\n/**\n * The pointer gesture behind a click, recorded where the click cannot report\n * it. A `click` carries no `pointerType` in the engines that matter, so the\n * `pointerdown` before it is the only thing that says which input activated\n * the control — and whether one did at all, since keyboard activation\n * synthesizes a click with no pointer behind it.\n *\n * State goes in with the record because a click reports that no better: a\n * browser that focuses a control on contact can open the very panel the tap\n * was meant to open, and reading \"is it open\" at click time then undoes it.\n * What the gesture started against is what it acts on.\n *\n * The record is spent by one click and dropped by everything else, because a\n * record that outlives its gesture is worse than none:\n *\n * - A scroll or an OS gesture takes the touch away — `pointercancel`, no click\n *   ever — and the finger would sit in the record until some later click.\n * - That later click is often `Enter` on a keyboard, which arrives with no\n *   pointerdown of its own and would inherit the abandoned finger. A keydown\n *   is the start of a keyboard activation and never part of a tap, so it drops\n *   the record too.\n *\n * Both ends have to be wired by the surface: `drop` on `onPointerCancel` and\n * on `onKeyDown`.\n */\nexport function useTapGesture<S>(): TapGesture<S> {\n  const record = useRef<TapRecord<S> | null>(null);\n\n  return useMemo(\n    () => ({\n      start: (event, state) => {\n        record.current = { pointerType: event.pointerType, state };\n      },\n      take: () => {\n        const spent = record.current;\n        record.current = null;\n        return spent;\n      },\n      drop: () => {\n        record.current = null;\n      },\n    }),\n    [],\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-prompt-input",
      "type": "registry:block",
      "title": "Beui Prompt Input",
      "description": "Prompt Input",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/prompt-input.tsx",
          "target": "@components/beui/components/agents/prompt-input.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { ArrowUp, Plus, Square } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type FormEvent,\n  type KeyboardEvent,\n  type ReactNode,\n  type TextareaHTMLAttributes,\n  useCallback,\n  useEffect,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport { Button } from \"@/components/beui/components/motion/button\";\nimport {\n  MorphPopover,\n  MorphPopoverContent,\n  MorphPopoverTrigger,\n} from \"@/components/beui/components/motion/popover-morph\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n} from \"@/components/beui/components/motion/select\";\nimport { SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface PromptModel {\n  value: string;\n  label: ReactNode;\n  icon?: ReactNode;\n  disabled?: boolean;\n}\n\nexport interface PromptAction {\n  value: string;\n  label: ReactNode;\n  description?: ReactNode;\n  icon?: ReactNode;\n  disabled?: boolean;\n}\n\nexport interface PromptInputProps extends Omit<\n  TextareaHTMLAttributes<HTMLTextAreaElement>,\n  \"value\" | \"defaultValue\" | \"onChange\" | \"onSubmit\" | \"children\"\n> {\n  value?: string;\n  defaultValue?: string;\n  onValueChange?: (value: string) => void;\n  models?: PromptModel[];\n  model?: string;\n  defaultModel?: string;\n  onModelChange?: (model: string) => void;\n  actions?: PromptAction[];\n  onAction?: (action: string) => void;\n  onSubmit?: (value: string, model?: string) => void | Promise<void>;\n  loading?: boolean;\n  onStop?: () => void;\n  minRows?: number;\n  maxRows?: number;\n  leadingAction?: ReactNode;\n  className?: string;\n}\n\nexport function PromptInput({\n  value,\n  defaultValue = \"\",\n  onValueChange,\n  models = [],\n  model,\n  defaultModel,\n  onModelChange,\n  actions = [],\n  onAction,\n  onSubmit,\n  loading = false,\n  onStop,\n  minRows = 2,\n  maxRows = 8,\n  leadingAction,\n  className,\n  disabled,\n  placeholder = \"Ask the agent to do something…\",\n  \"aria-label\": ariaLabel = \"Prompt\",\n  onKeyDown,\n  ...textareaProps\n}: PromptInputProps) {\n  const reduce = useReducedMotion() ?? false;\n  const textareaRef = useRef<HTMLTextAreaElement>(null);\n  const measurementRef = useRef<HTMLDivElement>(null);\n  const [internalValue, setInternalValue] = useState(defaultValue);\n  const [internalModel, setInternalModel] = useState(\n    defaultModel ?? models[0]?.value,\n  );\n  const [actionsOpen, setActionsOpen] = useState(false);\n  const currentValue = value ?? internalValue;\n  const currentModelValue = model ?? internalModel;\n  const currentModel = models.find(\n    (option) => option.value === currentModelValue,\n  );\n  const canSubmit = Boolean(currentValue.trim()) && !disabled && !loading;\n\n  const resizeTextarea = useCallback(() => {\n    const textarea = textareaRef.current;\n    const measurement = measurementRef.current;\n    if (!textarea || !measurement || textarea.value !== currentValue) return;\n\n    const lineHeight = 24;\n    const nextHeight = Math.min(\n      Math.max(measurement.scrollHeight, minRows * lineHeight),\n      maxRows * lineHeight,\n    );\n    const height = `${nextHeight}px`;\n    if (textarea.style.height !== height) textarea.style.height = height;\n  }, [currentValue, maxRows, minRows]);\n\n  useLayoutEffect(() => {\n    resizeTextarea();\n  }, [resizeTextarea]);\n\n  useEffect(() => {\n    const textarea = textareaRef.current;\n    if (!textarea || typeof ResizeObserver === \"undefined\") return;\n    const observer = new ResizeObserver(resizeTextarea);\n    observer.observe(textarea);\n    return () => observer.disconnect();\n  }, [resizeTextarea]);\n\n  const setValue = (next: string) => {\n    if (value === undefined) setInternalValue(next);\n    onValueChange?.(next);\n  };\n\n  const setModel = (next: string) => {\n    if (model === undefined) setInternalModel(next);\n    onModelChange?.(next);\n  };\n\n  const submit = (event?: FormEvent) => {\n    event?.preventDefault();\n    const prompt = currentValue.trim();\n    if (!prompt || disabled || loading) return;\n\n    onSubmit?.(prompt, currentModelValue);\n    if (value === undefined) setInternalValue(\"\");\n    textareaRef.current?.focus({ preventScroll: true });\n  };\n\n  const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n    onKeyDown?.(event);\n    if (\n      event.defaultPrevented ||\n      event.key !== \"Enter\" ||\n      event.shiftKey ||\n      event.nativeEvent.isComposing\n    ) {\n      return;\n    }\n    event.preventDefault();\n    submit();\n  };\n\n  return (\n    <form\n      onSubmit={submit}\n      className={cn(\n        \"relative w-full rounded-lg border border-border/80 bg-background p-2 transition-colors focus-within:border-foreground/25\",\n        disabled && \"opacity-60\",\n        className,\n      )}\n    >\n      <div\n        ref={measurementRef}\n        aria-hidden=\"true\"\n        className=\"pointer-events-none invisible absolute inset-x-2 top-0 whitespace-pre-wrap px-2 text-sm leading-6 [overflow-wrap:break-word]\"\n      >\n        {`${currentValue}\\u200b`}\n      </div>\n      <textarea\n        ref={textareaRef}\n        value={currentValue}\n        disabled={disabled}\n        placeholder={placeholder}\n        aria-label={ariaLabel}\n        rows={minRows}\n        {...textareaProps}\n        onChange={(event) => setValue(event.target.value)}\n        onKeyDown={handleKeyDown}\n        className=\"scrollbar-hide block w-full resize-none overflow-y-auto bg-transparent px-2 pt-1.5 text-sm leading-6 text-foreground outline-none placeholder:text-muted-foreground/55\"\n      />\n\n      <div className=\"mt-1 flex min-h-8 items-center gap-1\">\n        {actions.length ? (\n          <MorphPopover open={actionsOpen} onOpenChange={setActionsOpen}>\n            <MorphPopoverTrigger>\n              <Button\n                type=\"button\"\n                variant=\"ghost\"\n                size=\"icon\"\n                disabled={disabled || loading}\n                aria-label=\"Add to prompt\"\n                className=\"size-8\"\n              >\n                <motion.span\n                  aria-hidden=\"true\"\n                  animate={{ rotate: actionsOpen ? 45 : 0 }}\n                  transition={reduce ? { duration: 0 } : SPRING_SWAP}\n                >\n                  <Plus className=\"size-4\" />\n                </motion.span>\n              </Button>\n            </MorphPopoverTrigger>\n\n            <MorphPopoverContent\n              side=\"top\"\n              align=\"start\"\n              sideOffset={8}\n              radius={10}\n              className=\"w-56 p-1.5\"\n            >\n              {actions.map((action) => (\n                <button\n                  key={action.value}\n                  type=\"button\"\n                  disabled={action.disabled}\n                  onClick={() => {\n                    onAction?.(action.value);\n                    setActionsOpen(false);\n                  }}\n                  className=\"flex w-full items-start gap-2.5 rounded-md px-2.5 py-2 text-left outline-none transition-colors hover:bg-muted focus-visible:bg-muted disabled:pointer-events-none disabled:opacity-50\"\n                >\n                  {action.icon ? (\n                    <span className=\"mt-0.5 grid size-5 shrink-0 place-items-center text-muted-foreground [&_svg]:size-4\">\n                      {action.icon}\n                    </span>\n                  ) : null}\n                  <span className=\"min-w-0\">\n                    <span className=\"block text-sm text-foreground\">\n                      {action.label}\n                    </span>\n                    {action.description ? (\n                      <span className=\"mt-0.5 block text-xs leading-4 text-muted-foreground\">\n                        {action.description}\n                      </span>\n                    ) : null}\n                  </span>\n                </button>\n              ))}\n            </MorphPopoverContent>\n          </MorphPopover>\n        ) : null}\n        {leadingAction}\n        {models.length ? (\n          <Select\n            value={currentModelValue}\n            onValueChange={setModel}\n            disabled={disabled || loading}\n            className=\"min-w-0\"\n          >\n            <SelectTrigger className=\"h-8 w-auto max-w-52 rounded-md border-0 bg-transparent px-2 py-0 text-xs hover:bg-muted focus-visible:ring-2\">\n              <span className=\"flex min-w-0 items-center gap-1.5\">\n                {currentModel?.icon ? (\n                  <span className=\"grid size-4 shrink-0 place-items-center text-muted-foreground [&_svg]:size-3.5\">\n                    {currentModel.icon}\n                  </span>\n                ) : null}\n                <span className=\"truncate text-muted-foreground\">\n                  {currentModel?.label ?? \"Choose model\"}\n                </span>\n              </span>\n            </SelectTrigger>\n            <SelectContent className=\"right-auto w-52 shadow-none\">\n              {models.map((option) => (\n                <SelectItem\n                  key={option.value}\n                  value={option.value}\n                  disabled={option.disabled}\n                  className=\"py-2\"\n                >\n                  <span className=\"flex min-w-0 items-center gap-2\">\n                    {option.icon ? (\n                      <span className=\"grid size-5 shrink-0 place-items-center text-muted-foreground [&_svg]:size-4\">\n                        {option.icon}\n                      </span>\n                    ) : null}\n                    <span className=\"min-w-0 truncate text-sm text-foreground\">\n                      {option.label}\n                    </span>\n                  </span>\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n        ) : null}\n\n        <Button\n          type={loading ? \"button\" : \"submit\"}\n          size=\"icon\"\n          disabled={loading ? !onStop : !canSubmit}\n          aria-label={loading ? \"Stop generating\" : \"Send prompt\"}\n          onClick={loading ? onStop : undefined}\n          className=\"ml-auto size-8\"\n        >\n          <AnimatePresence initial={false} mode=\"popLayout\">\n            <motion.span\n              key={loading ? \"stop\" : \"send\"}\n              initial={reduce ? { opacity: 1 } : { opacity: 0, y: 3, scale: 0.8 }}\n              animate={{ opacity: 1, y: 0, scale: 1 }}\n              exit={reduce ? { opacity: 0 } : { opacity: 0, y: -3, scale: 0.8 }}\n              transition={reduce ? { duration: 0 } : SPRING_SWAP}\n              className=\"grid place-items-center\"\n            >\n              {loading ? (\n                <Square className=\"size-3 fill-current\" />\n              ) : (\n                <ArrowUp className=\"size-4\" />\n              )}\n            </motion.span>\n          </AnimatePresence>\n        </Button>\n      </div>\n    </form>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/button/index.tsx",
          "target": "@components/beui/components/motion/button/index.tsx",
          "type": "registry:component",
          "content": "export type {\n  ButtonLinkProps,\n  ButtonProps,\n  ButtonSize,\n  ButtonVariant,\n} from \"./base\";\nexport { Button, ButtonLink } from \"./base\";\nexport type { MagneticButtonProps } from \"./magnetic\";\nexport { MagneticButton } from \"./magnetic\";\nexport type { MetallicButtonProps } from \"./metallic\";\nexport { MetallicButton } from \"./metallic\";\nexport type { ButtonState, StatefulButtonProps } from \"./stateful\";\nexport { StatefulButton } from \"./stateful\";\n"
        },
        {
          "path": "components/beui/components/motion/button/base.tsx",
          "target": "@components/beui/components/motion/button/base.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  AnimatePresence,\n  type HTMLMotionProps,\n  motion,\n  useReducedMotion,\n} from \"motion/react\";\nimport {\n  forwardRef,\n  type PointerEvent,\n  type ReactNode,\n  useCallback,\n  useRef,\n  useState,\n} from \"react\";\nimport { EASE_OUT, SPRING_PRESS } from \"@/components/beui/lib/ease\";\nimport { useHoverCapable } from \"@/components/beui/lib/hooks/use-hover-capable\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"outline\";\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\";\n\nexport interface ButtonProps extends Omit<\n  HTMLMotionProps<\"button\">,\n  \"children\"\n> {\n  variant?: ButtonVariant;\n  size?: ButtonSize;\n  pressScale?: number;\n  /** Spawn a Material-style ripple from the press point. Off by default. */\n  ripple?: boolean;\n  children?: ReactNode;\n}\n\nexport interface ButtonLinkProps extends Omit<\n  HTMLMotionProps<\"a\">,\n  \"children\"\n> {\n  variant?: ButtonVariant;\n  size?: ButtonSize;\n  pressScale?: number;\n  children?: ReactNode;\n}\n\ntype Ripple = { id: number; x: number; y: number; size: number };\n\nconst VARIANT_CLASS: Record<ButtonVariant, string> = {\n  primary: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n  secondary: \"border border-border bg-card text-foreground hover:border-border\",\n  ghost: \"text-muted-foreground hover:text-foreground hover:bg-primary/5\",\n  outline:\n    \"border border-border bg-transparent text-foreground hover:bg-primary/5\",\n};\n\nconst SIZE_CLASS: Record<ButtonSize, string> = {\n  sm: \"h-8 px-3 text-xs gap-1.5 rounded-md\",\n  md: \"h-10 px-5 text-sm gap-2 rounded-md\",\n  lg: \"h-12 px-6 text-base gap-2 rounded-md\",\n  icon: \"h-8 w-8 rounded-md\",\n};\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n  function Button(\n    {\n      variant = \"primary\",\n      size = \"md\",\n      pressScale = 0.93,\n      ripple = false,\n      className,\n      children,\n      onPointerDown,\n      ...rest\n    },\n    ref,\n  ) {\n    const reduce = useReducedMotion();\n    const canHover = useHoverCapable();\n    const [ripples, setRipples] = useState<Ripple[]>([]);\n    const nextId = useRef(0);\n\n    const handlePointerDown = useCallback(\n      (event: PointerEvent<HTMLButtonElement>) => {\n        if (ripple && !reduce) {\n          const rect = event.currentTarget.getBoundingClientRect();\n          const size = Math.max(rect.width, rect.height) * 2;\n          const id = nextId.current++;\n          setRipples((prev) => [\n            ...prev,\n            {\n              id,\n              x: event.clientX - rect.left,\n              y: event.clientY - rect.top,\n              size,\n            },\n          ]);\n        }\n        onPointerDown?.(event);\n      },\n      [ripple, reduce, onPointerDown],\n    );\n\n    return (\n      <motion.button\n        ref={ref}\n        type=\"button\"\n        whileTap={reduce ? undefined : { scale: pressScale }}\n        whileHover={reduce || !canHover ? undefined : { scale: 1.02 }}\n        transition={SPRING_PRESS}\n        onPointerDown={handlePointerDown}\n        className={cn(\n          \"inline-flex items-center justify-center font-medium select-none\",\n          \"transition-colors\",\n          \"disabled:pointer-events-none disabled:opacity-50\",\n          ripple && \"relative overflow-hidden\",\n          VARIANT_CLASS[variant],\n          SIZE_CLASS[size],\n          className,\n        )}\n        {...rest}\n      >\n        {ripple && !reduce ? (\n          <span className=\"pointer-events-none absolute inset-0 overflow-hidden rounded-[inherit]\">\n            <AnimatePresence>\n              {ripples.map((r) => (\n                <motion.span\n                  key={r.id}\n                  className=\"absolute rounded-full bg-current\"\n                  style={{\n                    left: r.x,\n                    top: r.y,\n                    width: r.size,\n                    height: r.size,\n                    x: \"-50%\",\n                    y: \"-50%\",\n                  }}\n                  initial={{ scale: 0.05, opacity: 0.3 }}\n                  animate={{ scale: 1, opacity: 0 }}\n                  exit={{ opacity: 0 }}\n                  transition={{ duration: 1.6, ease: EASE_OUT }}\n                  onAnimationComplete={() =>\n                    setRipples((prev) => prev.filter((x) => x.id !== r.id))\n                  }\n                />\n              ))}\n            </AnimatePresence>\n          </span>\n        ) : null}\n        {children}\n      </motion.button>\n    );\n  },\n);\n\nexport const ButtonLink = forwardRef<HTMLAnchorElement, ButtonLinkProps>(\n  function ButtonLink(\n    {\n      variant = \"primary\",\n      size = \"md\",\n      pressScale = 0.93,\n      className,\n      children,\n      ...rest\n    },\n    ref,\n  ) {\n    const reduce = useReducedMotion();\n    const canHover = useHoverCapable();\n\n    return (\n      <motion.a\n        ref={ref}\n        whileTap={reduce ? undefined : { scale: pressScale }}\n        whileHover={reduce || !canHover ? undefined : { scale: 1.02 }}\n        transition={SPRING_PRESS}\n        className={cn(\n          \"inline-flex items-center justify-center font-medium select-none\",\n          \"transition-colors\",\n          VARIANT_CLASS[variant],\n          SIZE_CLASS[size],\n          className,\n        )}\n        {...rest}\n      >\n        {children}\n      </motion.a>\n    );\n  },\n);\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/hooks/use-hover-capable.ts",
          "target": "@components/beui/lib/hooks/use-hover-capable.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/**\n * Returns true only on devices that have a true hover (mouse / trackpad).\n * Touch devices fire phantom `:hover` on tap that sticks until tap-elsewhere\n * — gate hover-only effects (scale lifts, magnetic pulls) behind this.\n */\nexport function useHoverCapable() {\n  const [canHover, setCanHover] = useState(false);\n\n  useEffect(() => {\n    if (typeof window === \"undefined\" || !window.matchMedia) return;\n    const mq = window.matchMedia(\"(hover: hover) and (pointer: fine)\");\n    const update = () => setCanHover(mq.matches);\n    update();\n    mq.addEventListener?.(\"change\", update);\n    return () => mq.removeEventListener?.(\"change\", update);\n  }, []);\n\n  return canHover;\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/motion/button/magnetic.tsx",
          "target": "@components/beui/components/motion/button/magnetic.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { forwardRef } from \"react\";\nimport { Magnetic } from \"../magnetic\";\nimport { Button, type ButtonProps } from \"./base\";\n\nexport interface MagneticButtonProps extends ButtonProps {\n  /** Magnetic pull strength. Default 0.25. */\n  strength?: number;\n  /** Class applied to the magnetic wrapper. */\n  magneticClassName?: string;\n}\n\nexport const MagneticButton = forwardRef<HTMLButtonElement, MagneticButtonProps>(function MagneticButton(\n  { strength = 0.25, magneticClassName, children, ...rest },\n  ref,\n) {\n  return (\n    <Magnetic strength={strength} className={magneticClassName}>\n      <Button ref={ref} {...rest}>\n        {children}\n      </Button>\n    </Magnetic>\n  );\n});\n"
        },
        {
          "path": "components/beui/components/motion/magnetic.tsx",
          "target": "@components/beui/components/motion/magnetic.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, useMotionValue, useReducedMotion, useSpring } from \"motion/react\";\nimport { useRef, type ReactNode } from \"react\";\nimport { SPRING_MOUSE } from \"@/components/beui/lib/ease\";\nimport { useHoverCapable } from \"@/components/beui/lib/hooks/use-hover-capable\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface MagneticProps {\n  children: ReactNode;\n  strength?: number;\n  className?: string;\n}\n\nexport function Magnetic({ children, strength = 0.35, className }: MagneticProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const reduce = useReducedMotion();\n  const canHover = useHoverCapable();\n  // Decorative cursor-follow: skip on touch (phantom hover) and reduced motion.\n  const enabled = !reduce && canHover;\n  const x = useMotionValue(0);\n  const y = useMotionValue(0);\n  const sx = useSpring(x, SPRING_MOUSE);\n  const sy = useSpring(y, SPRING_MOUSE);\n\n  const onMove = (e: React.MouseEvent<HTMLDivElement>) => {\n    const el = ref.current;\n    if (!el || !enabled) return;\n    const rect = el.getBoundingClientRect();\n    x.set((e.clientX - rect.left - rect.width / 2) * strength);\n    y.set((e.clientY - rect.top - rect.height / 2) * strength);\n  };\n\n  const onLeave = () => {\n    x.set(0);\n    y.set(0);\n  };\n\n  return (\n    <motion.div\n      ref={ref}\n      onMouseMove={onMove}\n      onMouseLeave={onLeave}\n      style={{ x: sx, y: sy }}\n      className={cn(\"inline-block\", className)}\n    >\n      {children}\n    </motion.div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/button/metallic.tsx",
          "target": "@components/beui/components/motion/button/metallic.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { forwardRef, useState } from \"react\";\nimport { EASE_IN_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport { Button, type ButtonProps } from \"./base\";\n\nexport interface MetallicButtonProps extends Omit<\n  ButtonProps,\n  \"ripple\" | \"variant\"\n> {\n  /** Stops the traveling reflection while preserving the chrome rim. */\n  paused?: boolean;\n}\n\n// The rim and highlight drift separately so the material stays quiet and reflective.\nconst SILVER_DRIFT = {\n  duration: 8,\n  ease: EASE_IN_OUT,\n  repeat: Infinity,\n};\n\nconst CHROME_SHIMMER = {\n  duration: 2.4,\n  ease: EASE_IN_OUT,\n};\n\nexport const MetallicButton = forwardRef<\n  HTMLButtonElement,\n  MetallicButtonProps\n>(function MetallicButton(\n  {\n    size = \"md\",\n    paused = false,\n    className,\n    children,\n    onHoverStart,\n    onHoverEnd,\n    ...rest\n  },\n  ref,\n) {\n  const reduce = useReducedMotion();\n  const still = paused || Boolean(reduce);\n  const [hovered, setHovered] = useState(false);\n\n  return (\n    <Button\n      ref={ref}\n      variant=\"ghost\"\n      size={size}\n      onHoverStart={(event, info) => {\n        setHovered(true);\n        onHoverStart?.(event, info);\n      }}\n      onHoverEnd={(event, info) => {\n        setHovered(false);\n        onHoverEnd?.(event, info);\n      }}\n      className={cn(\n        \"group relative isolate overflow-hidden border-0 bg-transparent text-foreground\",\n        \"hover:bg-transparent hover:text-foreground\",\n        \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n        \"shadow-[0_8px_22px_rgba(0,0,0,0.16)]\",\n        size === \"icon\" && \"rounded-full\",\n        className,\n      )}\n      {...rest}\n    >\n      <motion.span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-y-0 left-[-18%] z-0 w-[136%] rounded-[inherit] bg-[linear-gradient(105deg,#111_0%,#737373_14%,#fafafa_26%,#525252_38%,#0a0a0a_50%,#a3a3a3_64%,#fff_75%,#404040_87%,#111_100%)]\"\n        animate={still ? undefined : { x: [\"0%\", \"13%\", \"0%\"] }}\n        transition={still ? undefined : SILVER_DRIFT}\n      />\n\n      <motion.span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-y-0 left-[-58%] z-[1] w-[52%] -skew-x-12 bg-[linear-gradient(90deg,transparent,rgba(255,255,255,0.5)_48%,transparent)] opacity-50 blur-[3px] mix-blend-screen\"\n        animate={still ? undefined : { x: hovered ? \"310%\" : \"0%\" }}\n        transition={still ? undefined : CHROME_SHIMMER}\n      />\n\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-[2px] z-[2] rounded-[inherit] bg-background transition-colors group-hover:bg-muted/40\"\n      />\n\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-[2px] z-[3] rounded-[inherit] shadow-[inset_0_1px_0_rgba(255,255,255,0.28),inset_0_-1px_0_rgba(0,0,0,0.16)]\"\n      />\n\n      <span className=\"relative z-10 inline-flex items-center justify-center gap-2\">\n        {children}\n      </span>\n    </Button>\n  );\n});\n"
        },
        {
          "path": "components/beui/components/motion/button/stateful.tsx",
          "target": "@components/beui/components/motion/button/stateful.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Check, Loader2, X } from \"lucide-react\";\nimport {\n  AnimatePresence,\n  motion,\n  useReducedMotion,\n  type Variants,\n} from \"motion/react\";\nimport {\n  forwardRef,\n  type ReactNode,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport { EASE_OUT, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { Button, type ButtonProps } from \"./base\";\n\nexport type ButtonState = \"idle\" | \"loading\" | \"success\" | \"error\";\n\nexport interface StatefulButtonProps extends Omit<ButtonProps, \"children\"> {\n  state?: ButtonState;\n  children: ReactNode;\n  loadingText?: ReactNode;\n  successText?: ReactNode;\n  errorText?: ReactNode;\n  icon?: ReactNode;\n}\n\nconst CASCADE_STAGGER = 0.025;\nconst ROLL_BLUR = \"blur(6px)\";\n\nconst CASCADE_LETTER_VARIANTS: Variants = {\n  initial: { opacity: 0, y: \"105%\", filter: ROLL_BLUR },\n  animate: (delay: number = 0) => ({\n    opacity: 1,\n    y: \"0%\",\n    filter: \"blur(0px)\",\n    transition: { ...SPRING_SWAP, delay },\n  }),\n  exit: (delay: number = 0) => ({\n    opacity: 0,\n    y: \"-105%\",\n    filter: ROLL_BLUR,\n    transition: { duration: 0.16, ease: EASE_OUT, delay: delay * 0.5 },\n  }),\n};\n\nconst ICON_VARIANTS: Variants = {\n  // Width collapses too, so the icon adds/removes its own space smoothly\n  // instead of popping the row width in a single frame.\n  initial: { opacity: 0, width: 0, scale: 0.7, filter: ROLL_BLUR },\n  animate: {\n    opacity: 1,\n    width: \"1.5rem\",\n    scale: 1,\n    filter: \"blur(0px)\",\n    transition: SPRING_SWAP,\n  },\n  exit: {\n    opacity: 0,\n    width: 0,\n    scale: 0.7,\n    filter: ROLL_BLUR,\n    transition: { duration: 0.16, ease: EASE_OUT },\n  },\n};\n\nfunction IconSlot({ keyId, children }: { keyId: string; children: ReactNode }) {\n  const reduce = useReducedMotion();\n  return (\n    <motion.span\n      key={keyId}\n      variants={ICON_VARIANTS}\n      initial={reduce ? { opacity: 0 } : \"initial\"}\n      animate={reduce ? { opacity: 1 } : \"animate\"}\n      exit={reduce ? { opacity: 0 } : \"exit\"}\n      transition={reduce ? { duration: 0.15 } : undefined}\n      className=\"inline-grid shrink-0 place-items-center overflow-hidden\"\n    >\n      {children}\n    </motion.span>\n  );\n}\n\nfunction TextSlot({\n  value,\n  children,\n}: {\n  value: string;\n  children: ReactNode;\n}) {\n  const reduce = useReducedMotion();\n  const measureRef = useRef<HTMLSpanElement>(null);\n  const [width, setWidth] = useState<number>();\n  const label = typeof children === \"string\" ? children : null;\n  const cascade = label !== null && !reduce;\n\n  // Measure strings with the same per-letter layout as the cascade. Measuring\n  // the whole string preserves kerning, which can make it narrower than the\n  // inline-block letters and clip the final glyph during the width animation.\n  // The label can change on any render, so the measurement intentionally runs after each commit.\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  useLayoutEffect(() => {\n    const nextWidth = measureRef.current?.offsetWidth;\n    if (!nextWidth) return;\n    setWidth((current) => (current === nextWidth ? current : nextWidth));\n  });\n\n  return (\n    <motion.span\n      initial={false}\n      animate={{ width }}\n      transition={reduce ? { duration: 0 } : SPRING_SWAP}\n      className=\"relative inline-block overflow-hidden whitespace-nowrap align-bottom\"\n    >\n      <span\n        ref={measureRef}\n        aria-hidden\n        className=\"invisible inline-block whitespace-nowrap\"\n      >\n        {cascade\n          ? label.split(\"\").map((char, index) => (\n              <span\n                // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity.\n                key={index}\n                className=\"inline-block whitespace-pre\"\n              >\n                {char}\n              </span>\n            ))\n          : children}\n      </span>\n\n      {cascade ? (\n        <>\n          <span className=\"sr-only\">{label}</span>\n          <AnimatePresence initial={false}>\n            <motion.span\n              key={`cascade-${value}`}\n              aria-hidden\n              initial=\"initial\"\n              animate=\"animate\"\n              exit=\"exit\"\n              className=\"absolute left-0 top-0 inline-block whitespace-pre\"\n            >\n              {label.split(\"\").map((char, index) => (\n                <motion.span\n                  // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity.\n                  key={index}\n                  custom={index * CASCADE_STAGGER}\n                  variants={CASCADE_LETTER_VARIANTS}\n                  className=\"inline-block whitespace-pre will-change-[opacity,filter,transform]\"\n                >\n                  {char}\n                </motion.span>\n              ))}\n            </motion.span>\n          </AnimatePresence>\n        </>\n      ) : (\n        <AnimatePresence initial={false}>\n          <motion.span\n            key={`text-${value}`}\n            initial={reduce ? { opacity: 0 } : { opacity: 0, y: 14, filter: ROLL_BLUR }}\n            animate={reduce ? { opacity: 1 } : { opacity: 1, y: 0, filter: \"blur(0px)\" }}\n            exit={reduce ? { opacity: 0 } : { opacity: 0, y: -14, filter: ROLL_BLUR }}\n            transition={reduce ? { duration: 0.15 } : SPRING_SWAP}\n            className=\"absolute left-0 top-0 inline-block will-change-[opacity,filter,transform]\"\n          >\n            {children}\n          </motion.span>\n        </AnimatePresence>\n      )}\n    </motion.span>\n  );\n}\n\nexport const StatefulButton = forwardRef<HTMLButtonElement, StatefulButtonProps>(function StatefulButton(\n  {\n    state = \"idle\",\n    children,\n    loadingText = \"Loading\",\n    successText = \"Done\",\n    errorText = \"Try again\",\n    icon,\n    disabled,\n    ...rest\n  },\n  ref,\n) {\n  const isBusy = state === \"loading\";\n  const stateText =\n    state === \"loading\"\n      ? loadingText\n      : state === \"success\"\n        ? successText\n        : state === \"error\"\n        ? errorText\n        : children;\n  const textKey =\n    typeof stateText === \"string\" ? `${state}-${stateText}` : state;\n\n  return (\n    <Button ref={ref} disabled={disabled || isBusy} aria-busy={isBusy} whileHover={undefined} {...rest}>\n      <span\n        aria-live=\"polite\"\n        className=\"relative inline-flex items-center justify-center overflow-hidden\"\n      >\n        <AnimatePresence initial={false}>\n          {state === \"loading\" ? (\n            <IconSlot keyId=\"loading-icon\">\n              <Loader2 className=\"h-4 w-4 animate-spin\" />\n            </IconSlot>\n          ) : null}\n          {state === \"success\" ? (\n            <IconSlot keyId=\"success-icon\">\n              <Check className=\"h-4 w-4\" />\n            </IconSlot>\n          ) : null}\n          {state === \"error\" ? (\n            <IconSlot keyId=\"error-icon\">\n              <X className=\"h-4 w-4\" />\n            </IconSlot>\n          ) : null}\n        </AnimatePresence>\n\n        <TextSlot value={textKey}>{stateText}</TextSlot>\n\n        <AnimatePresence initial={false}>\n          {state === \"idle\" && icon ? (\n            <IconSlot keyId=\"idle-icon\">{icon}</IconSlot>\n          ) : null}\n        </AnimatePresence>\n      </span>\n    </Button>\n  );\n});\n"
        },
        {
          "path": "components/beui/components/motion/popover-morph.tsx",
          "target": "@components/beui/components/motion/popover-morph.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  cloneElement,\n  createContext,\n  isValidElement,\n  type ReactElement,\n  type ReactNode,\n  type Ref,\n  useCallback,\n  useContext,\n  useEffect,\n  useId,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { usePopoverPortalPosition } from \"@/components/beui/components/motion/popover-position\";\nimport { EASE_OUT, SPRING_PANEL } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\ntype Side = \"top\" | \"bottom\";\ntype Align = \"start\" | \"end\";\n\ntype MorphContextValue = {\n  open: boolean;\n  setOpen: (open: boolean) => void;\n  toggle: () => void;\n  triggerId: string;\n  contentId: string;\n  /** The element the panel measures against — see `registerTrigger`. */\n  triggerRef: React.MutableRefObject<HTMLElement | null>;\n  registerTrigger: (node: HTMLElement | null) => void;\n  contentRef: React.MutableRefObject<HTMLDivElement | null>;\n};\n\nconst MorphContext = createContext<MorphContextValue | null>(null);\n\nfunction useMorphContext(component: string) {\n  const ctx = useContext(MorphContext);\n  if (!ctx) throw new Error(`${component} must be used within <MorphPopover>`);\n  return ctx;\n}\n\nexport interface MorphPopoverProps {\n  children: ReactNode;\n  /** Controlled open state. */\n  open?: boolean;\n  /** Uncontrolled initial open state. */\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  className?: string;\n}\n\n/**\n * A popover whose panel morphs open from the trigger corner: it's laid out at\n * full size but clipped to the corner nearest the trigger, then unclips as one\n * piece. Closes on outside pointer / Escape. Controlled or uncontrolled.\n */\nexport function MorphPopover({\n  children,\n  open: controlledOpen,\n  defaultOpen = false,\n  onOpenChange,\n  className,\n}: MorphPopoverProps) {\n  const baseId = useId();\n  const [root, setRoot] = useState<HTMLDivElement | null>(null);\n  const [trigger, setTrigger] = useState<HTMLElement | null>(null);\n  const contentRef = useRef<HTMLDivElement | null>(null);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const controlled = controlledOpen !== undefined;\n  const open = controlled ? controlledOpen : internalOpen;\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (!controlled) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [controlled, onOpenChange],\n  );\n  const toggle = useCallback(() => setOpen(!open), [setOpen, open]);\n\n  // A trigger normally registers itself through MorphPopoverTrigger. It can't\n  // when something else already clones the element — a Tooltip wrapping the\n  // button, say — and an unregistered trigger leaves the panel with nothing to\n  // measure against, so it renders permanently invisible. The root boxes the\n  // trigger exactly (the content portals out of it), so it stands in until a\n  // real trigger registers, and stands in again if that one unmounts. Both are\n  // state, so a trigger arriving while the panel is open re-anchors it.\n  const anchorRef = useMemo<React.MutableRefObject<HTMLElement | null>>(\n    () => ({ current: trigger ?? root }),\n    [root, trigger],\n  );\n\n  // The panel is a `role=\"dialog\"` and goes inert the moment it closes, so\n  // focus cannot be left sitting inside it: a dismissal hands it back to the\n  // trigger, the way the ARIA dialog pattern asks. A pointer dismissal takes\n  // the focus onward itself when it lands on something focusable — this only\n  // catches the case where it would otherwise be stranded. When no trigger has\n  // registered, the root anchor stands in only if it can actually hold focus;\n  // there is nowhere better than where the keyboard already is, so leave it.\n  const close = useCallback(() => {\n    setOpen(false);\n    const focused = document.activeElement;\n    const inPanel =\n      focused instanceof HTMLElement && contentRef.current?.contains(focused);\n    if (!inPanel) return;\n    const restore = trigger ?? (root && root.tabIndex >= 0 ? root : null);\n    restore?.focus();\n  }, [root, setOpen, trigger]);\n\n  useEffect(() => {\n    if (!open) return;\n    const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && close();\n    const onPointer = (e: PointerEvent) => {\n      const target = e.target as Node;\n      if (\n        root &&\n        !root.contains(target) &&\n        !contentRef.current?.contains(target)\n      )\n        close();\n    };\n    window.addEventListener(\"keydown\", onKey);\n    window.addEventListener(\"pointerdown\", onPointer);\n    return () => {\n      window.removeEventListener(\"keydown\", onKey);\n      window.removeEventListener(\"pointerdown\", onPointer);\n    };\n  }, [open, root, close]);\n\n  const ctx = useMemo<MorphContextValue>(\n    () => ({\n      open,\n      setOpen,\n      toggle,\n      triggerId: `${baseId}-trigger`,\n      contentId: `${baseId}-content`,\n      triggerRef: anchorRef,\n      registerTrigger: setTrigger,\n      contentRef,\n    }),\n    [open, setOpen, toggle, baseId, anchorRef],\n  );\n\n  return (\n    <MorphContext.Provider value={ctx}>\n      <div ref={setRoot} className={cn(\"relative inline-flex\", className)}>\n        {children}\n      </div>\n    </MorphContext.Provider>\n  );\n}\n\nexport interface MorphPopoverTriggerProps {\n  children: ReactElement;\n}\n\nfunction mergeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n  return (node: T | null) => {\n    for (const ref of refs) {\n      if (typeof ref === \"function\") ref(node);\n      else if (ref && typeof ref === \"object\")\n        (ref as React.MutableRefObject<T | null>).current = node;\n    }\n  };\n}\n\n/** Wraps a single element, toggling the popover on click. */\nexport function MorphPopoverTrigger({ children }: MorphPopoverTriggerProps) {\n  const ctx = useMorphContext(\"MorphPopoverTrigger\");\n  if (!isValidElement(children)) return children;\n\n  const child = children as ReactElement<Record<string, unknown>>;\n  const childOnClick = child.props.onClick as\n    | ((e: unknown) => void)\n    | undefined;\n  const childRef = (child.props as { ref?: Ref<HTMLElement> }).ref;\n\n  return cloneElement(child, {\n    id: ctx.triggerId,\n    ref: mergeRefs(childRef, ctx.registerTrigger),\n    onClick: (e: unknown) => {\n      childOnClick?.(e);\n      ctx.toggle();\n    },\n    \"aria-haspopup\": \"dialog\",\n    \"aria-expanded\": ctx.open,\n    \"aria-controls\": ctx.open ? ctx.contentId : undefined,\n  });\n}\n\nconst originFor = (side: Side, align: Align) =>\n  `${side === \"bottom\" ? \"top\" : \"bottom\"} ${align === \"end\" ? \"right\" : \"left\"}`;\n\n// A clip that hides everything but the corner nearest the trigger, so the\n// panel appears to grow out of it. inset(top right bottom left).\nfunction clipHidden(side: Side, align: Align, radius: number) {\n  const top = side === \"bottom\" ? \"0%\" : \"92%\";\n  const bottom = side === \"bottom\" ? \"92%\" : \"0%\";\n  const right = align === \"end\" ? \"0%\" : \"92%\";\n  const left = align === \"end\" ? \"92%\" : \"0%\";\n  return `inset(${top} ${right} ${bottom} ${left} round ${radius}px)`;\n}\nconst clipShown = (radius: number) => `inset(0% 0% 0% 0% round ${radius}px)`;\n\n// Preserve the original spring character on the wrapper, but tween the complex\n// clip-path so it cannot snap when the spring resolves its final distance.\nconst MORPH_CLIP_TRANSITION = { duration: 0.32, ease: EASE_OUT } as const;\n\nexport interface MorphPopoverContentProps {\n  children: ReactNode;\n  side?: Side;\n  align?: Align;\n  /** Gap between trigger and panel, in px. Default 8. */\n  sideOffset?: number;\n  /** Panel corner radius, in px. Default 16. */\n  radius?: number;\n  className?: string;\n}\n\nexport function MorphPopoverContent({\n  children,\n  side = \"bottom\",\n  align = \"end\",\n  sideOffset = 8,\n  radius = 16,\n  className,\n}: MorphPopoverContentProps) {\n  const ctx = useMorphContext(\"MorphPopoverContent\");\n  const reduce = useReducedMotion() ?? false;\n  const [portalReady, setPortalReady] = useState(false);\n  const layout = usePopoverPortalPosition(\n    ctx.triggerRef,\n    ctx.contentRef,\n    portalReady && ctx.open,\n  );\n\n  useEffect(() => setPortalReady(true), []);\n  const left = layout\n    ? align === \"end\"\n      ? layout.trigger.left + layout.trigger.width - layout.content.width\n      : layout.trigger.left\n    : 0;\n  const top = layout\n    ? side === \"bottom\"\n      ? layout.trigger.top + layout.trigger.height + sideOffset\n      : layout.trigger.top - layout.content.height - sideOffset\n    : 0;\n\n  // Both directions travel between the exact same hidden/show states. Exit\n  // targets \"hidden\" directly instead of introducing separate choreography.\n  const wrap = reduce\n    ? undefined\n    : {\n        hidden: { opacity: 0, scale: 0.96, transition: SPRING_PANEL },\n        show: { opacity: 1, scale: 1, transition: SPRING_PANEL },\n      };\n  const clip = reduce\n    ? undefined\n    : {\n        hidden: {\n          clipPath: clipHidden(side, align, radius),\n          transition: MORPH_CLIP_TRANSITION,\n        },\n        show: {\n          clipPath: clipShown(radius),\n          transition: MORPH_CLIP_TRANSITION,\n        },\n      };\n\n  // Keep the server and first client render identical, then mount the portal.\n  if (!portalReady) return null;\n\n  return createPortal(\n    <AnimatePresence>\n      {ctx.open ? (\n        <motion.div\n          data-morph-popover-portal=\"\"\n          // Wrapper carries the shadow as a drop-shadow filter, which hugs the\n          // clipped shape below (box-shadow would just get clipped away).\n          variants={wrap}\n          initial={reduce ? { opacity: 0 } : \"hidden\"}\n          animate={reduce ? { opacity: 1 } : \"show\"}\n          exit={reduce ? { opacity: 0 } : \"hidden\"}\n          transition={reduce ? { duration: 0.12 } : undefined}\n          style={{\n            left,\n            top,\n            visibility: layout ? \"visible\" : \"hidden\",\n            transformOrigin: originFor(side, align),\n          }}\n          className=\"fixed z-[9999] [filter:drop-shadow(0_10px_18px_rgba(0,0,0,0.14))]\"\n        >\n          <motion.div\n            ref={ctx.contentRef}\n            id={ctx.contentId}\n            role=\"dialog\"\n            aria-labelledby={ctx.triggerId}\n            variants={clip}\n            style={{ borderRadius: radius }}\n            className={cn(\n              \"overflow-hidden border border-border bg-background\",\n              className,\n            )}\n          >\n            {children}\n          </motion.div>\n        </motion.div>\n      ) : null}\n    </AnimatePresence>,\n    document.body,\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/popover-position.ts",
          "target": "@components/beui/components/motion/popover-position.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  type MutableRefObject,\n  useCallback,\n  useLayoutEffect,\n  useState,\n} from \"react\";\n\nexport type PortalLayout = {\n  trigger: {\n    left: number;\n    top: number;\n    width: number;\n    height: number;\n  };\n  content: {\n    width: number;\n    height: number;\n  };\n};\n\nfunction sameLayout(a: PortalLayout | null, b: PortalLayout) {\n  return (\n    a?.trigger.left === b.trigger.left &&\n    a.trigger.top === b.trigger.top &&\n    a.trigger.width === b.trigger.width &&\n    a.trigger.height === b.trigger.height &&\n    a.content.width === b.content.width &&\n    a.content.height === b.content.height\n  );\n}\n\n/** Measures a trigger and portalled panel in viewport coordinates. */\nexport function usePopoverPortalPosition<\n  TriggerElement extends HTMLElement,\n  ContentElement extends HTMLElement,\n>(\n  triggerRef: MutableRefObject<TriggerElement | null>,\n  contentRef: MutableRefObject<ContentElement | null>,\n  active: boolean,\n) {\n  const [layout, setLayout] = useState<PortalLayout | null>(null);\n\n  const update = useCallback(() => {\n    const trigger = triggerRef.current;\n    const content = contentRef.current;\n    if (!trigger || !content) return;\n\n    const rect = trigger.getBoundingClientRect();\n    const next: PortalLayout = {\n      trigger: {\n        left: rect.left,\n        top: rect.top,\n        width: rect.width,\n        height: rect.height,\n      },\n      content: {\n        width: content.offsetWidth,\n        height: content.offsetHeight,\n      },\n    };\n    setLayout((current) => (sameLayout(current, next) ? current : next));\n  }, [contentRef, triggerRef]);\n\n  useLayoutEffect(() => {\n    update();\n    if (!active) return;\n\n    const trigger = triggerRef.current;\n    const content = contentRef.current;\n    const observer = new ResizeObserver(update);\n    if (trigger) observer.observe(trigger);\n    if (content) observer.observe(content);\n\n    window.addEventListener(\"scroll\", update, true);\n    window.addEventListener(\"resize\", update);\n    return () => {\n      observer.disconnect();\n      window.removeEventListener(\"scroll\", update, true);\n      window.removeEventListener(\"resize\", update);\n    };\n  }, [active, contentRef, triggerRef, update]);\n\n  return layout;\n}\n"
        },
        {
          "path": "components/beui/components/motion/select.tsx",
          "target": "@components/beui/components/motion/select.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Check, ChevronDown } from \"lucide-react\";\nimport {\n  motion,\n  type Transition,\n  useReducedMotion,\n  type Variants,\n} from \"motion/react\";\nimport {\n  createContext,\n  type ReactNode,\n  useCallback,\n  useContext,\n  useEffect,\n  useId,\n  useLayoutEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nconst INSTANT_TRANSITION: Transition = { duration: 0 };\n\n// Spring with bounce powers the unfold/separation; per-property timings in the\n// content choreograph it (see SelectContent). Mirrors bouncy-accordion's feel.\nconst CHEVRON_TRANSITION: Transition = { type: \"spring\", duration: 0.4, bounce: 0.3 };\n\nconst LIST_VARIANTS: Variants = {\n  hidden: {},\n  show: { transition: { staggerChildren: 0.035, delayChildren: 0.05 } },\n};\nconst ITEM_VARIANTS: Variants = {\n  hidden: { opacity: 0, y: -6, filter: \"blur(3px)\" },\n  show: { opacity: 1, y: 0, filter: \"blur(0px)\" },\n};\n\ntype Placement = \"bottom\" | \"top\";\n\ninterface SelectContextValue {\n  value: string | undefined;\n  open: boolean;\n  setOpen: (open: boolean) => void;\n  select: (value: string) => void;\n  register: (value: string, label: string) => void;\n  unregister: (value: string) => void;\n  labelFor: (value: string | undefined) => string | undefined;\n  reduce: boolean;\n  triggerId: string;\n  listId: string;\n  disabled: boolean;\n  placement: Placement;\n  setPlacement: (p: Placement) => void;\n}\n\nconst SelectContext = createContext<SelectContextValue | null>(null);\n\nfunction useSelectContext(component: string) {\n  const ctx = useContext(SelectContext);\n  if (!ctx) throw new Error(`${component} must be used within <Select>`);\n  return ctx;\n}\n\nexport interface SelectProps {\n  value?: string;\n  defaultValue?: string;\n  onValueChange?: (value: string) => void;\n  /**\n   * Controlled open state of the panel. A layout that stacks selects can hold\n   * this to keep exactly one panel open — the panel is absolutely positioned\n   * inside its field, so two open at once paint over each other's options.\n   */\n  open?: boolean;\n  /** Uncontrolled initial open state. Default false. */\n  defaultOpen?: boolean;\n  /**\n   * Fires whenever the panel opens or closes. The panel is absolutely\n   * positioned inside the field, so a layout that stacks selects has to know\n   * which one is open to paint it above its neighbours.\n   */\n  onOpenChange?: (open: boolean) => void;\n  disabled?: boolean;\n  className?: string;\n  children: ReactNode;\n}\n\nexport function Select({\n  value,\n  defaultValue,\n  onValueChange,\n  open: openProp,\n  defaultOpen = false,\n  onOpenChange,\n  disabled = false,\n  className,\n  children,\n}: SelectProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const rootRef = useRef<HTMLDivElement>(null);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const [internal, setInternal] = useState(defaultValue);\n  const [labels, setLabels] = useState<Map<string, string>>(new Map());\n  const [placement, setPlacement] = useState<Placement>(\"bottom\");\n\n  const controlled = value !== undefined;\n  const current = controlled ? value : internal;\n  const openControlled = openProp !== undefined;\n  const open = openControlled ? openProp : internalOpen;\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (!openControlled) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [onOpenChange, openControlled],\n  );\n\n  const select = useCallback(\n    (next: string) => {\n      if (!controlled) setInternal(next);\n      onValueChange?.(next);\n      setOpen(false);\n    },\n    [controlled, onValueChange, setOpen],\n  );\n\n  const register = useCallback((v: string, label: string) => {\n    setLabels((m) => (m.get(v) === label ? m : new Map(m).set(v, label)));\n  }, []);\n  const unregister = useCallback((v: string) => {\n    setLabels((m) => {\n      if (!m.has(v)) return m;\n      const next = new Map(m);\n      next.delete(v);\n      return next;\n    });\n  }, []);\n\n  // close on outside pointer / escape\n  useEffect(() => {\n    if (!open) return;\n    const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && setOpen(false);\n    const onPointer = (e: PointerEvent) => {\n      if (rootRef.current && !rootRef.current.contains(e.target as Node))\n        setOpen(false);\n    };\n    window.addEventListener(\"keydown\", onKey);\n    window.addEventListener(\"pointerdown\", onPointer);\n    return () => {\n      window.removeEventListener(\"keydown\", onKey);\n      window.removeEventListener(\"pointerdown\", onPointer);\n    };\n  }, [open, setOpen]);\n\n  const ctx = useMemo<SelectContextValue>(\n    () => ({\n      value: current,\n      open,\n      setOpen,\n      select,\n      register,\n      unregister,\n      labelFor: (v) => (v === undefined ? undefined : labels.get(v)),\n      reduce,\n      triggerId: `${baseId}-trigger`,\n      listId: `${baseId}-list`,\n      disabled,\n      placement,\n      setPlacement,\n    }),\n    [\n      current,\n      open,\n      setOpen,\n      select,\n      register,\n      unregister,\n      labels,\n      reduce,\n      baseId,\n      disabled,\n      placement,\n    ],\n  );\n\n  return (\n    <SelectContext.Provider value={ctx}>\n      <div ref={rootRef} className={cn(\"relative\", className)}>\n        {children}\n      </div>\n    </SelectContext.Provider>\n  );\n}\n\nexport interface SelectTriggerProps {\n  className?: string;\n  children: ReactNode;\n}\n\nexport function SelectTrigger({ className, children }: SelectTriggerProps) {\n  const ctx = useSelectContext(\"SelectTrigger\");\n  const isTop = ctx.placement === \"top\";\n  // edge facing the panel flattens then rounds; the far edge stays rounded.\n  // All four corners are specified so none gets stranded when placement flips.\n  const kf = ctx.open ? [0, 0, 12] : [12, 0, 12];\n  const kfT: Transition = ctx.reduce\n    ? { duration: 0 }\n    : ctx.open\n      ? { duration: 0.6, times: [0, 0.4, 1], ease: EASE_OUT }\n      : { duration: 0.42, times: [0, 0.5, 1], ease: EASE_OUT };\n  return (\n    <motion.button\n      type=\"button\"\n      id={ctx.triggerId}\n      disabled={ctx.disabled}\n      aria-haspopup=\"listbox\"\n      aria-expanded={ctx.open}\n      aria-controls={ctx.open ? ctx.listId : undefined}\n      onClick={() => ctx.setOpen(!ctx.open)}\n      // Gooey: the edge facing the panel snaps flat (panel attached) then rounds\n      // back once the panel pulls away — the two pinch apart.\n      initial={false}\n      animate={{\n        borderTopLeftRadius: isTop ? kf : 12,\n        borderTopRightRadius: isTop ? kf : 12,\n        borderBottomLeftRadius: isTop ? 12 : kf,\n        borderBottomRightRadius: isTop ? 12 : kf,\n      }}\n      transition={{\n        borderTopLeftRadius: isTop ? kfT : INSTANT_TRANSITION,\n        borderTopRightRadius: isTop ? kfT : INSTANT_TRANSITION,\n        borderBottomLeftRadius: isTop ? INSTANT_TRANSITION : kfT,\n        borderBottomRightRadius: isTop ? INSTANT_TRANSITION : kfT,\n      }}\n      className={cn(\n        \"relative z-10 flex w-full items-center justify-between gap-2 rounded-xl border border-border bg-background px-3 py-2 text-sm text-foreground outline-none transition-colors\",\n        \"hover:border-(--color-border-strong) focus-visible:ring-2 focus-visible:ring-foreground/20\",\n        \"disabled:pointer-events-none disabled:opacity-50\",\n        className,\n      )}\n    >\n      {children}\n      <motion.span\n        aria-hidden\n        animate={{ rotate: ctx.open ? 180 : 0 }}\n        transition={ctx.reduce ? { duration: 0 } : CHEVRON_TRANSITION}\n        className=\"text-muted-foreground\"\n      >\n        <ChevronDown className=\"h-4 w-4\" />\n      </motion.span>\n    </motion.button>\n  );\n}\n\nexport interface SelectValueProps {\n  placeholder?: string;\n  className?: string;\n}\n\nexport function SelectValue({ placeholder, className }: SelectValueProps) {\n  const ctx = useSelectContext(\"SelectValue\");\n  const label = ctx.labelFor(ctx.value);\n  return (\n    <span\n      className={cn(label ? \"text-foreground\" : \"text-muted-foreground\", className)}\n    >\n      {label ?? placeholder ?? \"Select\"}\n    </span>\n  );\n}\n\nexport interface SelectContentProps {\n  className?: string;\n  children: ReactNode;\n}\n\nexport function SelectContent({ className, children }: SelectContentProps) {\n  const ctx = useSelectContext(\"SelectContent\");\n  const innerRef = useRef<HTMLDivElement>(null);\n  const [height, setHeight] = useState(0);\n  const open = ctx.open;\n  const { setPlacement } = ctx;\n\n  useLayoutEffect(() => {\n    const node = innerRef.current;\n    if (!node) return;\n    const measure = () => setHeight(node.offsetHeight);\n    measure();\n    const observer = new ResizeObserver(measure);\n    observer.observe(node);\n    return () => observer.disconnect();\n  });\n\n  // On open, flip upward when there isn't room below and there's more above.\n  useLayoutEffect(() => {\n    if (!open) return;\n    const trigger = document.getElementById(ctx.triggerId);\n    const node = innerRef.current;\n    if (!trigger || !node) return;\n    const rect = trigger.getBoundingClientRect();\n    const h = node.offsetHeight;\n    const below = window.innerHeight - rect.bottom;\n    const above = rect.top;\n    setPlacement(below < h + 16 && above > below ? \"top\" : \"bottom\");\n  }, [open, ctx.triggerId, setPlacement]);\n\n  // Specify EVERY corner + both margins each render. The near edge (facing the\n  // trigger) animates flat->round and the gap opens on that side; the far edge\n  // stays rounded and its margin pinned to 0. Setting all of them avoids a\n  // stranded square corner when the placement flips between opens.\n  const isTop = ctx.placement === \"top\";\n  const nearGap = open ? 8 : 0;\n  const nearRadius = open ? 12 : 0;\n\n  const gapT: Transition = open\n    ? { type: \"spring\", duration: 0.6, bounce: 0.5, delay: 0.12 }\n    : { type: \"spring\", duration: 0.3, bounce: 0.1 };\n  const radiusT: Transition = open\n    ? { duration: 0.3, ease: EASE_OUT, delay: 0.14 }\n    : { duration: 0.16, ease: EASE_OUT };\n\n  // Items stay mounted (open just animates the panel) so each item's label\n  // registration persists — otherwise the trigger would fall back to the\n  // placeholder the moment the panel closes.\n  return (\n    <motion.div\n      id={ctx.listId}\n      role=\"listbox\"\n      aria-labelledby={ctx.triggerId}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        ctx.reduce\n          ? { opacity: open ? 1 : 0, height: open ? height : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              height: open ? height : 0,\n              // gap opens on the side facing the trigger\n              marginTop: isTop ? 0 : nearGap,\n              marginBottom: isTop ? nearGap : 0,\n              // near corners go flat->round; far corners stay rounded\n              borderTopLeftRadius: isTop ? 12 : nearRadius,\n              borderTopRightRadius: isTop ? 12 : nearRadius,\n              borderBottomLeftRadius: isTop ? nearRadius : 12,\n              borderBottomRightRadius: isTop ? nearRadius : 12,\n            }\n      }\n      transition={\n        ctx.reduce\n          ? { duration: 0.12 }\n          : {\n              opacity: open\n                ? { duration: 0.18 }\n                : { duration: 0.16, delay: 0.12 },\n              height: open\n                ? { type: \"spring\", duration: 0.42, bounce: 0.14 }\n                : { duration: 0.26, ease: EASE_OUT, delay: 0.14 },\n              marginTop: isTop ? INSTANT_TRANSITION : gapT,\n              marginBottom: isTop ? gapT : INSTANT_TRANSITION,\n              borderTopLeftRadius: isTop ? INSTANT_TRANSITION : radiusT,\n              borderTopRightRadius: isTop ? INSTANT_TRANSITION : radiusT,\n              borderBottomLeftRadius: isTop ? radiusT : INSTANT_TRANSITION,\n              borderBottomRightRadius: isTop ? radiusT : INSTANT_TRANSITION,\n            }\n      }\n      style={{\n        transformOrigin: isTop ? \"bottom\" : \"top\",\n        overflow: \"hidden\",\n        pointerEvents: open ? \"auto\" : \"none\",\n      }}\n      // flush against the trigger, then separates into its own rounded pill;\n      // sits above or below depending on available space\n      className={cn(\n        \"absolute left-0 right-0 z-20 rounded-xl border border-border bg-background shadow-lg\",\n        isTop ? \"bottom-full\" : \"top-full\",\n        className,\n      )}\n    >\n      <motion.div\n        ref={innerRef}\n        variants={ctx.reduce ? undefined : LIST_VARIANTS}\n        initial={false}\n        animate={open ? \"show\" : \"hidden\"}\n        className=\"p-1\"\n      >\n        {children}\n      </motion.div>\n    </motion.div>\n  );\n}\n\nexport interface SelectItemProps {\n  value: string;\n  disabled?: boolean;\n  className?: string;\n  children: ReactNode;\n}\n\nexport function SelectItem({\n  value,\n  disabled = false,\n  className,\n  children,\n}: SelectItemProps) {\n  const ctx = useSelectContext(\"SelectItem\");\n  const selected = ctx.value === value;\n  const label = typeof children === \"string\" ? children : value;\n\n  useLayoutEffect(() => {\n    ctx.register(value, label);\n    return () => ctx.unregister(value);\n  // Registration is intentionally keyed to stable context methods and the item identity.\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [ctx.register, ctx.unregister, value, label]);\n\n  return (\n    <motion.li variants={ctx.reduce ? undefined : ITEM_VARIANTS}>\n      <button\n        type=\"button\"\n        role=\"option\"\n        aria-selected={selected}\n        disabled={disabled}\n        onClick={() => ctx.select(value)}\n        className={cn(\n          \"flex w-full items-center justify-between gap-2 rounded-lg px-2.5 py-1.5 text-left text-sm outline-none transition-colors\",\n          selected\n            ? \"bg-muted text-foreground\"\n            : \"text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:bg-muted\",\n          \"disabled:pointer-events-none disabled:opacity-50\",\n          className,\n        )}\n      >\n        {children}\n        {selected ? <Check className=\"h-3.5 w-3.5 shrink-0\" /> : null}\n      </button>\n    </motion.li>\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-todo-list",
      "type": "registry:block",
      "title": "Beui Todo List",
      "description": "Todo List",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/todo-list.tsx",
          "target": "@components/beui/components/agents/todo-list.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { ChevronDown, ListTodo } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useEffect,\n  useId,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport { ActionSwapRollText } from \"@/components/beui/components/motion/action-swap-roll\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport {\n  EASE_OUT,\n  SPRING_LAYOUT,\n  SPRING_SWAP,\n} from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type TodoItemStatus =\n  | \"pending\"\n  | \"in-progress\"\n  | \"completed\"\n  | \"cancelled\";\n\nexport interface TodoItem {\n  id: string;\n  title: ReactNode;\n  status?: TodoItemStatus;\n  progress?: number;\n  detail?: ReactNode;\n}\n\nexport interface TodoListProps {\n  items: TodoItem[];\n  title?: ReactNode;\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  collapseOnComplete?: boolean;\n  maxHeight?: number;\n  className?: string;\n}\n\nfunction statusLabel(status: TodoItemStatus) {\n  if (status === \"in-progress\") return \"In progress\";\n  if (status === \"completed\") return \"Completed\";\n  if (status === \"cancelled\") return \"Cancelled\";\n  return \"Pending\";\n}\n\nfunction TodoHeaderIcon({ complete }: { complete: boolean }) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <span\n      aria-hidden=\"true\"\n      className=\"relative grid size-6 shrink-0 place-items-center\"\n    >\n      <AnimatePresence initial={false} mode=\"popLayout\">\n        {complete ? (\n          <motion.svg\n            key=\"complete\"\n            viewBox=\"0 0 24 24\"\n            initial={reduce ? { opacity: 1 } : { opacity: 0, scale: 0.72 }}\n            animate={{ opacity: 1, scale: 1 }}\n            exit={{ opacity: 0 }}\n            transition={reduce ? { duration: 0 } : SPRING_SWAP}\n            className=\"absolute size-5.5 overflow-visible text-emerald-500\"\n          >\n            <circle cx=\"12\" cy=\"12\" r=\"9\" fill=\"currentColor\" />\n            <motion.path\n              d=\"M7.5 12.25 10.5 15.25 16.75 8.75\"\n              fill=\"none\"\n              stroke=\"white\"\n              strokeWidth=\"2.25\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              initial={reduce ? { pathLength: 1 } : { pathLength: 0 }}\n              animate={{ pathLength: 1 }}\n              transition={\n                reduce ? { duration: 0 } : { duration: 0.24, ease: EASE_OUT }\n              }\n            />\n          </motion.svg>\n        ) : (\n          <motion.span\n            key=\"todo\"\n            initial={reduce ? { opacity: 1 } : { opacity: 0, scale: 0.8 }}\n            animate={{ opacity: 1, scale: 1 }}\n            exit={reduce ? { opacity: 0 } : { opacity: 0, scale: 0.72 }}\n            transition={reduce ? { duration: 0 } : SPRING_SWAP}\n            className=\"absolute grid place-items-center text-muted-foreground\"\n          >\n            <ListTodo className=\"size-4\" />\n          </motion.span>\n        )}\n      </AnimatePresence>\n    </span>\n  );\n}\n\nfunction TodoStatusIcon({\n  status,\n  progress,\n}: {\n  status: TodoItemStatus;\n  progress?: number;\n}) {\n  const reduce = useReducedMotion() ?? false;\n  const normalizedProgress =\n    progress === undefined ? 0.68 : Math.min(100, Math.max(0, progress)) / 100;\n\n  return (\n    <motion.svg\n      aria-hidden=\"true\"\n      viewBox=\"0 0 24 24\"\n      initial={false}\n      className={cn(\n        \"mx-0.5 size-5 shrink-0 overflow-visible text-muted-foreground\",\n        status === \"in-progress\" && \"text-foreground\",\n        status === \"cancelled\" && \"text-rose-600 dark:text-rose-400\",\n      )}\n    >\n      <motion.circle\n        cx=\"12\"\n        cy=\"12\"\n        r=\"9\"\n        fill=\"currentColor\"\n        stroke=\"currentColor\"\n        strokeWidth=\"1.5\"\n        strokeDasharray={status === \"pending\" ? \"2 3\" : undefined}\n        strokeLinecap=\"round\"\n        initial={false}\n        animate={{ fillOpacity: status === \"completed\" ? 0.06 : 0 }}\n        transition={reduce ? { duration: 0 } : { duration: 0.18, ease: EASE_OUT }}\n        className={cn(status === \"in-progress\" && \"opacity-20\")}\n      />\n      <motion.circle\n        cx=\"12\"\n        cy=\"12\"\n        r=\"9\"\n        pathLength=\"1\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        initial={false}\n        animate={{\n          pathLength: status === \"in-progress\" ? normalizedProgress : 0,\n          opacity: status === \"in-progress\" ? 1 : 0,\n          rotate:\n            status === \"in-progress\" && progress === undefined && !reduce\n              ? 360\n              : -90,\n        }}\n        transition={\n          status === \"in-progress\" && progress === undefined && !reduce\n            ? { rotate: { duration: 1.1, repeat: Infinity, ease: \"linear\" } }\n            : reduce\n              ? { duration: 0 }\n              : SPRING_LAYOUT\n        }\n        style={{ transformOrigin: \"12px 12px\" }}\n      />\n      <motion.path\n        d=\"M7.5 12.25 10.5 15.25 16.75 8.75\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        initial={false}\n        animate={{\n          pathLength: status === \"completed\" ? 1 : 0,\n          opacity: status === \"completed\" ? 1 : 0,\n        }}\n        transition={reduce ? { duration: 0 } : { duration: 0.24, ease: EASE_OUT }}\n      />\n      <motion.path\n        d=\"M8.5 8.5 15.5 15.5M15.5 8.5 8.5 15.5\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        initial={false}\n        animate={{\n          pathLength: status === \"cancelled\" ? 1 : 0,\n          opacity: status === \"cancelled\" ? 1 : 0,\n        }}\n        transition={reduce ? { duration: 0 } : { duration: 0.2, ease: EASE_OUT }}\n      />\n    </motion.svg>\n  );\n}\n\nexport function TodoList({\n  items,\n  title = \"To-dos\",\n  open,\n  defaultOpen = true,\n  onOpenChange,\n  collapseOnComplete = true,\n  maxHeight = 248,\n  className,\n}: TodoListProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const triggerId = `${baseId}-trigger`;\n  const contentId = `${baseId}-content`;\n  const viewportRef = useRef<HTMLDivElement>(null);\n  const previousComplete = useRef(false);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const currentOpen = open ?? internalOpen;\n  const completed = items.filter((item) => item.status === \"completed\").length;\n  const allComplete = items.length > 0 && completed === items.length;\n  const itemCount = items.length;\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [onOpenChange, open],\n  );\n\n  useEffect(() => {\n    if (previousComplete.current && !allComplete) {\n      setOpen(true);\n    }\n    if (!previousComplete.current && allComplete && collapseOnComplete) {\n      setOpen(false);\n    }\n    previousComplete.current = allComplete;\n  }, [allComplete, collapseOnComplete, setOpen]);\n\n  useLayoutEffect(() => {\n    const viewport = viewportRef.current;\n    if (!viewport || itemCount === 0) return;\n\n    const frame = requestAnimationFrame(() => {\n      if (viewport.scrollHeight <= viewport.clientHeight) return;\n      if (typeof viewport.scrollTo === \"function\") {\n        viewport.scrollTo({\n          top: viewport.scrollHeight,\n          behavior: reduce ? \"auto\" : \"smooth\",\n        });\n      } else {\n        viewport.scrollTop = viewport.scrollHeight;\n      }\n    });\n    return () => cancelAnimationFrame(frame);\n  }, [itemCount, reduce]);\n\n  return (\n    <section\n      aria-label=\"Agent task list\"\n      className={cn(\n        \"w-full overflow-hidden rounded-lg border border-border/70\",\n        className,\n      )}\n    >\n      <button\n        id={triggerId}\n        type=\"button\"\n        aria-expanded={currentOpen}\n        aria-controls={contentId}\n        onClick={() => setOpen(!currentOpen)}\n        className=\"group flex h-11 w-full items-center gap-2.5 rounded-lg px-3.5 text-left outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n      >\n        <TodoHeaderIcon complete={allComplete} />\n        <h3 className=\"min-w-0 flex-1 truncate text-sm font-medium text-foreground/90\">\n          {title}\n        </h3>\n        <span\n          className={cn(\n            \"shrink-0 text-xs font-medium tabular-nums text-muted-foreground\",\n            allComplete && \"text-emerald-600 dark:text-emerald-400\",\n          )}\n        >\n          <span className=\"sr-only\">\n            {completed} of {items.length} tasks completed\n          </span>\n          <span aria-hidden=\"true\" className=\"inline-flex\">\n            <ActionSwapRollText value={String(completed)}>\n              {completed}\n            </ActionSwapRollText>\n            <span>/</span>\n            <span>{items.length}</span>\n          </span>\n        </span>\n        <motion.span\n          aria-hidden=\"true\"\n          animate={{ rotate: currentOpen ? 180 : 0 }}\n          transition={reduce ? { duration: 0 } : SPRING_SWAP}\n          className=\"text-muted-foreground/50 transition-colors group-hover:text-muted-foreground\"\n        >\n          <ChevronDown className=\"size-3.5\" />\n        </motion.span>\n      </button>\n\n      <AgentDisclosure\n        id={contentId}\n        role=\"region\"\n        aria-labelledby={triggerId}\n        open={currentOpen}\n      >\n        <div\n          ref={viewportRef}\n          className=\"scrollbar-hide overflow-y-auto px-2 pb-2\"\n          style={{ maxHeight }}\n        >\n          {items.length ? (\n            <ol aria-live=\"polite\" className=\"space-y-0\">\n            <AnimatePresence initial={false} mode=\"popLayout\">\n              {items.map((item) => {\n                const status = item.status ?? \"pending\";\n                return (\n                  <motion.li\n                    layout=\"position\"\n                    key={item.id}\n                    initial={reduce ? { opacity: 1 } : { opacity: 0, y: 6 }}\n                    animate={{ opacity: 1, y: 0 }}\n                    exit={reduce ? { opacity: 0 } : { opacity: 0, y: -3 }}\n                    transition={\n                      reduce\n                        ? { duration: 0 }\n                        : {\n                            opacity: { duration: 0.18, ease: EASE_OUT },\n                            y: SPRING_LAYOUT,\n                            layout: SPRING_LAYOUT,\n                          }\n                    }\n                    className=\"flex min-h-9 items-center gap-2.5 rounded-md px-1.5 py-1\"\n                  >\n                    <TodoStatusIcon status={status} progress={item.progress} />\n                    <span className=\"sr-only\">{statusLabel(status)}: </span>\n                    <span\n                      className={cn(\n                        \"min-w-0 flex-1 truncate text-sm leading-5\",\n                        status === \"pending\" && \"text-muted-foreground/65\",\n                        status === \"in-progress\" && \"text-foreground\",\n                        status === \"completed\" && \"text-muted-foreground/60\",\n                        status === \"cancelled\" && \"text-muted-foreground/55\",\n                      )}\n                    >\n                      <span className=\"relative inline-block max-w-full\">\n                        {item.title}\n                        <motion.span\n                          aria-hidden=\"true\"\n                          initial={false}\n                          animate={{\n                            scaleX: status === \"completed\" ? 1 : 0,\n                            opacity: status === \"completed\" ? 1 : 0,\n                          }}\n                          transition={\n                            reduce\n                              ? { duration: 0 }\n                              : { duration: 0.28, ease: EASE_OUT, delay: 0.06 }\n                          }\n                          className=\"absolute inset-x-0 top-1/2 h-px origin-left bg-current\"\n                        />\n                      </span>\n                    </span>\n                    {item.detail ? (\n                      <span className=\"shrink-0 text-sm text-muted-foreground/55\">\n                        {item.detail}\n                      </span>\n                    ) : null}\n                  </motion.li>\n                );\n              })}\n            </AnimatePresence>\n            </ol>\n          ) : (\n            <p className=\"px-1.5 py-2 text-sm text-muted-foreground\">\n              No tasks yet\n            </p>\n          )}\n        </div>\n      </AgentDisclosure>\n    </section>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/action-swap-roll.tsx",
          "target": "@components/beui/components/motion/action-swap-roll.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  ActionSwapButton,\n  ActionSwapIcon,\n  ActionSwapText,\n  type ActionSwapButtonProps,\n  type ActionSwapIconProps,\n  type ActionSwapTextProps,\n} from \"./action-swap\";\n\nexport type {\n  ActionSwapButtonSize,\n  ActionSwapButtonVariant,\n  ActionSwapItem,\n} from \"./action-swap\";\n\nexport type ActionSwapRollButtonProps = Omit<ActionSwapButtonProps, \"animation\">;\nexport type ActionSwapRollTextProps = Omit<ActionSwapTextProps, \"animation\">;\nexport type ActionSwapRollIconProps = Omit<ActionSwapIconProps, \"animation\">;\n\nexport function ActionSwapRollButton(props: ActionSwapRollButtonProps) {\n  return <ActionSwapButton {...props} animation=\"roll\" />;\n}\n\nexport function ActionSwapRollText(props: ActionSwapRollTextProps) {\n  return <ActionSwapText {...props} animation=\"roll\" />;\n}\n\nexport function ActionSwapRollIcon(props: ActionSwapRollIconProps) {\n  return <ActionSwapIcon {...props} animation=\"roll\" />;\n}\n"
        },
        {
          "path": "components/beui/components/motion/action-swap.tsx",
          "target": "@components/beui/components/motion/action-swap.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion, type HTMLMotionProps, type Variants } from \"motion/react\";\nimport { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { EASE_OUT, SPRING_PRESS, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type ActionSwapItem = {\n  id: string;\n  label: ReactNode;\n  icon?: ReactNode;\n  ariaLabel?: string;\n};\n\nexport type ActionSwapButtonVariant = \"primary\" | \"secondary\" | \"outline\" | \"ghost\";\nexport type ActionSwapButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\";\nexport type ActionSwapAnimation = \"blur\" | \"roll\" | \"cascade\";\n\n/** Animations with a single-element variant set (cascade animates per letter). */\ntype CoreAnimation = \"blur\" | \"roll\";\n\nexport interface ActionSwapButtonProps extends Omit<\n  HTMLMotionProps<\"button\">,\n  \"children\" | \"onChange\"\n> {\n  items: ActionSwapItem[];\n  value?: string;\n  defaultValue?: string;\n  onValueChange?: (value: string, item: ActionSwapItem) => void;\n  variant?: ActionSwapButtonVariant;\n  size?: ActionSwapButtonSize;\n  animation?: ActionSwapAnimation;\n  iconOnly?: boolean;\n  cycle?: boolean;\n}\n\nexport interface ActionSwapTextProps {\n  value: string;\n  children: ReactNode;\n  animation?: ActionSwapAnimation;\n  className?: string;\n}\n\nexport interface ActionSwapIconProps {\n  value: string;\n  children: ReactNode;\n  animation?: ActionSwapAnimation;\n  className?: string;\n}\n\nconst BLUR_TRANSITION = { duration: 0.2, ease: \"easeInOut\" } as const;\nconst ROLL_TRANSITION = SPRING_SWAP;\nconst ROLL_EXIT_TRANSITION = { duration: 0.14, ease: EASE_OUT } as const;\nconst SWAP_BLUR = \"blur(8px)\";\nconst ROLL_BLUR = \"blur(3px)\";\n\n// Cascade rolls the label one letter at a time, left to right. The leaving\n// and landing strings overlap as independent layers (no shared cells), so\n// proportional glyph widths never jitter. Exits cascade at half the enter\n// stagger so the tail of the old label lingers briefly.\nconst CASCADE_STAGGER = 0.025;\n\nconst CASCADE_LETTER_VARIANTS: Variants = {\n  initial: { opacity: 0, y: \"105%\", filter: ROLL_BLUR },\n  animate: (delay: number = 0) => ({\n    opacity: 1,\n    y: \"0%\",\n    filter: \"blur(0px)\",\n    transition: { ...SPRING_SWAP, delay },\n  }),\n  exit: (delay: number = 0) => ({\n    opacity: 0,\n    y: \"-105%\",\n    filter: ROLL_BLUR,\n    transition: { duration: 0.16, ease: EASE_OUT, delay: delay * 0.5 },\n  }),\n};\n\nconst TEXT_VARIANTS: Record<CoreAnimation, Variants> = {\n  blur: {\n    initial: { opacity: 0, scale: 0.94, filter: SWAP_BLUR },\n    animate: {\n      opacity: 1,\n      scale: 1,\n      filter: \"blur(0px)\",\n      transition: BLUR_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      scale: 0.94,\n      filter: SWAP_BLUR,\n      transition: BLUR_TRANSITION,\n    },\n  },\n  roll: {\n    initial: { opacity: 0, y: \"90%\", filter: ROLL_BLUR },\n    animate: {\n      opacity: 1,\n      y: \"0%\",\n      filter: \"blur(0px)\",\n      transition: ROLL_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      y: \"-90%\",\n      filter: ROLL_BLUR,\n      transition: ROLL_EXIT_TRANSITION,\n    },\n  },\n};\n\nconst ICON_VARIANTS: Record<CoreAnimation, Variants> = {\n  blur: {\n    initial: { opacity: 0, scale: 0.25, filter: SWAP_BLUR },\n    animate: {\n      opacity: 1,\n      scale: 1,\n      filter: \"blur(0px)\",\n      transition: BLUR_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      scale: 0.25,\n      filter: SWAP_BLUR,\n      transition: BLUR_TRANSITION,\n    },\n  },\n  roll: {\n    initial: { opacity: 0, y: 12, filter: ROLL_BLUR },\n    animate: {\n      opacity: 1,\n      y: 0,\n      filter: \"blur(0px)\",\n      transition: ROLL_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      y: -12,\n      filter: ROLL_BLUR,\n      transition: ROLL_EXIT_TRANSITION,\n    },\n  },\n};\n\nconst VARIANT_CLASS: Record<ActionSwapButtonVariant, string> = {\n  primary: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n  secondary: \"border border-border bg-card text-foreground hover:border-border\",\n  outline: \"border border-border bg-transparent text-foreground hover:bg-primary/5\",\n  ghost: \"text-muted-foreground hover:bg-primary/5 hover:text-foreground\",\n};\n\nconst SIZE_CLASS: Record<ActionSwapButtonSize, string> = {\n  sm: \"h-8 gap-1.5 rounded-full px-3 text-xs\",\n  md: \"h-10 gap-2 rounded-full px-4 text-sm\",\n  lg: \"h-12 gap-2.5 rounded-full px-5 text-base\",\n  icon: \"h-10 w-10 rounded-full\",\n};\n\nexport function ActionSwapText({\n  value,\n  children,\n  animation = \"blur\",\n  className,\n}: ActionSwapTextProps) {\n  const reduce = useReducedMotion();\n\n  // Cascade needs a plain string to split into letters; non-string content\n  // and reduced motion fall back to the closest single-element animation.\n  const label = typeof children === \"string\" ? children : null;\n  const cascade = animation === \"cascade\" && label !== null && !reduce;\n  const coreAnimation: CoreAnimation =\n    animation === \"cascade\" ? \"roll\" : animation;\n\n  return (\n    <span\n      className={cn(\n        \"relative -my-[0.08em] inline-block max-w-full whitespace-nowrap py-[0.08em] align-bottom\",\n        className,\n      )}\n      style={{\n        clipPath: \"inset(0 -999px)\",\n        WebkitClipPath: \"inset(0 -999px)\",\n      }}\n    >\n      <span\n        aria-hidden\n        className=\"invisible inline-block whitespace-nowrap\"\n      >\n        {cascade\n          ? label.split(\"\").map((char, index) => (\n              <span\n                // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity.\n                key={index}\n                className=\"inline-block whitespace-pre\"\n              >\n                {char}\n              </span>\n            ))\n          : children}\n      </span>\n      {cascade ? (\n        <>\n          {/* Letters are decorative fragments; readers get the whole label. */}\n          <span className=\"sr-only\">{label}</span>\n          <AnimatePresence initial={false}>\n            <motion.span\n              key={`cascade-${value}`}\n              aria-hidden\n              initial=\"initial\"\n              animate=\"animate\"\n              exit=\"exit\"\n              className=\"absolute left-0 top-[0.08em] inline-block whitespace-pre\"\n            >\n              {label.split(\"\").map((char, i) => (\n                <motion.span\n                  // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity — the letter at a position is exactly what rolls.\n                  key={i}\n                  custom={i * CASCADE_STAGGER}\n                  variants={CASCADE_LETTER_VARIANTS}\n                  className=\"inline-block whitespace-pre will-change-[opacity,filter,transform]\"\n                >\n                  {char}\n                </motion.span>\n              ))}\n            </motion.span>\n          </AnimatePresence>\n        </>\n      ) : (\n        <AnimatePresence initial={false}>\n          <motion.span\n            key={`${animation}-${value}`}\n            variants={TEXT_VARIANTS[coreAnimation]}\n            initial={reduce ? false : \"initial\"}\n            animate={reduce ? { opacity: 1, filter: \"blur(0px)\", scale: 1, y: 0 } : \"animate\"}\n            exit={reduce ? undefined : \"exit\"}\n            // Truncation lives on the layer that holds the text — the layer\n            // moves as a whole, so clipping it never eats the roll.\n            className=\"absolute left-0 top-[0.08em] inline-block max-w-full truncate will-change-[opacity,filter,transform]\"\n          >\n            {children}\n          </motion.span>\n        </AnimatePresence>\n      )}\n    </span>\n  );\n}\n\nexport function ActionSwapIcon({\n  value,\n  children,\n  animation = \"blur\",\n  className,\n}: ActionSwapIconProps) {\n  const reduce = useReducedMotion();\n  // Icons are single elements — cascade maps to its closest motion, roll.\n  const coreAnimation: CoreAnimation =\n    animation === \"cascade\" ? \"roll\" : animation;\n\n  return (\n    <span className={cn(\"relative inline-grid shrink-0 place-items-center overflow-hidden\", className)}>\n      <AnimatePresence mode=\"popLayout\" initial={false}>\n        <motion.span\n          key={`${animation}-${value}`}\n          aria-hidden\n          variants={ICON_VARIANTS[coreAnimation]}\n          initial={reduce ? false : \"initial\"}\n          animate={reduce ? { opacity: 1, filter: \"blur(0px)\", scale: 1, y: 0 } : \"animate\"}\n          exit={reduce ? undefined : \"exit\"}\n          className=\"col-start-1 row-start-1 inline-flex items-center justify-center will-change-[opacity,filter,transform]\"\n        >\n          {children}\n        </motion.span>\n      </AnimatePresence>\n    </span>\n  );\n}\n\nexport function ActionSwapButton({\n  items,\n  value,\n  defaultValue,\n  onValueChange,\n  variant = \"secondary\",\n  size = \"md\",\n  animation = \"blur\",\n  iconOnly = size === \"icon\",\n  cycle = true,\n  className,\n  disabled,\n  onClick,\n  ...rest\n}: ActionSwapButtonProps) {\n  const reduce = useReducedMotion();\n  const [internalValue, setInternalValue] = useState(defaultValue ?? items[0]?.id);\n  const currentValue = value ?? internalValue;\n  const activeIndex = Math.max(0, items.findIndex((item) => item.id === currentValue));\n  const activeItem = items[activeIndex] ?? items[0];\n  const hasIcon = items.some((item) => item.icon);\n  const nextItem = cycle && items.length > 0 ? items[(activeIndex + 1) % items.length] : undefined;\n\n  if (!activeItem) return null;\n\n  const accessibleLabel = activeItem.ariaLabel ?? (iconOnly && typeof activeItem.label === \"string\" ? activeItem.label : undefined);\n\n  return (\n    <motion.button\n      type=\"button\"\n      disabled={disabled}\n      whileTap={reduce || disabled ? undefined : { scale: 0.97 }}\n      transition={SPRING_PRESS}\n      className={cn(\n        \"inline-flex items-center justify-center overflow-hidden font-medium transition-colors\",\n        \"disabled:pointer-events-none disabled:opacity-50\",\n        VARIANT_CLASS[variant],\n        SIZE_CLASS[size],\n        className,\n      )}\n      aria-label={accessibleLabel}\n      onClick={(event) => {\n        onClick?.(event);\n        if (event.defaultPrevented || disabled || !cycle || !nextItem) return;\n        if (value === undefined) setInternalValue(nextItem.id);\n        onValueChange?.(nextItem.id, nextItem);\n      }}\n      {...rest}\n    >\n      {hasIcon ? (\n        <ActionSwapIcon value={activeItem.id} animation={animation} className=\"h-4 w-4\">\n          {activeItem.icon ?? null}\n        </ActionSwapIcon>\n      ) : null}\n      {!iconOnly ? (\n        <ActionSwapText value={activeItem.id} animation={animation}>\n          {activeItem.label}\n        </ActionSwapText>\n      ) : null}\n    </motion.button>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-disclosure.tsx",
          "target": "@components/beui/components/agents/agent-disclosure.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, type HTMLMotionProps, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface AgentDisclosureProps\n  extends Omit<HTMLMotionProps<\"div\">, \"animate\" | \"initial\"> {\n  open: boolean;\n  openHeight?: CSSProperties[\"height\"];\n}\n\n/** Shared transform-only reveal for collapsible agent content. */\nexport function AgentDisclosure({\n  open,\n  openHeight = \"auto\",\n  className,\n  style,\n  transition,\n  ...props\n}: AgentDisclosureProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.div\n      {...props}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        reduce\n          ? { opacity: open ? 1 : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              clipPath: open ? \"inset(0 0 0% 0)\" : \"inset(0 0 100% 0)\",\n              y: open ? 0 : -4,\n            }\n      }\n      transition={\n        transition ?? {\n          duration: reduce ? 0 : open ? 0.22 : 0.14,\n          ease: EASE_OUT,\n        }\n      }\n      className={cn(\"overflow-hidden\", className)}\n      style={{\n        ...style,\n        height: open ? openHeight : 0,\n        pointerEvents: open ? undefined : \"none\",\n        transformOrigin: \"top\",\n      }}\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-code-block",
      "type": "registry:block",
      "title": "Beui Code Block",
      "description": "Code Block",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/code-block.tsx",
          "target": "@components/beui/components/agents/code-block.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Check, Copy, FileCode2, LoaderCircle } from \"lucide-react\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useEffect,\n  useLayoutEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  type AgentCodeLanguage,\n  AgentCodeLine,\n  useAgentCodeTokens,\n} from \"@/components/beui/components/agents/agent-code\";\nimport { SPRING_PRESS } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type CodeBlockStatus = \"streaming\" | \"complete\";\n\nexport interface CodeBlockProps {\n  code: string;\n  language?: AgentCodeLanguage;\n  filename?: ReactNode;\n  status?: CodeBlockStatus;\n  showLineNumbers?: boolean;\n  highlightLines?: number[];\n  maxHeight?: number;\n  wrap?: boolean;\n  copyable?: boolean;\n  onCopy?: () => void | Promise<void>;\n  className?: string;\n}\n\nexport function CodeBlock({\n  code,\n  language = \"typescript\",\n  filename,\n  status = \"complete\",\n  showLineNumbers = true,\n  highlightLines = [],\n  maxHeight = 280,\n  wrap = false,\n  copyable = true,\n  onCopy,\n  className,\n}: CodeBlockProps) {\n  const reduce = useReducedMotion() ?? false;\n  const viewportRef = useRef<HTMLDivElement>(null);\n  const copyTimer = useRef<number | undefined>(undefined);\n  const [copied, setCopied] = useState(false);\n  const streaming = status === \"streaming\";\n  const tokens = useAgentCodeTokens(code, language);\n  const highlighted = useMemo(\n    () => new Set(highlightLines),\n    [highlightLines],\n  );\n  let offset = 0;\n  const lines = code.split(\"\\n\").map((content) => {\n    const line = { content, offset };\n    offset += content.length + 1;\n    return line;\n  });\n\n  useEffect(\n    () => () => {\n      if (copyTimer.current) window.clearTimeout(copyTimer.current);\n    },\n    [],\n  );\n\n  useLayoutEffect(() => {\n    const viewport = viewportRef.current;\n    if (!viewport || !streaming) return;\n\n    const frame = requestAnimationFrame(() => {\n      if (viewport.scrollHeight <= viewport.clientHeight) return;\n      if (typeof viewport.scrollTo === \"function\") {\n        viewport.scrollTo({\n          top: viewport.scrollHeight,\n          behavior: reduce ? \"auto\" : \"smooth\",\n        });\n      } else {\n        viewport.scrollTop = viewport.scrollHeight;\n      }\n    });\n    return () => cancelAnimationFrame(frame);\n  });\n\n  const handleCopy = useCallback(async () => {\n    if (onCopy) await onCopy();\n    else await navigator.clipboard?.writeText(code);\n\n    setCopied(true);\n    if (copyTimer.current) window.clearTimeout(copyTimer.current);\n    copyTimer.current = window.setTimeout(() => setCopied(false), 1600);\n  }, [code, onCopy]);\n\n  return (\n    <div\n      data-state={status}\n      aria-busy={streaming}\n      className={cn(\n        \"w-full overflow-hidden rounded-lg bg-muted/80 text-sm\",\n        className,\n      )}\n    >\n      <div className=\"flex h-10 items-center gap-2.5 px-3\">\n        <FileCode2\n          aria-hidden=\"true\"\n          className=\"size-3.5 shrink-0 text-muted-foreground/70\"\n        />\n        {filename ? (\n          <span className=\"min-w-0 truncate font-mono text-xs text-foreground/80\">\n            {filename}\n          </span>\n        ) : null}\n        <span className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground/55\">\n          {language}\n        </span>\n        <span\n          className={cn(\n            \"ml-auto inline-flex shrink-0 items-center gap-1 text-[10px] font-medium\",\n            streaming\n              ? \"text-blue-600 dark:text-blue-400\"\n              : \"text-emerald-600 dark:text-emerald-400\",\n          )}\n        >\n          {streaming ? (\n            <LoaderCircle className={cn(\"size-3\", !reduce && \"animate-spin\")} />\n          ) : (\n            <Check className=\"size-3\" />\n          )}\n          {streaming ? \"Writing\" : \"Ready\"}\n        </span>\n        {copyable || onCopy ? (\n          <motion.button\n            type=\"button\"\n            aria-label={copied ? \"Copied\" : \"Copy code\"}\n            title={copied ? \"Copied\" : \"Copy code\"}\n            onClick={handleCopy}\n            whileTap={reduce ? undefined : { scale: 0.9 }}\n            transition={SPRING_PRESS}\n            className=\"grid size-7 shrink-0 place-items-center rounded-md text-muted-foreground outline-none transition-colors hover:bg-background/70 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n          >\n            {copied ? (\n              <Check className=\"size-3.5\" />\n            ) : (\n              <Copy className=\"size-3.5\" />\n            )}\n          </motion.button>\n        ) : null}\n      </div>\n\n      <div\n        ref={viewportRef}\n        role={streaming ? \"log\" : undefined}\n        aria-live={streaming ? \"polite\" : undefined}\n        className=\"scrollbar-hide overflow-auto border-t border-foreground/[0.06] py-2\"\n        style={{ maxHeight }}\n      >\n        <pre className=\"m-0 min-w-max font-mono text-xs leading-5 text-foreground/85\">\n          <code>\n            {lines.map((line, index) => {\n              const lineNumber = index + 1;\n              return (\n                <span\n                  key={line.offset}\n                  className={cn(\n                    \"grid min-h-5\",\n                    showLineNumbers\n                      ? \"grid-cols-[2.75rem_minmax(0,1fr)]\"\n                      : \"grid-cols-1\",\n                    highlighted.has(lineNumber) && \"bg-blue-500/[0.07]\",\n                  )}\n                >\n                  {showLineNumbers ? (\n                    <span className=\"select-none pr-3 text-right tabular-nums text-muted-foreground/35\">\n                      {lineNumber}\n                    </span>\n                  ) : null}\n                  <AgentCodeLine\n                    code={line.content}\n                    tokens={tokens?.[index]}\n                    className={cn(\n                      \"pr-4\",\n                      showLineNumbers ? \"pl-1\" : \"pl-4\",\n                      wrap ? \"whitespace-pre-wrap break-words\" : \"whitespace-pre\",\n                    )}\n                  />\n                </span>\n              );\n            })}\n          </code>\n        </pre>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-code.tsx",
          "target": "@components/beui/components/agents/agent-code.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  type CSSProperties,\n  Fragment,\n  useEffect,\n  useState,\n} from \"react\";\nimport { createHighlighter, type Highlighter } from \"shiki\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type AgentCodeLanguage =\n  | \"bash\"\n  | \"diff\"\n  | \"json\"\n  | \"text\"\n  | \"tsx\"\n  | \"typescript\";\n\nexport interface AgentCodeToken {\n  content: string;\n  offset: number;\n  light?: string;\n  dark?: string;\n}\n\nexport type AgentCodeTokenLines = AgentCodeToken[][];\n\nexport interface AgentCodeProps {\n  code: string;\n  language?: AgentCodeLanguage;\n  className?: string;\n}\n\nexport interface AgentCodeLineProps {\n  code: string;\n  tokens?: AgentCodeToken[];\n  className?: string;\n}\n\nconst LIGHT_THEME = \"github-light-high-contrast\";\nconst DARK_THEME = \"github-dark-high-contrast\";\nlet agentCodeHighlighter: Promise<Highlighter> | null = null;\nconst tokenCache = new Map<string, AgentCodeTokenLines>();\n\nfunction getAgentCodeHighlighter() {\n  if (!agentCodeHighlighter) {\n    agentCodeHighlighter = createHighlighter({\n      themes: [LIGHT_THEME, DARK_THEME],\n      langs: [\"bash\", \"diff\", \"json\", \"tsx\", \"typescript\"],\n    });\n  }\n  return agentCodeHighlighter;\n}\n\nfunction tokenCacheKey(code: string, language: AgentCodeLanguage) {\n  return `${language}\\u0000${code}`;\n}\n\nexport function useAgentCodeTokens(\n  code: string,\n  language: AgentCodeLanguage,\n) {\n  const key = tokenCacheKey(code, language);\n  const cached = tokenCache.get(key);\n  const [result, setResult] = useState<{\n    key: string;\n    code: string;\n    language: AgentCodeLanguage;\n    lines: AgentCodeTokenLines;\n  } | null>(cached ? { key, code, language, lines: cached } : null);\n\n  useEffect(() => {\n    const current = tokenCache.get(key);\n    if (current) {\n      setResult({ key, code, language, lines: current });\n      return;\n    }\n\n    let cancelled = false;\n    getAgentCodeHighlighter().then((highlighter) => {\n      if (cancelled) return;\n      const lines = highlighter\n        .codeToTokensWithThemes(code, {\n          lang: language,\n          themes: {\n            light: LIGHT_THEME,\n            dark: DARK_THEME,\n          },\n        })\n        .map((line) =>\n          line.map((token) => ({\n            content: token.content,\n            offset: token.offset,\n            light: token.variants.light?.color,\n            dark: token.variants.dark?.color,\n          })),\n      );\n      tokenCache.set(key, lines);\n      setResult({ key, code, language, lines });\n    });\n    return () => {\n      cancelled = true;\n    };\n  }, [code, key, language]);\n\n  if (result?.key === key) return result.lines;\n  if (result?.language === language && code.startsWith(result.code)) {\n    return result.lines;\n  }\n  return null;\n}\n\nexport function AgentCodeLine({\n  code,\n  tokens,\n  className,\n}: AgentCodeLineProps) {\n  return (\n    <span className={className}>\n      {tokens\n        ? tokens.map((token) => (\n            <span\n              key={`${token.offset}-${token.content}`}\n              style={\n                {\n                  \"--agent-code-light\": token.light ?? \"currentColor\",\n                  \"--agent-code-dark\": token.dark ?? token.light ?? \"currentColor\",\n                } as CSSProperties\n              }\n              className=\"text-[var(--agent-code-light)] dark:text-[var(--agent-code-dark)]\"\n            >\n              {token.content}\n            </span>\n          ))\n        : code}\n    </span>\n  );\n}\n\nexport function AgentCode({\n  code,\n  language = \"bash\",\n  className,\n}: AgentCodeProps) {\n  const tokens = useAgentCodeTokens(code, language);\n  let offset = 0;\n  const lines = code.split(\"\\n\").map((content) => {\n    const line = { content, offset };\n    offset += content.length + 1;\n    return line;\n  });\n\n  return (\n    <pre\n      className={cn(\n        \"m-0 overflow-x-auto whitespace-pre font-mono text-xs leading-5 text-foreground/85\",\n        className,\n      )}\n    >\n      <code>\n        {lines.map((line, index) => (\n          <Fragment key={line.offset}>\n            <AgentCodeLine code={line.content} tokens={tokens?.[index]} />\n            {index < lines.length - 1 ? \"\\n\" : null}\n          </Fragment>\n        ))}\n      </code>\n    </pre>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-approval-card",
      "type": "registry:block",
      "title": "Beui Approval Card",
      "description": "Approval Card",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/approval-card/index.tsx",
          "target": "@components/beui/components/agents/approval-card/index.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  ArrowLeft,\n  ArrowRight,\n  Check,\n  CircleHelp,\n  LoaderCircle,\n  MessageSquareText,\n  X,\n} from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport { ActionSwapRollText } from \"@/components/beui/components/motion/action-swap-roll\";\nimport { Button } from \"@/components/beui/components/motion/button\";\nimport { Checkbox } from \"@/components/beui/components/motion/checkbox\";\nimport { Input } from \"@/components/beui/components/motion/input\";\nimport { RadioGroup, RadioGroupItem } from \"@/components/beui/components/motion/radio\";\nimport { EASE_OUT, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport type {\n  ApprovalCardAnswer,\n  ApprovalCardAnswers,\n  ApprovalCardProps,\n  ApprovalCardQuestion,\n  ApprovalCardStatus,\n} from \"./types\";\n\nexport type {\n  ApprovalCardAnswer,\n  ApprovalCardAnswers,\n  ApprovalCardOption,\n  ApprovalCardProps,\n  ApprovalCardQuestion,\n  ApprovalCardStatus,\n} from \"./types\";\n\nconst EMPTY_ANSWER: ApprovalCardAnswer = { selected: [], custom: \"\" };\n\nfunction getStatusLabel(status: ApprovalCardStatus) {\n  if (status === \"submitting\") return \"Submitting\";\n  if (status === \"approved\") return \"Approved\";\n  if (status === \"rejected\") return \"Rejected\";\n  if (status === \"changes-requested\") return \"Changes requested\";\n  if (status === \"answered\") return \"Response submitted\";\n  return \"Input required\";\n}\n\nfunction getStatusClass(status: ApprovalCardStatus) {\n  if (status === \"approved\" || status === \"answered\") {\n    return \"text-emerald-600 dark:text-emerald-400\";\n  }\n  if (status === \"rejected\") return \"text-rose-600 dark:text-rose-400\";\n  if (status === \"changes-requested\") {\n    return \"text-amber-600 dark:text-amber-400\";\n  }\n  return \"text-muted-foreground\";\n}\n\nfunction getStatusBadgeClass(status: ApprovalCardStatus) {\n  if (status === \"pending\" || status === \"changes-requested\") {\n    return \"border-amber-500/30 bg-amber-500/10 text-amber-600 dark:text-amber-400\";\n  }\n  if (status === \"submitting\") {\n    return \"border-blue-500/30 bg-blue-500/10 text-blue-600 dark:text-blue-400\";\n  }\n  if (status === \"approved\" || status === \"answered\") {\n    return \"border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400\";\n  }\n  return \"border-rose-500/30 bg-rose-500/10 text-rose-600 dark:text-rose-400\";\n}\n\nfunction isAnswered(answer: ApprovalCardAnswer) {\n  return answer.selected.length > 0 || Boolean(answer.custom?.trim());\n}\n\nfunction QuestionOptions({\n  question,\n  answer,\n  disabled,\n  onChange,\n  onSingleSelect,\n}: {\n  question: ApprovalCardQuestion;\n  answer: ApprovalCardAnswer;\n  disabled: boolean;\n  onChange: (answer: ApprovalCardAnswer) => void;\n  onSingleSelect?: () => void;\n}) {\n  const custom = answer.custom ?? \"\";\n\n  return (\n    <div className=\"mt-3\">\n      {question.options?.length ? (\n        question.multiple ? (\n          <div className=\"grid gap-0.5\">\n            {question.options.map((option) => (\n              <Checkbox\n                key={option.value}\n                checked={answer.selected.includes(option.value)}\n                disabled={disabled || option.disabled}\n                label={option.label}\n                onCheckedChange={(checked) =>\n                  onChange({\n                    ...answer,\n                    selected: checked\n                      ? [...answer.selected, option.value]\n                      : answer.selected.filter((value) => value !== option.value),\n                  })\n                }\n                className=\"min-h-9 rounded-lg px-1.5 py-1\"\n              />\n            ))}\n          </div>\n        ) : (\n          <RadioGroup\n            value={answer.selected[0] ?? \"\"}\n            onValueChange={(value) => {\n              onChange({ selected: [value], custom: \"\" });\n              onSingleSelect?.();\n            }}\n            className=\"gap-0.5\"\n          >\n            {question.options.map((option) => (\n              <RadioGroupItem\n                key={option.value}\n                value={option.value}\n                label={option.label}\n                disabled={disabled || option.disabled}\n                className=\"min-h-9 rounded-lg px-1.5 py-1\"\n              />\n            ))}\n          </RadioGroup>\n        )\n      ) : null}\n\n      {question.allowCustom ? (\n        <Input\n          value={custom}\n          disabled={disabled}\n          placeholder={question.customPlaceholder ?? \"Add another response…\"}\n          onChange={(value) =>\n            onChange({\n              selected: question.multiple ? answer.selected : [],\n              custom: value,\n            })\n          }\n          className={cn(\"p-0.5\", question.options?.length && \"mt-1.5\")}\n          classNames={{\n            field:\n              \"h-10 rounded-md border-0 bg-background/70 focus-within:bg-background\",\n            input: \"px-3 text-sm\",\n          }}\n        />\n      ) : null}\n    </div>\n  );\n}\n\nfunction ProgressDots({ current, ids }: { current: number; ids: string[] }) {\n  return (\n    <span className=\"flex gap-1.5\">\n      <span className=\"sr-only\">\n        Question {current + 1} of {ids.length}\n      </span>\n      {ids.map((id, index) => (\n        <motion.span\n          key={id}\n          aria-hidden=\"true\"\n          initial={{\n            scale: index === current ? 1 : 0.75,\n            opacity: index <= current ? 1 : 0.35,\n          }}\n          animate={{\n            scale: index === current ? 1 : 0.75,\n            opacity: index <= current ? 1 : 0.35,\n          }}\n          transition={SPRING_SWAP}\n          className=\"size-1.5 rounded-full bg-foreground\"\n        />\n      ))}\n    </span>\n  );\n}\n\nexport function ApprovalCard({\n  title = \"Approval required\",\n  description,\n  children,\n  questions = [],\n  status = \"pending\",\n  answers,\n  defaultAnswers = {},\n  onAnswersChange,\n  step,\n  defaultStep = 0,\n  onStepChange,\n  onSubmit,\n  onApprove,\n  onReject,\n  onRequestChanges,\n  onDismiss,\n  approveLabel = \"Approve\",\n  submitLabel = \"Submit response\",\n  result,\n  className,\n}: ApprovalCardProps) {\n  const reduce = useReducedMotion() ?? false;\n  const [internalAnswers, setInternalAnswers] =\n    useState<ApprovalCardAnswers>(defaultAnswers);\n  const [internalStep, setInternalStep] = useState(defaultStep);\n  const autoAdvanceTimer = useRef<number | undefined>(undefined);\n  const currentAnswers = answers ?? internalAnswers;\n  const currentStep = Math.min(\n    Math.max(0, step ?? internalStep),\n    Math.max(0, questions.length - 1),\n  );\n  const question = questions[currentStep];\n  const questionMode = questions.length > 0;\n  const pending = status === \"pending\";\n  const busy = status === \"submitting\";\n  const interactive = pending || busy;\n  const currentAnswer = question\n    ? (currentAnswers[question.id] ?? EMPTY_ANSWER)\n    : EMPTY_ANSWER;\n  const displayTitle = question?.title ?? title;\n  const titleKey = question?.id ?? String(status);\n  const statusLabel = getStatusLabel(status);\n\n  const clearAutoAdvance = useCallback(() => {\n    if (autoAdvanceTimer.current === undefined) return;\n    window.clearTimeout(autoAdvanceTimer.current);\n    autoAdvanceTimer.current = undefined;\n  }, []);\n\n  useEffect(() => clearAutoAdvance, [clearAutoAdvance]);\n\n  const setAnswers = useCallback(\n    (next: ApprovalCardAnswers) => {\n      if (answers === undefined) setInternalAnswers(next);\n      onAnswersChange?.(next);\n    },\n    [answers, onAnswersChange],\n  );\n\n  const setStep = (next: number) => {\n    clearAutoAdvance();\n    if (step === undefined) setInternalStep(next);\n    onStepChange?.(next);\n  };\n\n  const updateCurrentAnswer = (next: ApprovalCardAnswer) => {\n    if (!question) return;\n    setAnswers({ ...currentAnswers, [question.id]: next });\n  };\n\n  const continueQuestion = () => {\n    if (currentStep < questions.length - 1) {\n      setStep(currentStep + 1);\n      return;\n    }\n    onSubmit?.(currentAnswers);\n  };\n\n  const queueAutoAdvance = () => {\n    if (\n      !question ||\n      question.multiple ||\n      question.autoAdvance === false ||\n      currentStep >= questions.length - 1 ||\n      busy\n    ) {\n      return;\n    }\n\n    clearAutoAdvance();\n    autoAdvanceTimer.current = window.setTimeout(() => {\n      setStep(currentStep + 1);\n    }, 240);\n  };\n\n  return (\n    <div\n      data-state={status}\n      aria-busy={busy}\n      className={cn(\n        \"w-full overflow-hidden rounded-lg bg-muted p-4 text-sm\",\n        className,\n      )}\n    >\n      <div className=\"flex items-start gap-3\">\n        <span\n          aria-hidden=\"true\"\n          className={cn(\n            \"grid size-5 shrink-0 place-items-center text-muted-foreground\",\n            getStatusClass(status),\n          )}\n        >\n          {busy ? (\n            <LoaderCircle className={cn(\"size-4\", !reduce && \"animate-spin\")} />\n          ) : interactive ? (\n            questionMode ? (\n              <CircleHelp className=\"size-4\" />\n            ) : (\n              <MessageSquareText className=\"size-4\" />\n            )\n          ) : status === \"rejected\" ? (\n            <X className=\"size-4\" />\n          ) : (\n            <Check className=\"size-4\" />\n          )}\n        </span>\n\n        <div className=\"min-w-0 flex-1\">\n          <div className=\"flex min-w-0 items-start gap-3\">\n            <h3 className=\"min-w-0 flex-1 text-sm font-medium leading-5 text-foreground\">\n              <ActionSwapRollText value={titleKey}>\n                {displayTitle}\n              </ActionSwapRollText>\n            </h3>\n            {questionMode && interactive ? (\n              <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground/65\">\n                {currentStep + 1}/{questions.length}\n              </span>\n            ) : (\n              <span\n                className={cn(\n                  \"shrink-0 rounded-full border px-2 py-0.5 text-[11px] font-medium transition-colors\",\n                  getStatusBadgeClass(status),\n                )}\n              >\n                {statusLabel}\n              </span>\n            )}\n            {onDismiss ? (\n              <button\n                type=\"button\"\n                aria-label=\"Dismiss\"\n                onClick={onDismiss}\n                className=\"grid size-5 shrink-0 place-items-center rounded-full text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n              >\n                <X className=\"size-4\" />\n              </button>\n            ) : null}\n          </div>\n\n          <AgentDisclosure open={interactive}>\n            {questionMode && question ? (\n              <AnimatePresence initial={false} mode=\"wait\">\n                <motion.div\n                  key={question.id}\n                  initial={reduce ? { opacity: 1 } : { opacity: 0, x: 8 }}\n                  animate={{ opacity: 1, x: 0 }}\n                  exit={reduce ? { opacity: 0 } : { opacity: 0, x: -6 }}\n                  transition={{ duration: reduce ? 0 : 0.2, ease: EASE_OUT }}\n                >\n                  {question.description ? (\n                    <p className=\"mt-1 leading-5 text-muted-foreground\">\n                      {question.description}\n                    </p>\n                  ) : null}\n                  <QuestionOptions\n                    question={question}\n                    answer={currentAnswer}\n                    disabled={busy}\n                    onChange={updateCurrentAnswer}\n                    onSingleSelect={queueAutoAdvance}\n                  />\n                </motion.div>\n              </AnimatePresence>\n            ) : (\n              <div>\n                {description ? (\n                  <p className=\"mt-1 leading-5 text-muted-foreground\">\n                    {description}\n                  </p>\n                ) : null}\n                {children ? <div className=\"mt-3\">{children}</div> : null}\n              </div>\n            )}\n\n            {questionMode ? (\n              <div className=\"mt-4 flex items-center gap-3\">\n                <Button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  aria-label=\"Previous question\"\n                  disabled={busy || currentStep === 0}\n                  onClick={() => setStep(currentStep - 1)}\n                >\n                  <ArrowLeft className=\"size-4\" />\n                </Button>\n                <ProgressDots\n                  current={currentStep}\n                  ids={questions.map((item) => item.id)}\n                />\n                <Button\n                  size={currentStep === questions.length - 1 ? \"sm\" : \"icon\"}\n                  aria-label={\n                    currentStep === questions.length - 1\n                      ? \"Submit response\"\n                      : \"Next question\"\n                  }\n                  disabled={busy || !isAnswered(currentAnswer)}\n                  onClick={continueQuestion}\n                  className=\"ml-auto\"\n                >\n                  {busy ? (\n                    <LoaderCircle className={cn(\"size-4\", !reduce && \"animate-spin\")} />\n                  ) : currentStep === questions.length - 1 ? (\n                    <>\n                      {submitLabel}\n                      <ArrowRight className=\"size-3.5\" />\n                    </>\n                  ) : (\n                    <ArrowRight className=\"size-4\" />\n                  )}\n                </Button>\n              </div>\n            ) : (\n              <div className=\"mt-4 flex flex-wrap items-center gap-2\">\n                <Button\n                  size=\"sm\"\n                  disabled={busy}\n                  onClick={onApprove}\n                >\n                  {approveLabel}\n                </Button>\n                {onRequestChanges ? (\n                  <Button\n                    variant=\"secondary\"\n                    size=\"sm\"\n                    disabled={busy}\n                    onClick={onRequestChanges}\n                  >\n                    Request changes\n                  </Button>\n                ) : null}\n                {onReject ? (\n                  <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    disabled={busy}\n                    onClick={onReject}\n                    className=\"text-muted-foreground hover:text-rose-600 dark:hover:text-rose-400\"\n                  >\n                    Reject\n                  </Button>\n                ) : null}\n              </div>\n            )}\n          </AgentDisclosure>\n\n          {!interactive ? (\n            <p className=\"mt-1 text-sm text-muted-foreground\">\n              {result ?? statusLabel}\n            </p>\n          ) : null}\n        </div>\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-disclosure.tsx",
          "target": "@components/beui/components/agents/agent-disclosure.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, type HTMLMotionProps, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface AgentDisclosureProps\n  extends Omit<HTMLMotionProps<\"div\">, \"animate\" | \"initial\"> {\n  open: boolean;\n  openHeight?: CSSProperties[\"height\"];\n}\n\n/** Shared transform-only reveal for collapsible agent content. */\nexport function AgentDisclosure({\n  open,\n  openHeight = \"auto\",\n  className,\n  style,\n  transition,\n  ...props\n}: AgentDisclosureProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.div\n      {...props}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        reduce\n          ? { opacity: open ? 1 : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              clipPath: open ? \"inset(0 0 0% 0)\" : \"inset(0 0 100% 0)\",\n              y: open ? 0 : -4,\n            }\n      }\n      transition={\n        transition ?? {\n          duration: reduce ? 0 : open ? 0.22 : 0.14,\n          ease: EASE_OUT,\n        }\n      }\n      className={cn(\"overflow-hidden\", className)}\n      style={{\n        ...style,\n        height: open ? openHeight : 0,\n        pointerEvents: open ? undefined : \"none\",\n        transformOrigin: \"top\",\n      }}\n    />\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/motion/action-swap-roll.tsx",
          "target": "@components/beui/components/motion/action-swap-roll.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  ActionSwapButton,\n  ActionSwapIcon,\n  ActionSwapText,\n  type ActionSwapButtonProps,\n  type ActionSwapIconProps,\n  type ActionSwapTextProps,\n} from \"./action-swap\";\n\nexport type {\n  ActionSwapButtonSize,\n  ActionSwapButtonVariant,\n  ActionSwapItem,\n} from \"./action-swap\";\n\nexport type ActionSwapRollButtonProps = Omit<ActionSwapButtonProps, \"animation\">;\nexport type ActionSwapRollTextProps = Omit<ActionSwapTextProps, \"animation\">;\nexport type ActionSwapRollIconProps = Omit<ActionSwapIconProps, \"animation\">;\n\nexport function ActionSwapRollButton(props: ActionSwapRollButtonProps) {\n  return <ActionSwapButton {...props} animation=\"roll\" />;\n}\n\nexport function ActionSwapRollText(props: ActionSwapRollTextProps) {\n  return <ActionSwapText {...props} animation=\"roll\" />;\n}\n\nexport function ActionSwapRollIcon(props: ActionSwapRollIconProps) {\n  return <ActionSwapIcon {...props} animation=\"roll\" />;\n}\n"
        },
        {
          "path": "components/beui/components/motion/action-swap.tsx",
          "target": "@components/beui/components/motion/action-swap.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion, type HTMLMotionProps, type Variants } from \"motion/react\";\nimport { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { EASE_OUT, SPRING_PRESS, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type ActionSwapItem = {\n  id: string;\n  label: ReactNode;\n  icon?: ReactNode;\n  ariaLabel?: string;\n};\n\nexport type ActionSwapButtonVariant = \"primary\" | \"secondary\" | \"outline\" | \"ghost\";\nexport type ActionSwapButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\";\nexport type ActionSwapAnimation = \"blur\" | \"roll\" | \"cascade\";\n\n/** Animations with a single-element variant set (cascade animates per letter). */\ntype CoreAnimation = \"blur\" | \"roll\";\n\nexport interface ActionSwapButtonProps extends Omit<\n  HTMLMotionProps<\"button\">,\n  \"children\" | \"onChange\"\n> {\n  items: ActionSwapItem[];\n  value?: string;\n  defaultValue?: string;\n  onValueChange?: (value: string, item: ActionSwapItem) => void;\n  variant?: ActionSwapButtonVariant;\n  size?: ActionSwapButtonSize;\n  animation?: ActionSwapAnimation;\n  iconOnly?: boolean;\n  cycle?: boolean;\n}\n\nexport interface ActionSwapTextProps {\n  value: string;\n  children: ReactNode;\n  animation?: ActionSwapAnimation;\n  className?: string;\n}\n\nexport interface ActionSwapIconProps {\n  value: string;\n  children: ReactNode;\n  animation?: ActionSwapAnimation;\n  className?: string;\n}\n\nconst BLUR_TRANSITION = { duration: 0.2, ease: \"easeInOut\" } as const;\nconst ROLL_TRANSITION = SPRING_SWAP;\nconst ROLL_EXIT_TRANSITION = { duration: 0.14, ease: EASE_OUT } as const;\nconst SWAP_BLUR = \"blur(8px)\";\nconst ROLL_BLUR = \"blur(3px)\";\n\n// Cascade rolls the label one letter at a time, left to right. The leaving\n// and landing strings overlap as independent layers (no shared cells), so\n// proportional glyph widths never jitter. Exits cascade at half the enter\n// stagger so the tail of the old label lingers briefly.\nconst CASCADE_STAGGER = 0.025;\n\nconst CASCADE_LETTER_VARIANTS: Variants = {\n  initial: { opacity: 0, y: \"105%\", filter: ROLL_BLUR },\n  animate: (delay: number = 0) => ({\n    opacity: 1,\n    y: \"0%\",\n    filter: \"blur(0px)\",\n    transition: { ...SPRING_SWAP, delay },\n  }),\n  exit: (delay: number = 0) => ({\n    opacity: 0,\n    y: \"-105%\",\n    filter: ROLL_BLUR,\n    transition: { duration: 0.16, ease: EASE_OUT, delay: delay * 0.5 },\n  }),\n};\n\nconst TEXT_VARIANTS: Record<CoreAnimation, Variants> = {\n  blur: {\n    initial: { opacity: 0, scale: 0.94, filter: SWAP_BLUR },\n    animate: {\n      opacity: 1,\n      scale: 1,\n      filter: \"blur(0px)\",\n      transition: BLUR_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      scale: 0.94,\n      filter: SWAP_BLUR,\n      transition: BLUR_TRANSITION,\n    },\n  },\n  roll: {\n    initial: { opacity: 0, y: \"90%\", filter: ROLL_BLUR },\n    animate: {\n      opacity: 1,\n      y: \"0%\",\n      filter: \"blur(0px)\",\n      transition: ROLL_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      y: \"-90%\",\n      filter: ROLL_BLUR,\n      transition: ROLL_EXIT_TRANSITION,\n    },\n  },\n};\n\nconst ICON_VARIANTS: Record<CoreAnimation, Variants> = {\n  blur: {\n    initial: { opacity: 0, scale: 0.25, filter: SWAP_BLUR },\n    animate: {\n      opacity: 1,\n      scale: 1,\n      filter: \"blur(0px)\",\n      transition: BLUR_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      scale: 0.25,\n      filter: SWAP_BLUR,\n      transition: BLUR_TRANSITION,\n    },\n  },\n  roll: {\n    initial: { opacity: 0, y: 12, filter: ROLL_BLUR },\n    animate: {\n      opacity: 1,\n      y: 0,\n      filter: \"blur(0px)\",\n      transition: ROLL_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      y: -12,\n      filter: ROLL_BLUR,\n      transition: ROLL_EXIT_TRANSITION,\n    },\n  },\n};\n\nconst VARIANT_CLASS: Record<ActionSwapButtonVariant, string> = {\n  primary: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n  secondary: \"border border-border bg-card text-foreground hover:border-border\",\n  outline: \"border border-border bg-transparent text-foreground hover:bg-primary/5\",\n  ghost: \"text-muted-foreground hover:bg-primary/5 hover:text-foreground\",\n};\n\nconst SIZE_CLASS: Record<ActionSwapButtonSize, string> = {\n  sm: \"h-8 gap-1.5 rounded-full px-3 text-xs\",\n  md: \"h-10 gap-2 rounded-full px-4 text-sm\",\n  lg: \"h-12 gap-2.5 rounded-full px-5 text-base\",\n  icon: \"h-10 w-10 rounded-full\",\n};\n\nexport function ActionSwapText({\n  value,\n  children,\n  animation = \"blur\",\n  className,\n}: ActionSwapTextProps) {\n  const reduce = useReducedMotion();\n\n  // Cascade needs a plain string to split into letters; non-string content\n  // and reduced motion fall back to the closest single-element animation.\n  const label = typeof children === \"string\" ? children : null;\n  const cascade = animation === \"cascade\" && label !== null && !reduce;\n  const coreAnimation: CoreAnimation =\n    animation === \"cascade\" ? \"roll\" : animation;\n\n  return (\n    <span\n      className={cn(\n        \"relative -my-[0.08em] inline-block max-w-full whitespace-nowrap py-[0.08em] align-bottom\",\n        className,\n      )}\n      style={{\n        clipPath: \"inset(0 -999px)\",\n        WebkitClipPath: \"inset(0 -999px)\",\n      }}\n    >\n      <span\n        aria-hidden\n        className=\"invisible inline-block whitespace-nowrap\"\n      >\n        {cascade\n          ? label.split(\"\").map((char, index) => (\n              <span\n                // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity.\n                key={index}\n                className=\"inline-block whitespace-pre\"\n              >\n                {char}\n              </span>\n            ))\n          : children}\n      </span>\n      {cascade ? (\n        <>\n          {/* Letters are decorative fragments; readers get the whole label. */}\n          <span className=\"sr-only\">{label}</span>\n          <AnimatePresence initial={false}>\n            <motion.span\n              key={`cascade-${value}`}\n              aria-hidden\n              initial=\"initial\"\n              animate=\"animate\"\n              exit=\"exit\"\n              className=\"absolute left-0 top-[0.08em] inline-block whitespace-pre\"\n            >\n              {label.split(\"\").map((char, i) => (\n                <motion.span\n                  // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity — the letter at a position is exactly what rolls.\n                  key={i}\n                  custom={i * CASCADE_STAGGER}\n                  variants={CASCADE_LETTER_VARIANTS}\n                  className=\"inline-block whitespace-pre will-change-[opacity,filter,transform]\"\n                >\n                  {char}\n                </motion.span>\n              ))}\n            </motion.span>\n          </AnimatePresence>\n        </>\n      ) : (\n        <AnimatePresence initial={false}>\n          <motion.span\n            key={`${animation}-${value}`}\n            variants={TEXT_VARIANTS[coreAnimation]}\n            initial={reduce ? false : \"initial\"}\n            animate={reduce ? { opacity: 1, filter: \"blur(0px)\", scale: 1, y: 0 } : \"animate\"}\n            exit={reduce ? undefined : \"exit\"}\n            // Truncation lives on the layer that holds the text — the layer\n            // moves as a whole, so clipping it never eats the roll.\n            className=\"absolute left-0 top-[0.08em] inline-block max-w-full truncate will-change-[opacity,filter,transform]\"\n          >\n            {children}\n          </motion.span>\n        </AnimatePresence>\n      )}\n    </span>\n  );\n}\n\nexport function ActionSwapIcon({\n  value,\n  children,\n  animation = \"blur\",\n  className,\n}: ActionSwapIconProps) {\n  const reduce = useReducedMotion();\n  // Icons are single elements — cascade maps to its closest motion, roll.\n  const coreAnimation: CoreAnimation =\n    animation === \"cascade\" ? \"roll\" : animation;\n\n  return (\n    <span className={cn(\"relative inline-grid shrink-0 place-items-center overflow-hidden\", className)}>\n      <AnimatePresence mode=\"popLayout\" initial={false}>\n        <motion.span\n          key={`${animation}-${value}`}\n          aria-hidden\n          variants={ICON_VARIANTS[coreAnimation]}\n          initial={reduce ? false : \"initial\"}\n          animate={reduce ? { opacity: 1, filter: \"blur(0px)\", scale: 1, y: 0 } : \"animate\"}\n          exit={reduce ? undefined : \"exit\"}\n          className=\"col-start-1 row-start-1 inline-flex items-center justify-center will-change-[opacity,filter,transform]\"\n        >\n          {children}\n        </motion.span>\n      </AnimatePresence>\n    </span>\n  );\n}\n\nexport function ActionSwapButton({\n  items,\n  value,\n  defaultValue,\n  onValueChange,\n  variant = \"secondary\",\n  size = \"md\",\n  animation = \"blur\",\n  iconOnly = size === \"icon\",\n  cycle = true,\n  className,\n  disabled,\n  onClick,\n  ...rest\n}: ActionSwapButtonProps) {\n  const reduce = useReducedMotion();\n  const [internalValue, setInternalValue] = useState(defaultValue ?? items[0]?.id);\n  const currentValue = value ?? internalValue;\n  const activeIndex = Math.max(0, items.findIndex((item) => item.id === currentValue));\n  const activeItem = items[activeIndex] ?? items[0];\n  const hasIcon = items.some((item) => item.icon);\n  const nextItem = cycle && items.length > 0 ? items[(activeIndex + 1) % items.length] : undefined;\n\n  if (!activeItem) return null;\n\n  const accessibleLabel = activeItem.ariaLabel ?? (iconOnly && typeof activeItem.label === \"string\" ? activeItem.label : undefined);\n\n  return (\n    <motion.button\n      type=\"button\"\n      disabled={disabled}\n      whileTap={reduce || disabled ? undefined : { scale: 0.97 }}\n      transition={SPRING_PRESS}\n      className={cn(\n        \"inline-flex items-center justify-center overflow-hidden font-medium transition-colors\",\n        \"disabled:pointer-events-none disabled:opacity-50\",\n        VARIANT_CLASS[variant],\n        SIZE_CLASS[size],\n        className,\n      )}\n      aria-label={accessibleLabel}\n      onClick={(event) => {\n        onClick?.(event);\n        if (event.defaultPrevented || disabled || !cycle || !nextItem) return;\n        if (value === undefined) setInternalValue(nextItem.id);\n        onValueChange?.(nextItem.id, nextItem);\n      }}\n      {...rest}\n    >\n      {hasIcon ? (\n        <ActionSwapIcon value={activeItem.id} animation={animation} className=\"h-4 w-4\">\n          {activeItem.icon ?? null}\n        </ActionSwapIcon>\n      ) : null}\n      {!iconOnly ? (\n        <ActionSwapText value={activeItem.id} animation={animation}>\n          {activeItem.label}\n        </ActionSwapText>\n      ) : null}\n    </motion.button>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/button/index.tsx",
          "target": "@components/beui/components/motion/button/index.tsx",
          "type": "registry:component",
          "content": "export type {\n  ButtonLinkProps,\n  ButtonProps,\n  ButtonSize,\n  ButtonVariant,\n} from \"./base\";\nexport { Button, ButtonLink } from \"./base\";\nexport type { MagneticButtonProps } from \"./magnetic\";\nexport { MagneticButton } from \"./magnetic\";\nexport type { MetallicButtonProps } from \"./metallic\";\nexport { MetallicButton } from \"./metallic\";\nexport type { ButtonState, StatefulButtonProps } from \"./stateful\";\nexport { StatefulButton } from \"./stateful\";\n"
        },
        {
          "path": "components/beui/components/motion/button/base.tsx",
          "target": "@components/beui/components/motion/button/base.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  AnimatePresence,\n  type HTMLMotionProps,\n  motion,\n  useReducedMotion,\n} from \"motion/react\";\nimport {\n  forwardRef,\n  type PointerEvent,\n  type ReactNode,\n  useCallback,\n  useRef,\n  useState,\n} from \"react\";\nimport { EASE_OUT, SPRING_PRESS } from \"@/components/beui/lib/ease\";\nimport { useHoverCapable } from \"@/components/beui/lib/hooks/use-hover-capable\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"outline\";\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\";\n\nexport interface ButtonProps extends Omit<\n  HTMLMotionProps<\"button\">,\n  \"children\"\n> {\n  variant?: ButtonVariant;\n  size?: ButtonSize;\n  pressScale?: number;\n  /** Spawn a Material-style ripple from the press point. Off by default. */\n  ripple?: boolean;\n  children?: ReactNode;\n}\n\nexport interface ButtonLinkProps extends Omit<\n  HTMLMotionProps<\"a\">,\n  \"children\"\n> {\n  variant?: ButtonVariant;\n  size?: ButtonSize;\n  pressScale?: number;\n  children?: ReactNode;\n}\n\ntype Ripple = { id: number; x: number; y: number; size: number };\n\nconst VARIANT_CLASS: Record<ButtonVariant, string> = {\n  primary: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n  secondary: \"border border-border bg-card text-foreground hover:border-border\",\n  ghost: \"text-muted-foreground hover:text-foreground hover:bg-primary/5\",\n  outline:\n    \"border border-border bg-transparent text-foreground hover:bg-primary/5\",\n};\n\nconst SIZE_CLASS: Record<ButtonSize, string> = {\n  sm: \"h-8 px-3 text-xs gap-1.5 rounded-md\",\n  md: \"h-10 px-5 text-sm gap-2 rounded-md\",\n  lg: \"h-12 px-6 text-base gap-2 rounded-md\",\n  icon: \"h-8 w-8 rounded-md\",\n};\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n  function Button(\n    {\n      variant = \"primary\",\n      size = \"md\",\n      pressScale = 0.93,\n      ripple = false,\n      className,\n      children,\n      onPointerDown,\n      ...rest\n    },\n    ref,\n  ) {\n    const reduce = useReducedMotion();\n    const canHover = useHoverCapable();\n    const [ripples, setRipples] = useState<Ripple[]>([]);\n    const nextId = useRef(0);\n\n    const handlePointerDown = useCallback(\n      (event: PointerEvent<HTMLButtonElement>) => {\n        if (ripple && !reduce) {\n          const rect = event.currentTarget.getBoundingClientRect();\n          const size = Math.max(rect.width, rect.height) * 2;\n          const id = nextId.current++;\n          setRipples((prev) => [\n            ...prev,\n            {\n              id,\n              x: event.clientX - rect.left,\n              y: event.clientY - rect.top,\n              size,\n            },\n          ]);\n        }\n        onPointerDown?.(event);\n      },\n      [ripple, reduce, onPointerDown],\n    );\n\n    return (\n      <motion.button\n        ref={ref}\n        type=\"button\"\n        whileTap={reduce ? undefined : { scale: pressScale }}\n        whileHover={reduce || !canHover ? undefined : { scale: 1.02 }}\n        transition={SPRING_PRESS}\n        onPointerDown={handlePointerDown}\n        className={cn(\n          \"inline-flex items-center justify-center font-medium select-none\",\n          \"transition-colors\",\n          \"disabled:pointer-events-none disabled:opacity-50\",\n          ripple && \"relative overflow-hidden\",\n          VARIANT_CLASS[variant],\n          SIZE_CLASS[size],\n          className,\n        )}\n        {...rest}\n      >\n        {ripple && !reduce ? (\n          <span className=\"pointer-events-none absolute inset-0 overflow-hidden rounded-[inherit]\">\n            <AnimatePresence>\n              {ripples.map((r) => (\n                <motion.span\n                  key={r.id}\n                  className=\"absolute rounded-full bg-current\"\n                  style={{\n                    left: r.x,\n                    top: r.y,\n                    width: r.size,\n                    height: r.size,\n                    x: \"-50%\",\n                    y: \"-50%\",\n                  }}\n                  initial={{ scale: 0.05, opacity: 0.3 }}\n                  animate={{ scale: 1, opacity: 0 }}\n                  exit={{ opacity: 0 }}\n                  transition={{ duration: 1.6, ease: EASE_OUT }}\n                  onAnimationComplete={() =>\n                    setRipples((prev) => prev.filter((x) => x.id !== r.id))\n                  }\n                />\n              ))}\n            </AnimatePresence>\n          </span>\n        ) : null}\n        {children}\n      </motion.button>\n    );\n  },\n);\n\nexport const ButtonLink = forwardRef<HTMLAnchorElement, ButtonLinkProps>(\n  function ButtonLink(\n    {\n      variant = \"primary\",\n      size = \"md\",\n      pressScale = 0.93,\n      className,\n      children,\n      ...rest\n    },\n    ref,\n  ) {\n    const reduce = useReducedMotion();\n    const canHover = useHoverCapable();\n\n    return (\n      <motion.a\n        ref={ref}\n        whileTap={reduce ? undefined : { scale: pressScale }}\n        whileHover={reduce || !canHover ? undefined : { scale: 1.02 }}\n        transition={SPRING_PRESS}\n        className={cn(\n          \"inline-flex items-center justify-center font-medium select-none\",\n          \"transition-colors\",\n          VARIANT_CLASS[variant],\n          SIZE_CLASS[size],\n          className,\n        )}\n        {...rest}\n      >\n        {children}\n      </motion.a>\n    );\n  },\n);\n"
        },
        {
          "path": "components/beui/lib/hooks/use-hover-capable.ts",
          "target": "@components/beui/lib/hooks/use-hover-capable.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/**\n * Returns true only on devices that have a true hover (mouse / trackpad).\n * Touch devices fire phantom `:hover` on tap that sticks until tap-elsewhere\n * — gate hover-only effects (scale lifts, magnetic pulls) behind this.\n */\nexport function useHoverCapable() {\n  const [canHover, setCanHover] = useState(false);\n\n  useEffect(() => {\n    if (typeof window === \"undefined\" || !window.matchMedia) return;\n    const mq = window.matchMedia(\"(hover: hover) and (pointer: fine)\");\n    const update = () => setCanHover(mq.matches);\n    update();\n    mq.addEventListener?.(\"change\", update);\n    return () => mq.removeEventListener?.(\"change\", update);\n  }, []);\n\n  return canHover;\n}\n"
        },
        {
          "path": "components/beui/components/motion/button/magnetic.tsx",
          "target": "@components/beui/components/motion/button/magnetic.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { forwardRef } from \"react\";\nimport { Magnetic } from \"../magnetic\";\nimport { Button, type ButtonProps } from \"./base\";\n\nexport interface MagneticButtonProps extends ButtonProps {\n  /** Magnetic pull strength. Default 0.25. */\n  strength?: number;\n  /** Class applied to the magnetic wrapper. */\n  magneticClassName?: string;\n}\n\nexport const MagneticButton = forwardRef<HTMLButtonElement, MagneticButtonProps>(function MagneticButton(\n  { strength = 0.25, magneticClassName, children, ...rest },\n  ref,\n) {\n  return (\n    <Magnetic strength={strength} className={magneticClassName}>\n      <Button ref={ref} {...rest}>\n        {children}\n      </Button>\n    </Magnetic>\n  );\n});\n"
        },
        {
          "path": "components/beui/components/motion/magnetic.tsx",
          "target": "@components/beui/components/motion/magnetic.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, useMotionValue, useReducedMotion, useSpring } from \"motion/react\";\nimport { useRef, type ReactNode } from \"react\";\nimport { SPRING_MOUSE } from \"@/components/beui/lib/ease\";\nimport { useHoverCapable } from \"@/components/beui/lib/hooks/use-hover-capable\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface MagneticProps {\n  children: ReactNode;\n  strength?: number;\n  className?: string;\n}\n\nexport function Magnetic({ children, strength = 0.35, className }: MagneticProps) {\n  const ref = useRef<HTMLDivElement>(null);\n  const reduce = useReducedMotion();\n  const canHover = useHoverCapable();\n  // Decorative cursor-follow: skip on touch (phantom hover) and reduced motion.\n  const enabled = !reduce && canHover;\n  const x = useMotionValue(0);\n  const y = useMotionValue(0);\n  const sx = useSpring(x, SPRING_MOUSE);\n  const sy = useSpring(y, SPRING_MOUSE);\n\n  const onMove = (e: React.MouseEvent<HTMLDivElement>) => {\n    const el = ref.current;\n    if (!el || !enabled) return;\n    const rect = el.getBoundingClientRect();\n    x.set((e.clientX - rect.left - rect.width / 2) * strength);\n    y.set((e.clientY - rect.top - rect.height / 2) * strength);\n  };\n\n  const onLeave = () => {\n    x.set(0);\n    y.set(0);\n  };\n\n  return (\n    <motion.div\n      ref={ref}\n      onMouseMove={onMove}\n      onMouseLeave={onLeave}\n      style={{ x: sx, y: sy }}\n      className={cn(\"inline-block\", className)}\n    >\n      {children}\n    </motion.div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/button/metallic.tsx",
          "target": "@components/beui/components/motion/button/metallic.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { forwardRef, useState } from \"react\";\nimport { EASE_IN_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport { Button, type ButtonProps } from \"./base\";\n\nexport interface MetallicButtonProps extends Omit<\n  ButtonProps,\n  \"ripple\" | \"variant\"\n> {\n  /** Stops the traveling reflection while preserving the chrome rim. */\n  paused?: boolean;\n}\n\n// The rim and highlight drift separately so the material stays quiet and reflective.\nconst SILVER_DRIFT = {\n  duration: 8,\n  ease: EASE_IN_OUT,\n  repeat: Infinity,\n};\n\nconst CHROME_SHIMMER = {\n  duration: 2.4,\n  ease: EASE_IN_OUT,\n};\n\nexport const MetallicButton = forwardRef<\n  HTMLButtonElement,\n  MetallicButtonProps\n>(function MetallicButton(\n  {\n    size = \"md\",\n    paused = false,\n    className,\n    children,\n    onHoverStart,\n    onHoverEnd,\n    ...rest\n  },\n  ref,\n) {\n  const reduce = useReducedMotion();\n  const still = paused || Boolean(reduce);\n  const [hovered, setHovered] = useState(false);\n\n  return (\n    <Button\n      ref={ref}\n      variant=\"ghost\"\n      size={size}\n      onHoverStart={(event, info) => {\n        setHovered(true);\n        onHoverStart?.(event, info);\n      }}\n      onHoverEnd={(event, info) => {\n        setHovered(false);\n        onHoverEnd?.(event, info);\n      }}\n      className={cn(\n        \"group relative isolate overflow-hidden border-0 bg-transparent text-foreground\",\n        \"hover:bg-transparent hover:text-foreground\",\n        \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n        \"shadow-[0_8px_22px_rgba(0,0,0,0.16)]\",\n        size === \"icon\" && \"rounded-full\",\n        className,\n      )}\n      {...rest}\n    >\n      <motion.span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-y-0 left-[-18%] z-0 w-[136%] rounded-[inherit] bg-[linear-gradient(105deg,#111_0%,#737373_14%,#fafafa_26%,#525252_38%,#0a0a0a_50%,#a3a3a3_64%,#fff_75%,#404040_87%,#111_100%)]\"\n        animate={still ? undefined : { x: [\"0%\", \"13%\", \"0%\"] }}\n        transition={still ? undefined : SILVER_DRIFT}\n      />\n\n      <motion.span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-y-0 left-[-58%] z-[1] w-[52%] -skew-x-12 bg-[linear-gradient(90deg,transparent,rgba(255,255,255,0.5)_48%,transparent)] opacity-50 blur-[3px] mix-blend-screen\"\n        animate={still ? undefined : { x: hovered ? \"310%\" : \"0%\" }}\n        transition={still ? undefined : CHROME_SHIMMER}\n      />\n\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-[2px] z-[2] rounded-[inherit] bg-background transition-colors group-hover:bg-muted/40\"\n      />\n\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-[2px] z-[3] rounded-[inherit] shadow-[inset_0_1px_0_rgba(255,255,255,0.28),inset_0_-1px_0_rgba(0,0,0,0.16)]\"\n      />\n\n      <span className=\"relative z-10 inline-flex items-center justify-center gap-2\">\n        {children}\n      </span>\n    </Button>\n  );\n});\n"
        },
        {
          "path": "components/beui/components/motion/button/stateful.tsx",
          "target": "@components/beui/components/motion/button/stateful.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Check, Loader2, X } from \"lucide-react\";\nimport {\n  AnimatePresence,\n  motion,\n  useReducedMotion,\n  type Variants,\n} from \"motion/react\";\nimport {\n  forwardRef,\n  type ReactNode,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport { EASE_OUT, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { Button, type ButtonProps } from \"./base\";\n\nexport type ButtonState = \"idle\" | \"loading\" | \"success\" | \"error\";\n\nexport interface StatefulButtonProps extends Omit<ButtonProps, \"children\"> {\n  state?: ButtonState;\n  children: ReactNode;\n  loadingText?: ReactNode;\n  successText?: ReactNode;\n  errorText?: ReactNode;\n  icon?: ReactNode;\n}\n\nconst CASCADE_STAGGER = 0.025;\nconst ROLL_BLUR = \"blur(6px)\";\n\nconst CASCADE_LETTER_VARIANTS: Variants = {\n  initial: { opacity: 0, y: \"105%\", filter: ROLL_BLUR },\n  animate: (delay: number = 0) => ({\n    opacity: 1,\n    y: \"0%\",\n    filter: \"blur(0px)\",\n    transition: { ...SPRING_SWAP, delay },\n  }),\n  exit: (delay: number = 0) => ({\n    opacity: 0,\n    y: \"-105%\",\n    filter: ROLL_BLUR,\n    transition: { duration: 0.16, ease: EASE_OUT, delay: delay * 0.5 },\n  }),\n};\n\nconst ICON_VARIANTS: Variants = {\n  // Width collapses too, so the icon adds/removes its own space smoothly\n  // instead of popping the row width in a single frame.\n  initial: { opacity: 0, width: 0, scale: 0.7, filter: ROLL_BLUR },\n  animate: {\n    opacity: 1,\n    width: \"1.5rem\",\n    scale: 1,\n    filter: \"blur(0px)\",\n    transition: SPRING_SWAP,\n  },\n  exit: {\n    opacity: 0,\n    width: 0,\n    scale: 0.7,\n    filter: ROLL_BLUR,\n    transition: { duration: 0.16, ease: EASE_OUT },\n  },\n};\n\nfunction IconSlot({ keyId, children }: { keyId: string; children: ReactNode }) {\n  const reduce = useReducedMotion();\n  return (\n    <motion.span\n      key={keyId}\n      variants={ICON_VARIANTS}\n      initial={reduce ? { opacity: 0 } : \"initial\"}\n      animate={reduce ? { opacity: 1 } : \"animate\"}\n      exit={reduce ? { opacity: 0 } : \"exit\"}\n      transition={reduce ? { duration: 0.15 } : undefined}\n      className=\"inline-grid shrink-0 place-items-center overflow-hidden\"\n    >\n      {children}\n    </motion.span>\n  );\n}\n\nfunction TextSlot({\n  value,\n  children,\n}: {\n  value: string;\n  children: ReactNode;\n}) {\n  const reduce = useReducedMotion();\n  const measureRef = useRef<HTMLSpanElement>(null);\n  const [width, setWidth] = useState<number>();\n  const label = typeof children === \"string\" ? children : null;\n  const cascade = label !== null && !reduce;\n\n  // Measure strings with the same per-letter layout as the cascade. Measuring\n  // the whole string preserves kerning, which can make it narrower than the\n  // inline-block letters and clip the final glyph during the width animation.\n  // The label can change on any render, so the measurement intentionally runs after each commit.\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  useLayoutEffect(() => {\n    const nextWidth = measureRef.current?.offsetWidth;\n    if (!nextWidth) return;\n    setWidth((current) => (current === nextWidth ? current : nextWidth));\n  });\n\n  return (\n    <motion.span\n      initial={false}\n      animate={{ width }}\n      transition={reduce ? { duration: 0 } : SPRING_SWAP}\n      className=\"relative inline-block overflow-hidden whitespace-nowrap align-bottom\"\n    >\n      <span\n        ref={measureRef}\n        aria-hidden\n        className=\"invisible inline-block whitespace-nowrap\"\n      >\n        {cascade\n          ? label.split(\"\").map((char, index) => (\n              <span\n                // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity.\n                key={index}\n                className=\"inline-block whitespace-pre\"\n              >\n                {char}\n              </span>\n            ))\n          : children}\n      </span>\n\n      {cascade ? (\n        <>\n          <span className=\"sr-only\">{label}</span>\n          <AnimatePresence initial={false}>\n            <motion.span\n              key={`cascade-${value}`}\n              aria-hidden\n              initial=\"initial\"\n              animate=\"animate\"\n              exit=\"exit\"\n              className=\"absolute left-0 top-0 inline-block whitespace-pre\"\n            >\n              {label.split(\"\").map((char, index) => (\n                <motion.span\n                  // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity.\n                  key={index}\n                  custom={index * CASCADE_STAGGER}\n                  variants={CASCADE_LETTER_VARIANTS}\n                  className=\"inline-block whitespace-pre will-change-[opacity,filter,transform]\"\n                >\n                  {char}\n                </motion.span>\n              ))}\n            </motion.span>\n          </AnimatePresence>\n        </>\n      ) : (\n        <AnimatePresence initial={false}>\n          <motion.span\n            key={`text-${value}`}\n            initial={reduce ? { opacity: 0 } : { opacity: 0, y: 14, filter: ROLL_BLUR }}\n            animate={reduce ? { opacity: 1 } : { opacity: 1, y: 0, filter: \"blur(0px)\" }}\n            exit={reduce ? { opacity: 0 } : { opacity: 0, y: -14, filter: ROLL_BLUR }}\n            transition={reduce ? { duration: 0.15 } : SPRING_SWAP}\n            className=\"absolute left-0 top-0 inline-block will-change-[opacity,filter,transform]\"\n          >\n            {children}\n          </motion.span>\n        </AnimatePresence>\n      )}\n    </motion.span>\n  );\n}\n\nexport const StatefulButton = forwardRef<HTMLButtonElement, StatefulButtonProps>(function StatefulButton(\n  {\n    state = \"idle\",\n    children,\n    loadingText = \"Loading\",\n    successText = \"Done\",\n    errorText = \"Try again\",\n    icon,\n    disabled,\n    ...rest\n  },\n  ref,\n) {\n  const isBusy = state === \"loading\";\n  const stateText =\n    state === \"loading\"\n      ? loadingText\n      : state === \"success\"\n        ? successText\n        : state === \"error\"\n        ? errorText\n        : children;\n  const textKey =\n    typeof stateText === \"string\" ? `${state}-${stateText}` : state;\n\n  return (\n    <Button ref={ref} disabled={disabled || isBusy} aria-busy={isBusy} whileHover={undefined} {...rest}>\n      <span\n        aria-live=\"polite\"\n        className=\"relative inline-flex items-center justify-center overflow-hidden\"\n      >\n        <AnimatePresence initial={false}>\n          {state === \"loading\" ? (\n            <IconSlot keyId=\"loading-icon\">\n              <Loader2 className=\"h-4 w-4 animate-spin\" />\n            </IconSlot>\n          ) : null}\n          {state === \"success\" ? (\n            <IconSlot keyId=\"success-icon\">\n              <Check className=\"h-4 w-4\" />\n            </IconSlot>\n          ) : null}\n          {state === \"error\" ? (\n            <IconSlot keyId=\"error-icon\">\n              <X className=\"h-4 w-4\" />\n            </IconSlot>\n          ) : null}\n        </AnimatePresence>\n\n        <TextSlot value={textKey}>{stateText}</TextSlot>\n\n        <AnimatePresence initial={false}>\n          {state === \"idle\" && icon ? (\n            <IconSlot keyId=\"idle-icon\">{icon}</IconSlot>\n          ) : null}\n        </AnimatePresence>\n      </span>\n    </Button>\n  );\n});\n"
        },
        {
          "path": "components/beui/components/motion/checkbox.tsx",
          "target": "@components/beui/components/motion/checkbox.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { useId } from \"react\";\nimport { EASE_OUT, SPRING_PRESS } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nconst CHECK_PATH = \"M5 13l4 4L19 7\";\nconst INDETERMINATE_PATH = \"M6 12h12\";\n\nexport interface CheckboxProps {\n  checked: boolean;\n  onCheckedChange: (checked: boolean) => void;\n  disabled?: boolean;\n  indeterminate?: boolean;\n  label?: string;\n  className?: string;\n  id?: string;\n  \"aria-label\"?: string;\n  /** Associates an external message (e.g. a form error) with the control. */\n  \"aria-describedby\"?: string;\n}\n\nexport function Checkbox({\n  checked,\n  onCheckedChange,\n  disabled,\n  indeterminate,\n  label,\n  className,\n  id: idProp,\n  \"aria-label\": ariaLabel,\n  \"aria-describedby\": ariaDescribedBy,\n}: CheckboxProps) {\n  const autoId = useId();\n  const id = idProp ?? autoId;\n  const reduce = useReducedMotion();\n  const showMark = checked || indeterminate;\n  const path = indeterminate ? INDETERMINATE_PATH : CHECK_PATH;\n\n  return (\n    <label\n      htmlFor={id}\n      className={cn(\n        \"inline-flex items-center gap-3\",\n        disabled ? \"cursor-not-allowed\" : \"cursor-pointer\",\n        className,\n      )}\n    >\n      <motion.button\n        id={id}\n        type=\"button\"\n        role=\"checkbox\"\n        aria-checked={indeterminate ? \"mixed\" : checked}\n        aria-label={ariaLabel}\n        aria-describedby={ariaDescribedBy}\n        disabled={disabled}\n        onClick={() => !disabled && onCheckedChange(!checked)}\n        whileTap={reduce || disabled ? undefined : { scale: 0.92 }}\n        transition={SPRING_PRESS}\n        data-state={\n          checked ? \"checked\" : indeterminate ? \"indeterminate\" : \"unchecked\"\n        }\n        className={cn(\n          \"inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md border-2 outline-none transition-colors duration-200\",\n          \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n          \"disabled:cursor-not-allowed disabled:opacity-60\",\n          showMark\n            ? \"border-primary bg-primary text-primary-foreground\"\n            : \"border-muted-foreground/50 bg-background hover:border-muted-foreground\",\n        )}\n      >\n        <AnimatePresence initial={false}>\n          {showMark ? (\n            <motion.svg\n              key={indeterminate ? \"indeterminate\" : \"checked\"}\n              width=\"12\"\n              height=\"12\"\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              strokeWidth={3}\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              initial={reduce ? { opacity: 1 } : { opacity: 0, scale: 0.5 }}\n              animate={reduce ? { opacity: 1 } : { opacity: 1, scale: 1 }}\n              exit={\n                reduce\n                  ? { opacity: 0 }\n                  : { opacity: 0, scale: 0.5, filter: \"blur(4px)\" }\n              }\n              transition={\n                reduce ? { duration: 0 } : { duration: 0.16, ease: EASE_OUT }\n              }\n              aria-hidden\n            >\n              <title>{indeterminate ? \"Partially selected\" : \"Selected\"}</title>\n              <motion.path\n                d={path}\n                initial={reduce ? { pathLength: 1 } : { pathLength: 0 }}\n                animate={{ pathLength: 1 }}\n                transition={\n                  reduce\n                    ? { duration: 0 }\n                    : {\n                        duration: indeterminate ? 0.2 : 0.3,\n                        ease: EASE_OUT,\n                        delay: 0.04,\n                      }\n                }\n              />\n            </motion.svg>\n          ) : null}\n        </AnimatePresence>\n      </motion.button>\n      {label ? (\n        <span className={cn(\"select-none text-sm text-foreground\", disabled && \"opacity-60\")}>\n          {label}\n        </span>\n      ) : null}\n    </label>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/input.tsx",
          "target": "@components/beui/components/motion/input.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  AnimatePresence,\n  animate,\n  motion,\n  useReducedMotion,\n} from \"motion/react\";\nimport {\n  forwardRef,\n  useEffect,\n  useId,\n  useRef,\n  useState,\n  type InputHTMLAttributes,\n  type ReactNode,\n} from \"react\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type InputClassNames = {\n  root?: string;\n  label?: string;\n  field?: string;\n  input?: string;\n  leftIcon?: string;\n  rightIcon?: string;\n  successIcon?: string;\n  errorMessage?: string;\n};\n\nexport interface InputProps extends Omit<\n  InputHTMLAttributes<HTMLInputElement>,\n  \"value\" | \"defaultValue\" | \"onChange\"\n> {\n  label?: string;\n  value?: string;\n  defaultValue?: string;\n  onChange?: (value: string) => void;\n  /** Truthy error triggers a shake, red border and (if a string) a message. */\n  error?: string | boolean;\n  /** Reserve one message line so validation does not shift nearby content. */\n  reserveErrorLine?: boolean;\n  success?: boolean;\n  leftIcon?: ReactNode;\n  rightIcon?: ReactNode;\n  className?: string;\n  classNames?: InputClassNames;\n}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n  {\n    label,\n    value: valueProp,\n    defaultValue,\n    onChange,\n    onFocus,\n    onBlur,\n    error,\n    reserveErrorLine = false,\n    success,\n    leftIcon,\n    rightIcon,\n    className,\n    classNames,\n    disabled,\n    id: idProp,\n    type,\n    ...rest\n  },\n  ref,\n) {\n  const reactId = useId();\n  const id = idProp ?? reactId;\n  const reduce = useReducedMotion();\n\n  const controlled = valueProp !== undefined;\n  const [internal, setInternal] = useState(defaultValue ?? \"\");\n  const value = controlled ? (valueProp ?? \"\") : internal;\n\n  const [focused, setFocused] = useState(false);\n\n  const fieldRef = useRef<HTMLDivElement>(null);\n\n  const hasError = Boolean(error);\n  const errorMessage = typeof error === \"string\" ? error : null;\n\n  // Right edge shows the success check, otherwise the caller's right icon.\n  const rightSlot = success ? null : rightIcon;\n\n  // Shake the field when an error appears.\n  useEffect(() => {\n    if (!fieldRef.current || reduce || !hasError) return;\n    animate(\n      fieldRef.current,\n      { x: [0, -6, 6, -4, 4, -2, 0] },\n      { duration: 0.45 },\n    );\n  }, [hasError, reduce]);\n\n  const handleChange = (next: string) => {\n    if (!controlled) setInternal(next);\n    onChange?.(next);\n  };\n\n  return (\n    <div\n      className={cn(\"flex flex-col gap-1.5\", className, classNames?.root)}\n    >\n      {label ? (\n        <label\n          htmlFor={id}\n          className={cn(\n            \"px-1 text-sm font-medium text-foreground\",\n            classNames?.label,\n          )}\n        >\n          {label}\n        </label>\n      ) : null}\n\n      <div\n        ref={fieldRef}\n        data-state={\n          hasError\n            ? \"error\"\n            : success\n              ? \"success\"\n              : focused\n                ? \"focused\"\n                : \"idle\"\n        }\n        className={cn(\n          \"relative h-11 overflow-hidden rounded-full border transition-colors duration-200\",\n          \"border-border\",\n          focused && !hasError && \"border-foreground/40 ring-2 ring-ring/40\",\n          hasError && \"border-destructive ring-2 ring-destructive/25\",\n          disabled && \"opacity-60\",\n          classNames?.field,\n        )}\n      >\n        {leftIcon ? (\n          <span\n            className={cn(\n              \"pointer-events-none absolute left-3 top-1/2 flex -translate-y-1/2 items-center text-muted-foreground [&_svg]:h-4 [&_svg]:w-4\",\n              classNames?.leftIcon,\n            )}\n          >\n            {leftIcon}\n          </span>\n        ) : null}\n\n        <input\n          ref={ref}\n          id={id}\n          type={type}\n          value={value}\n          disabled={disabled}\n          aria-invalid={hasError || undefined}\n          aria-describedby={errorMessage ? `${id}-error` : undefined}\n          {...rest}\n          onChange={(e) => handleChange(e.target.value)}\n          onFocus={(event) => {\n            setFocused(true);\n            onFocus?.(event);\n          }}\n          onBlur={(event) => {\n            setFocused(false);\n            onBlur?.(event);\n          }}\n          className={cn(\n            \"peer h-full w-full bg-transparent text-base leading-6 text-foreground caret-foreground outline-none\",\n            \"placeholder:text-muted-foreground/60\",\n            leftIcon ? \"pl-10\" : \"pl-3.5\",\n            rightSlot || success ? \"pr-10\" : \"pr-3.5\",\n            disabled && \"cursor-not-allowed\",\n            classNames?.input,\n          )}\n        />\n\n        {success ? (\n          <motion.svg\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            className={cn(\n              \"absolute right-3.5 top-1/2 h-5 w-5 -translate-y-1/2 text-(--color-success)\",\n              classNames?.successIcon,\n            )}\n          >\n            <motion.path\n              d=\"M5 12.5l4.5 4.5L19 7.5\"\n              stroke=\"currentColor\"\n              strokeWidth={2.5}\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              initial={reduce ? { pathLength: 1 } : { pathLength: 0 }}\n              animate={{ pathLength: 1 }}\n              transition={{ duration: 0.35, ease: \"easeOut\" }}\n            />\n          </motion.svg>\n        ) : rightSlot ? (\n          <span\n            className={cn(\n              \"absolute right-0 top-0 flex h-full items-center text-muted-foreground [&_button]:grid [&_button]:size-11 [&_button]:place-items-center [&_svg]:h-4 [&_svg]:w-4\",\n              classNames?.rightIcon,\n            )}\n          >\n            {rightSlot}\n          </span>\n        ) : null}\n      </div>\n\n      <div className={reserveErrorLine ? \"min-h-4\" : \"contents\"}>\n        <AnimatePresence initial={false}>\n          {errorMessage ? (\n            <motion.p\n              id={`${id}-error`}\n              role=\"alert\"\n              initial={\n                reduce\n                  ? { opacity: 0 }\n                  : { opacity: 0, y: -4, filter: \"blur(4px)\" }\n              }\n              animate={{ opacity: 1, y: 0, filter: \"blur(0px)\" }}\n              exit={\n                reduce\n                  ? { opacity: 0 }\n                  : { opacity: 0, y: -4, filter: \"blur(4px)\" }\n              }\n              transition={{ duration: 0.2 }}\n              className={cn(\n                \"px-1 text-xs text-destructive\",\n                classNames?.errorMessage,\n              )}\n            >\n              {errorMessage}\n            </motion.p>\n          ) : null}\n        </AnimatePresence>\n      </div>\n    </div>\n  );\n});\n"
        },
        {
          "path": "components/beui/components/motion/radio.tsx",
          "target": "@components/beui/components/motion/radio.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, MotionConfig, useReducedMotion } from \"motion/react\";\nimport {\n  createContext,\n  useCallback,\n  useContext,\n  useId,\n  useMemo,\n  useState,\n  type ReactNode,\n} from \"react\";\nimport { SPRING_LAYOUT, SPRING_PRESS } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\ntype RadioCtx = {\n  value: string;\n  setValue: (value: string) => void;\n  layoutId: string;\n};\n\nconst RadioCtx = createContext<RadioCtx | null>(null);\n\nfunction useRadioGroup() {\n  const ctx = useContext(RadioCtx);\n  if (!ctx) {\n    throw new Error(\"RadioGroupItem must be used inside <RadioGroup>\");\n  }\n  return ctx;\n}\n\nexport interface RadioGroupProps {\n  value?: string;\n  defaultValue?: string;\n  onValueChange?: (value: string) => void;\n  children: ReactNode;\n  className?: string;\n  orientation?: \"vertical\" | \"horizontal\";\n}\n\nexport function RadioGroup({\n  value,\n  defaultValue = \"\",\n  onValueChange,\n  children,\n  className,\n  orientation = \"vertical\",\n}: RadioGroupProps) {\n  const [internal, setInternal] = useState(defaultValue);\n  const layoutId = useId();\n  const reduce = useReducedMotion();\n  const controlled = value !== undefined;\n  const current = controlled ? value : internal;\n  const setValue = useCallback(\n    (next: string) => {\n      if (!controlled) setInternal(next);\n      onValueChange?.(next);\n    },\n    [controlled, onValueChange],\n  );\n  const contextValue = useMemo(\n    () => ({ value: current, setValue, layoutId }),\n    [current, layoutId, setValue],\n  );\n\n  return (\n    <MotionConfig transition={reduce ? { duration: 0 } : SPRING_LAYOUT}>\n      <RadioCtx.Provider value={contextValue}>\n        <div\n          role=\"radiogroup\"\n          className={cn(\n            \"flex gap-3\",\n            orientation === \"vertical\" ? \"flex-col\" : \"flex-row flex-wrap\",\n            className,\n          )}\n        >\n          {children}\n        </div>\n      </RadioCtx.Provider>\n    </MotionConfig>\n  );\n}\n\nexport interface RadioGroupItemProps {\n  value: string;\n  label?: string;\n  disabled?: boolean;\n  className?: string;\n  id?: string;\n}\n\nexport function RadioGroupItem({\n  value,\n  label,\n  disabled,\n  className,\n  id: idProp,\n}: RadioGroupItemProps) {\n  const { value: groupValue, setValue, layoutId } = useRadioGroup();\n  const autoId = useId();\n  const id = idProp ?? autoId;\n  const reduce = useReducedMotion();\n  const selected = groupValue === value;\n\n  return (\n    <label\n      htmlFor={id}\n      className={cn(\n        \"inline-flex items-center gap-3\",\n        disabled ? \"cursor-not-allowed\" : \"cursor-pointer\",\n        className,\n      )}\n    >\n      <motion.button\n        id={id}\n        type=\"button\"\n        role=\"radio\"\n        aria-checked={selected}\n        disabled={disabled}\n        onClick={() => !disabled && setValue(value)}\n        whileTap={reduce || disabled ? undefined : { scale: 0.92 }}\n        transition={SPRING_PRESS}\n        data-state={selected ? \"checked\" : \"unchecked\"}\n        className={cn(\n          \"relative inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full border-2 outline-none transition-colors duration-200\",\n          \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n          \"disabled:cursor-not-allowed disabled:opacity-60\",\n          selected\n            ? \"border-primary\"\n            : \"border-muted-foreground/50 hover:border-muted-foreground\",\n        )}\n      >\n        {selected ? (\n          <motion.span\n            layoutId={layoutId}\n            className=\"absolute inset-1 rounded-full bg-primary\"\n            transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n          />\n        ) : null}\n      </motion.button>\n      {label ? (\n        <span className={cn(\"select-none text-sm text-foreground\", disabled && \"opacity-60\")}>\n          {label}\n        </span>\n      ) : null}\n    </label>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/approval-card/types.ts",
          "target": "@components/beui/components/agents/approval-card/types.ts",
          "type": "registry:component",
          "content": "import type { ReactNode } from \"react\";\n\nexport type ApprovalCardStatus =\n  | \"pending\"\n  | \"submitting\"\n  | \"approved\"\n  | \"rejected\"\n  | \"changes-requested\"\n  | \"answered\";\n\nexport interface ApprovalCardOption {\n  value: string;\n  label: string;\n  disabled?: boolean;\n}\n\nexport interface ApprovalCardQuestion {\n  id: string;\n  title: ReactNode;\n  description?: ReactNode;\n  options?: ApprovalCardOption[];\n  multiple?: boolean;\n  autoAdvance?: boolean;\n  allowCustom?: boolean;\n  customPlaceholder?: string;\n}\n\nexport interface ApprovalCardAnswer {\n  selected: string[];\n  custom?: string;\n}\n\nexport type ApprovalCardAnswers = Record<string, ApprovalCardAnswer>;\n\nexport interface ApprovalCardProps {\n  title?: ReactNode;\n  description?: ReactNode;\n  children?: ReactNode;\n  questions?: ApprovalCardQuestion[];\n  status?: ApprovalCardStatus;\n  answers?: ApprovalCardAnswers;\n  defaultAnswers?: ApprovalCardAnswers;\n  onAnswersChange?: (answers: ApprovalCardAnswers) => void;\n  step?: number;\n  defaultStep?: number;\n  onStepChange?: (step: number) => void;\n  onSubmit?: (answers: ApprovalCardAnswers) => void;\n  onApprove?: () => void;\n  onReject?: () => void;\n  onRequestChanges?: () => void;\n  onDismiss?: () => void;\n  approveLabel?: ReactNode;\n  submitLabel?: ReactNode;\n  result?: ReactNode;\n  className?: string;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-file-diff",
      "type": "registry:block",
      "title": "Beui File Diff",
      "description": "File Diff",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/file-diff.tsx",
          "target": "@components/beui/components/agents/file-diff.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  Check,\n  ChevronDown,\n  Copy,\n  FileCode2,\n  LoaderCircle,\n} from \"lucide-react\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useEffect,\n  useId,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  type AgentCodeLanguage,\n  AgentCodeLine,\n  useAgentCodeTokens,\n} from \"@/components/beui/components/agents/agent-code\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport { SPRING_PRESS, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type FileDiffStatus = \"streaming\" | \"complete\";\nexport type FileDiffLineType = \"added\" | \"removed\" | \"context\";\n\nexport interface FileDiffLine {\n  id: string;\n  type?: FileDiffLineType;\n  oldLine?: number;\n  newLine?: number;\n  content: string;\n}\n\nexport interface FileDiffProps {\n  file: ReactNode;\n  lines: FileDiffLine[];\n  status?: FileDiffStatus;\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  collapseOnComplete?: boolean;\n  maxHeight?: number;\n  language?: AgentCodeLanguage;\n  copyText?: string;\n  onCopy?: () => void | Promise<void>;\n  className?: string;\n}\n\nfunction ChangeCount({ value, type }: { value: number; type: \"added\" | \"removed\" }) {\n  if (!value) return null;\n  return (\n    <span\n      className={cn(\n        \"font-mono text-xs tabular-nums\",\n        type === \"added\"\n          ? \"text-emerald-600 dark:text-emerald-400\"\n          : \"text-rose-600 dark:text-rose-400\",\n      )}\n    >\n      {type === \"added\" ? \"+\" : \"−\"}\n      {value}\n    </span>\n  );\n}\n\nexport function FileDiff({\n  file,\n  lines,\n  status = \"streaming\",\n  open,\n  defaultOpen = true,\n  onOpenChange,\n  collapseOnComplete = true,\n  maxHeight = 220,\n  language = \"typescript\",\n  copyText,\n  onCopy,\n  className,\n}: FileDiffProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const triggerId = `${baseId}-trigger`;\n  const contentId = `${baseId}-content`;\n  const viewportRef = useRef<HTMLDivElement>(null);\n  const previousStatus = useRef(status);\n  const copyTimer = useRef<number | undefined>(undefined);\n  const [copied, setCopied] = useState(false);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const currentOpen = open ?? internalOpen;\n  const streaming = status === \"streaming\";\n  const additions = lines.filter((line) => line.type === \"added\").length;\n  const deletions = lines.filter((line) => line.type === \"removed\").length;\n  const canCopy = Boolean(copyText || onCopy);\n  const code = lines.map((line) => line.content).join(\"\\n\");\n  const tokens = useAgentCodeTokens(code, language);\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [onOpenChange, open],\n  );\n\n  useEffect(() => {\n    if (previousStatus.current !== \"streaming\" && status === \"streaming\") {\n      setOpen(true);\n    }\n    if (\n      previousStatus.current === \"streaming\" &&\n      status === \"complete\" &&\n      collapseOnComplete\n    ) {\n      setOpen(false);\n    }\n    previousStatus.current = status;\n  }, [collapseOnComplete, setOpen, status]);\n\n  useEffect(\n    () => () => {\n      if (copyTimer.current) window.clearTimeout(copyTimer.current);\n    },\n    [],\n  );\n\n  useLayoutEffect(() => {\n    const viewport = viewportRef.current;\n    if (!viewport || !currentOpen || !streaming) return;\n\n    const frame = requestAnimationFrame(() => {\n      if (viewport.scrollHeight <= viewport.clientHeight) return;\n      if (typeof viewport.scrollTo === \"function\") {\n        viewport.scrollTo({\n          top: viewport.scrollHeight,\n          behavior: reduce ? \"auto\" : \"smooth\",\n        });\n      } else {\n        viewport.scrollTop = viewport.scrollHeight;\n      }\n    });\n    return () => cancelAnimationFrame(frame);\n  });\n\n  const handleCopy = useCallback(async () => {\n    if (onCopy) await onCopy();\n    else if (copyText) await navigator.clipboard?.writeText(copyText);\n\n    setCopied(true);\n    if (copyTimer.current) window.clearTimeout(copyTimer.current);\n    copyTimer.current = window.setTimeout(() => setCopied(false), 1600);\n  }, [copyText, onCopy]);\n\n  return (\n    <div\n      data-state={status}\n      aria-busy={streaming}\n      className={cn(\"w-full text-sm\", className)}\n    >\n      <button\n        id={triggerId}\n        type=\"button\"\n        aria-expanded={currentOpen}\n        aria-controls={contentId}\n        onClick={() => setOpen(!currentOpen)}\n        className=\"group flex min-h-9 w-full items-center gap-2 rounded-md py-1 text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n      >\n        <FileCode2\n          aria-hidden=\"true\"\n          className=\"size-4 shrink-0 text-muted-foreground\"\n        />\n        <span className=\"min-w-0 flex-1 truncate font-mono text-xs text-foreground/80\">\n          {file}\n        </span>\n        <span className=\"flex shrink-0 items-center gap-2\">\n          <ChangeCount value={additions} type=\"added\" />\n          <ChangeCount value={deletions} type=\"removed\" />\n        </span>\n        <span className=\"grid size-4 shrink-0 place-items-center text-muted-foreground/60\">\n          {streaming ? (\n            <LoaderCircle\n              aria-label=\"Applying changes\"\n              className={cn(\"size-3.5\", !reduce && \"animate-spin\")}\n            />\n          ) : (\n            <Check aria-label=\"Changes applied\" className=\"size-3.5\" />\n          )}\n        </span>\n        <motion.span\n          aria-hidden=\"true\"\n          animate={{ rotate: currentOpen ? 180 : 0 }}\n          transition={reduce ? { duration: 0 } : SPRING_SWAP}\n          className=\"shrink-0 text-muted-foreground/45 transition-colors group-hover:text-muted-foreground\"\n        >\n          <ChevronDown className=\"size-3.5\" />\n        </motion.span>\n      </button>\n\n      <AgentDisclosure\n        id={contentId}\n        role=\"region\"\n        aria-labelledby={triggerId}\n        open={currentOpen}\n      >\n        <div className=\"pl-6 pt-1.5\">\n          <div className=\"overflow-hidden rounded-lg bg-muted/80\">\n            <div\n              ref={viewportRef}\n              data-slot=\"file-diff-viewport\"\n              aria-live=\"polite\"\n              className=\"scrollbar-hide overflow-auto\"\n              style={{ maxHeight }}\n            >\n              <div className=\"font-mono text-xs leading-5\">\n                <span className=\"sr-only\">File changes</span>\n                {lines.map((line, index) => {\n                  const type = line.type ?? \"context\";\n                  return (\n                    <div\n                      key={line.id}\n                      className={cn(\n                        \"grid grid-cols-[2.25rem_2.25rem_1rem_minmax(0,1fr)]\",\n                        type === \"added\" && \"bg-emerald-500/[0.07]\",\n                        type === \"removed\" && \"bg-rose-500/[0.07]\",\n                      )}\n                    >\n                      <span className=\"select-none pr-2 text-right tabular-nums text-muted-foreground/40\">\n                        {line.oldLine}\n                      </span>\n                      <span className=\"select-none pr-2 text-right tabular-nums text-muted-foreground/40\">\n                        {line.newLine}\n                      </span>\n                      <span\n                        className={cn(\n                          \"select-none text-center text-muted-foreground/45\",\n                          type === \"added\" &&\n                            \"text-emerald-600 dark:text-emerald-400\",\n                          type === \"removed\" &&\n                            \"text-rose-600 dark:text-rose-400\",\n                        )}\n                      >\n                        {type === \"added\"\n                          ? \"+\"\n                          : type === \"removed\"\n                            ? \"−\"\n                            : \"\"}\n                      </span>\n                      <AgentCodeLine\n                        code={line.content}\n                        tokens={tokens?.[index]}\n                        className=\"min-w-0 whitespace-pre px-1.5\"\n                      />\n                    </div>\n                  );\n                })}\n              </div>\n            </div>\n\n            {canCopy ? (\n              <div className=\"flex justify-end px-2 pb-1.5 pt-1\">\n                <motion.button\n                  type=\"button\"\n                  aria-label={copied ? \"Copied\" : \"Copy diff\"}\n                  title={copied ? \"Copied\" : \"Copy diff\"}\n                  onClick={handleCopy}\n                  whileTap={reduce ? undefined : { scale: 0.9 }}\n                  transition={SPRING_PRESS}\n                  className=\"grid size-7 place-items-center rounded-md text-muted-foreground outline-none transition-colors hover:bg-background/70 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n                >\n                  {copied ? (\n                    <Check className=\"size-3.5\" />\n                  ) : (\n                    <Copy className=\"size-3.5\" />\n                  )}\n                </motion.button>\n              </div>\n            ) : null}\n          </div>\n        </div>\n      </AgentDisclosure>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-code.tsx",
          "target": "@components/beui/components/agents/agent-code.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  type CSSProperties,\n  Fragment,\n  useEffect,\n  useState,\n} from \"react\";\nimport { createHighlighter, type Highlighter } from \"shiki\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type AgentCodeLanguage =\n  | \"bash\"\n  | \"diff\"\n  | \"json\"\n  | \"text\"\n  | \"tsx\"\n  | \"typescript\";\n\nexport interface AgentCodeToken {\n  content: string;\n  offset: number;\n  light?: string;\n  dark?: string;\n}\n\nexport type AgentCodeTokenLines = AgentCodeToken[][];\n\nexport interface AgentCodeProps {\n  code: string;\n  language?: AgentCodeLanguage;\n  className?: string;\n}\n\nexport interface AgentCodeLineProps {\n  code: string;\n  tokens?: AgentCodeToken[];\n  className?: string;\n}\n\nconst LIGHT_THEME = \"github-light-high-contrast\";\nconst DARK_THEME = \"github-dark-high-contrast\";\nlet agentCodeHighlighter: Promise<Highlighter> | null = null;\nconst tokenCache = new Map<string, AgentCodeTokenLines>();\n\nfunction getAgentCodeHighlighter() {\n  if (!agentCodeHighlighter) {\n    agentCodeHighlighter = createHighlighter({\n      themes: [LIGHT_THEME, DARK_THEME],\n      langs: [\"bash\", \"diff\", \"json\", \"tsx\", \"typescript\"],\n    });\n  }\n  return agentCodeHighlighter;\n}\n\nfunction tokenCacheKey(code: string, language: AgentCodeLanguage) {\n  return `${language}\\u0000${code}`;\n}\n\nexport function useAgentCodeTokens(\n  code: string,\n  language: AgentCodeLanguage,\n) {\n  const key = tokenCacheKey(code, language);\n  const cached = tokenCache.get(key);\n  const [result, setResult] = useState<{\n    key: string;\n    code: string;\n    language: AgentCodeLanguage;\n    lines: AgentCodeTokenLines;\n  } | null>(cached ? { key, code, language, lines: cached } : null);\n\n  useEffect(() => {\n    const current = tokenCache.get(key);\n    if (current) {\n      setResult({ key, code, language, lines: current });\n      return;\n    }\n\n    let cancelled = false;\n    getAgentCodeHighlighter().then((highlighter) => {\n      if (cancelled) return;\n      const lines = highlighter\n        .codeToTokensWithThemes(code, {\n          lang: language,\n          themes: {\n            light: LIGHT_THEME,\n            dark: DARK_THEME,\n          },\n        })\n        .map((line) =>\n          line.map((token) => ({\n            content: token.content,\n            offset: token.offset,\n            light: token.variants.light?.color,\n            dark: token.variants.dark?.color,\n          })),\n      );\n      tokenCache.set(key, lines);\n      setResult({ key, code, language, lines });\n    });\n    return () => {\n      cancelled = true;\n    };\n  }, [code, key, language]);\n\n  if (result?.key === key) return result.lines;\n  if (result?.language === language && code.startsWith(result.code)) {\n    return result.lines;\n  }\n  return null;\n}\n\nexport function AgentCodeLine({\n  code,\n  tokens,\n  className,\n}: AgentCodeLineProps) {\n  return (\n    <span className={className}>\n      {tokens\n        ? tokens.map((token) => (\n            <span\n              key={`${token.offset}-${token.content}`}\n              style={\n                {\n                  \"--agent-code-light\": token.light ?? \"currentColor\",\n                  \"--agent-code-dark\": token.dark ?? token.light ?? \"currentColor\",\n                } as CSSProperties\n              }\n              className=\"text-[var(--agent-code-light)] dark:text-[var(--agent-code-dark)]\"\n            >\n              {token.content}\n            </span>\n          ))\n        : code}\n    </span>\n  );\n}\n\nexport function AgentCode({\n  code,\n  language = \"bash\",\n  className,\n}: AgentCodeProps) {\n  const tokens = useAgentCodeTokens(code, language);\n  let offset = 0;\n  const lines = code.split(\"\\n\").map((content) => {\n    const line = { content, offset };\n    offset += content.length + 1;\n    return line;\n  });\n\n  return (\n    <pre\n      className={cn(\n        \"m-0 overflow-x-auto whitespace-pre font-mono text-xs leading-5 text-foreground/85\",\n        className,\n      )}\n    >\n      <code>\n        {lines.map((line, index) => (\n          <Fragment key={line.offset}>\n            <AgentCodeLine code={line.content} tokens={tokens?.[index]} />\n            {index < lines.length - 1 ? \"\\n\" : null}\n          </Fragment>\n        ))}\n      </code>\n    </pre>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-disclosure.tsx",
          "target": "@components/beui/components/agents/agent-disclosure.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, type HTMLMotionProps, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface AgentDisclosureProps\n  extends Omit<HTMLMotionProps<\"div\">, \"animate\" | \"initial\"> {\n  open: boolean;\n  openHeight?: CSSProperties[\"height\"];\n}\n\n/** Shared transform-only reveal for collapsible agent content. */\nexport function AgentDisclosure({\n  open,\n  openHeight = \"auto\",\n  className,\n  style,\n  transition,\n  ...props\n}: AgentDisclosureProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.div\n      {...props}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        reduce\n          ? { opacity: open ? 1 : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              clipPath: open ? \"inset(0 0 0% 0)\" : \"inset(0 0 100% 0)\",\n              y: open ? 0 : -4,\n            }\n      }\n      transition={\n        transition ?? {\n          duration: reduce ? 0 : open ? 0.22 : 0.14,\n          ease: EASE_OUT,\n        }\n      }\n      className={cn(\"overflow-hidden\", className)}\n      style={{\n        ...style,\n        height: open ? openHeight : 0,\n        pointerEvents: open ? undefined : \"none\",\n        transformOrigin: \"top\",\n      }}\n    />\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-tool-result",
      "type": "registry:block",
      "title": "Beui Tool Result",
      "description": "Tool Result",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/tool-result.tsx",
          "target": "@components/beui/components/agents/tool-result.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  Ban,\n  Braces,\n  Check,\n  ChevronDown,\n  CircleCheck,\n  CircleX,\n  Copy,\n  LoaderCircle,\n  RotateCcw,\n  SquareTerminal,\n  Wrench,\n} from \"lucide-react\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useEffect,\n  useId,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  AgentCode,\n  type AgentCodeLanguage,\n} from \"@/components/beui/components/agents/agent-code\";\nimport { ActionSwapRollText } from \"@/components/beui/components/motion/action-swap-roll\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport { SPRING_PRESS, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type ToolResultStatus = \"running\" | \"success\" | \"error\" | \"cancelled\";\nexport type ToolResultKind = \"terminal\" | \"request\" | \"custom\";\n\nexport interface ToolResultProps {\n  tool: ReactNode;\n  title: ReactNode;\n  children: ReactNode;\n  status?: ToolResultStatus;\n  kind?: ToolResultKind;\n  meta?: ReactNode;\n  icon?: ReactNode;\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  collapseOnComplete?: boolean;\n  maxHeight?: number;\n  copyText?: string;\n  onCopy?: () => void | Promise<void>;\n  onRetry?: () => void;\n  className?: string;\n  contentClassName?: string;\n}\n\nexport interface ToolResultOutputProps {\n  children: string;\n  language?: AgentCodeLanguage;\n  className?: string;\n}\n\nfunction getStatusLabel(status: ToolResultStatus) {\n  if (status === \"running\") return \"Running\";\n  if (status === \"success\") return \"Completed\";\n  if (status === \"error\") return \"Failed\";\n  return \"Cancelled\";\n}\n\nfunction getSwapKey(value: ReactNode, fallback: string) {\n  return typeof value === \"string\" || typeof value === \"number\"\n    ? String(value)\n    : fallback;\n}\n\nfunction getStatusClass(status: ToolResultStatus) {\n  if (status === \"running\") {\n    return \"text-blue-600 dark:text-blue-400\";\n  }\n  if (status === \"success\") {\n    return \"text-emerald-600 dark:text-emerald-400\";\n  }\n  if (status === \"error\") {\n    return \"text-rose-600 dark:text-rose-400\";\n  }\n  return \"text-muted-foreground\";\n}\n\nfunction KindIcon({ kind }: { kind: ToolResultKind }) {\n  if (kind === \"terminal\") return <SquareTerminal className=\"size-4\" />;\n  if (kind === \"request\") return <Braces className=\"size-4\" />;\n  return <Wrench className=\"size-4\" />;\n}\n\nfunction StatusIcon({\n  status,\n  reduce,\n}: {\n  status: ToolResultStatus;\n  reduce: boolean;\n}) {\n  if (status === \"running\") {\n    return <LoaderCircle className={cn(\"size-3\", !reduce && \"animate-spin\")} />;\n  }\n  if (status === \"success\") return <CircleCheck className=\"size-3\" />;\n  if (status === \"error\") return <CircleX className=\"size-3\" />;\n  return <Ban className=\"size-3\" />;\n}\n\nfunction ToolResultAction({\n  label,\n  onClick,\n  children,\n}: {\n  label: string;\n  onClick: () => void;\n  children: ReactNode;\n}) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.button\n      type=\"button\"\n      aria-label={label}\n      title={label}\n      onClick={onClick}\n      whileTap={reduce ? undefined : { scale: 0.9 }}\n      transition={SPRING_PRESS}\n      className=\"grid size-7 place-items-center rounded-md text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n    >\n      {children}\n    </motion.button>\n  );\n}\n\nexport function ToolResultOutput({\n  children,\n  language = \"bash\",\n  className,\n}: ToolResultOutputProps) {\n  return (\n    <AgentCode\n      code={children}\n      language={language}\n      className={cn(\n        \"whitespace-pre-wrap break-words text-foreground/80\",\n        className,\n      )}\n    />\n  );\n}\n\nexport function ToolResult({\n  tool,\n  title,\n  children,\n  status = \"running\",\n  kind = \"custom\",\n  meta,\n  icon,\n  open,\n  defaultOpen = true,\n  onOpenChange,\n  collapseOnComplete = true,\n  maxHeight = 220,\n  copyText,\n  onCopy,\n  onRetry,\n  className,\n  contentClassName,\n}: ToolResultProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const triggerId = `${baseId}-trigger`;\n  const contentId = `${baseId}-content`;\n  const viewportRef = useRef<HTMLDivElement>(null);\n  const previousStatus = useRef(status);\n  const copyTimer = useRef<number | undefined>(undefined);\n  const [copied, setCopied] = useState(false);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const currentOpen = open ?? internalOpen;\n  const running = status === \"running\";\n  const canCopy = Boolean(copyText || onCopy);\n  const titleKey = getSwapKey(title, status);\n  const metaKey = getSwapKey(meta, `${status}-meta`);\n  const toolKey = getSwapKey(tool, `${status}-tool`);\n  const statusLabel = getStatusLabel(status);\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [onOpenChange, open],\n  );\n\n  useEffect(() => {\n    if (previousStatus.current !== \"running\" && status === \"running\") {\n      setOpen(true);\n    }\n    if (\n      previousStatus.current === \"running\" &&\n      status !== \"running\" &&\n      collapseOnComplete\n    ) {\n      setOpen(false);\n    }\n    previousStatus.current = status;\n  }, [collapseOnComplete, setOpen, status]);\n\n  useEffect(\n    () => () => {\n      if (copyTimer.current) window.clearTimeout(copyTimer.current);\n    },\n    [],\n  );\n\n  useLayoutEffect(() => {\n    const viewport = viewportRef.current;\n    if (!viewport || !currentOpen || !running) return;\n\n    const frame = requestAnimationFrame(() => {\n      if (typeof viewport.scrollTo === \"function\") {\n        viewport.scrollTo({\n          top: viewport.scrollHeight,\n          behavior: reduce ? \"auto\" : \"smooth\",\n        });\n      } else {\n        viewport.scrollTop = viewport.scrollHeight;\n      }\n    });\n    return () => cancelAnimationFrame(frame);\n  });\n\n  const handleCopy = useCallback(async () => {\n    if (onCopy) await onCopy();\n    else if (copyText) await navigator.clipboard?.writeText(copyText);\n\n    setCopied(true);\n    if (copyTimer.current) window.clearTimeout(copyTimer.current);\n    copyTimer.current = window.setTimeout(() => setCopied(false), 1600);\n  }, [copyText, onCopy]);\n\n  return (\n    <div\n      data-state={status}\n      aria-busy={running}\n      className={cn(\"w-full text-sm\", className)}\n    >\n      <button\n        id={triggerId}\n        type=\"button\"\n        aria-expanded={currentOpen}\n        aria-controls={contentId}\n        onClick={() => setOpen(!currentOpen)}\n        className=\"group flex min-h-9 w-full items-center gap-2 rounded-md py-1 text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n      >\n        <span\n          aria-hidden=\"true\"\n          className=\"grid size-4 shrink-0 place-items-center text-muted-foreground\"\n        >\n          {icon ?? <KindIcon kind={kind} />}\n        </span>\n        <span className=\"flex min-w-0 flex-1 items-baseline gap-2\">\n          <span className=\"min-w-0 truncate font-medium text-foreground/90\">\n            <ActionSwapRollText value={titleKey}>\n              {title}\n            </ActionSwapRollText>\n          </span>\n          {meta ? (\n            <span className=\"shrink-0 text-xs text-muted-foreground/60\">\n              <ActionSwapRollText value={metaKey}>\n                {meta}\n              </ActionSwapRollText>\n            </span>\n          ) : null}\n          <span className=\"min-w-0 truncate font-mono text-[11px] text-muted-foreground/55\">\n            <ActionSwapRollText value={toolKey}>\n              {tool}\n            </ActionSwapRollText>\n          </span>\n        </span>\n        <span\n          className={cn(\n            \"inline-flex shrink-0 items-center gap-1 text-[11px] font-medium\",\n            getStatusClass(status),\n          )}\n        >\n          <StatusIcon status={status} reduce={reduce} />\n          <ActionSwapRollText value={status}>{statusLabel}</ActionSwapRollText>\n        </span>\n        <motion.span\n          aria-hidden=\"true\"\n          animate={{ rotate: currentOpen ? 180 : 0 }}\n          transition={reduce ? { duration: 0 } : SPRING_SWAP}\n          className=\"shrink-0 text-muted-foreground/50 transition-colors group-hover:text-muted-foreground\"\n        >\n          <ChevronDown className=\"size-3.5\" />\n        </motion.span>\n      </button>\n\n      <AgentDisclosure\n        id={contentId}\n        role=\"region\"\n        aria-labelledby={triggerId}\n        open={currentOpen}\n      >\n        <div className=\"pl-6 pt-1.5\">\n          <div className=\"overflow-hidden rounded-lg bg-muted/80\">\n          <div\n            ref={viewportRef}\n            role=\"log\"\n            aria-live=\"polite\"\n            className=\"scrollbar-hide overflow-y-auto\"\n            style={{ maxHeight }}\n          >\n            <div className={cn(\"p-3\", contentClassName)}>{children}</div>\n          </div>\n\n            {canCopy || onRetry ? (\n              <div className=\"flex items-center gap-0.5 px-2 pb-1.5\">\n              {canCopy ? (\n                <ToolResultAction\n                  label={copied ? \"Copied\" : \"Copy result\"}\n                  onClick={handleCopy}\n                >\n                  {copied ? (\n                    <Check className=\"size-3.5\" />\n                  ) : (\n                    <Copy className=\"size-3.5\" />\n                  )}\n                </ToolResultAction>\n              ) : null}\n              {onRetry ? (\n                <ToolResultAction label=\"Run again\" onClick={onRetry}>\n                  <RotateCcw className=\"size-3.5\" />\n                </ToolResultAction>\n              ) : null}\n              <span className=\"ml-auto text-[11px] text-muted-foreground/55\">\n                <ActionSwapRollText value={status}>\n                  {statusLabel}\n                </ActionSwapRollText>\n              </span>\n              </div>\n            ) : null}\n          </div>\n        </div>\n      </AgentDisclosure>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-code.tsx",
          "target": "@components/beui/components/agents/agent-code.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  type CSSProperties,\n  Fragment,\n  useEffect,\n  useState,\n} from \"react\";\nimport { createHighlighter, type Highlighter } from \"shiki\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type AgentCodeLanguage =\n  | \"bash\"\n  | \"diff\"\n  | \"json\"\n  | \"text\"\n  | \"tsx\"\n  | \"typescript\";\n\nexport interface AgentCodeToken {\n  content: string;\n  offset: number;\n  light?: string;\n  dark?: string;\n}\n\nexport type AgentCodeTokenLines = AgentCodeToken[][];\n\nexport interface AgentCodeProps {\n  code: string;\n  language?: AgentCodeLanguage;\n  className?: string;\n}\n\nexport interface AgentCodeLineProps {\n  code: string;\n  tokens?: AgentCodeToken[];\n  className?: string;\n}\n\nconst LIGHT_THEME = \"github-light-high-contrast\";\nconst DARK_THEME = \"github-dark-high-contrast\";\nlet agentCodeHighlighter: Promise<Highlighter> | null = null;\nconst tokenCache = new Map<string, AgentCodeTokenLines>();\n\nfunction getAgentCodeHighlighter() {\n  if (!agentCodeHighlighter) {\n    agentCodeHighlighter = createHighlighter({\n      themes: [LIGHT_THEME, DARK_THEME],\n      langs: [\"bash\", \"diff\", \"json\", \"tsx\", \"typescript\"],\n    });\n  }\n  return agentCodeHighlighter;\n}\n\nfunction tokenCacheKey(code: string, language: AgentCodeLanguage) {\n  return `${language}\\u0000${code}`;\n}\n\nexport function useAgentCodeTokens(\n  code: string,\n  language: AgentCodeLanguage,\n) {\n  const key = tokenCacheKey(code, language);\n  const cached = tokenCache.get(key);\n  const [result, setResult] = useState<{\n    key: string;\n    code: string;\n    language: AgentCodeLanguage;\n    lines: AgentCodeTokenLines;\n  } | null>(cached ? { key, code, language, lines: cached } : null);\n\n  useEffect(() => {\n    const current = tokenCache.get(key);\n    if (current) {\n      setResult({ key, code, language, lines: current });\n      return;\n    }\n\n    let cancelled = false;\n    getAgentCodeHighlighter().then((highlighter) => {\n      if (cancelled) return;\n      const lines = highlighter\n        .codeToTokensWithThemes(code, {\n          lang: language,\n          themes: {\n            light: LIGHT_THEME,\n            dark: DARK_THEME,\n          },\n        })\n        .map((line) =>\n          line.map((token) => ({\n            content: token.content,\n            offset: token.offset,\n            light: token.variants.light?.color,\n            dark: token.variants.dark?.color,\n          })),\n      );\n      tokenCache.set(key, lines);\n      setResult({ key, code, language, lines });\n    });\n    return () => {\n      cancelled = true;\n    };\n  }, [code, key, language]);\n\n  if (result?.key === key) return result.lines;\n  if (result?.language === language && code.startsWith(result.code)) {\n    return result.lines;\n  }\n  return null;\n}\n\nexport function AgentCodeLine({\n  code,\n  tokens,\n  className,\n}: AgentCodeLineProps) {\n  return (\n    <span className={className}>\n      {tokens\n        ? tokens.map((token) => (\n            <span\n              key={`${token.offset}-${token.content}`}\n              style={\n                {\n                  \"--agent-code-light\": token.light ?? \"currentColor\",\n                  \"--agent-code-dark\": token.dark ?? token.light ?? \"currentColor\",\n                } as CSSProperties\n              }\n              className=\"text-[var(--agent-code-light)] dark:text-[var(--agent-code-dark)]\"\n            >\n              {token.content}\n            </span>\n          ))\n        : code}\n    </span>\n  );\n}\n\nexport function AgentCode({\n  code,\n  language = \"bash\",\n  className,\n}: AgentCodeProps) {\n  const tokens = useAgentCodeTokens(code, language);\n  let offset = 0;\n  const lines = code.split(\"\\n\").map((content) => {\n    const line = { content, offset };\n    offset += content.length + 1;\n    return line;\n  });\n\n  return (\n    <pre\n      className={cn(\n        \"m-0 overflow-x-auto whitespace-pre font-mono text-xs leading-5 text-foreground/85\",\n        className,\n      )}\n    >\n      <code>\n        {lines.map((line, index) => (\n          <Fragment key={line.offset}>\n            <AgentCodeLine code={line.content} tokens={tokens?.[index]} />\n            {index < lines.length - 1 ? \"\\n\" : null}\n          </Fragment>\n        ))}\n      </code>\n    </pre>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/motion/action-swap-roll.tsx",
          "target": "@components/beui/components/motion/action-swap-roll.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  ActionSwapButton,\n  ActionSwapIcon,\n  ActionSwapText,\n  type ActionSwapButtonProps,\n  type ActionSwapIconProps,\n  type ActionSwapTextProps,\n} from \"./action-swap\";\n\nexport type {\n  ActionSwapButtonSize,\n  ActionSwapButtonVariant,\n  ActionSwapItem,\n} from \"./action-swap\";\n\nexport type ActionSwapRollButtonProps = Omit<ActionSwapButtonProps, \"animation\">;\nexport type ActionSwapRollTextProps = Omit<ActionSwapTextProps, \"animation\">;\nexport type ActionSwapRollIconProps = Omit<ActionSwapIconProps, \"animation\">;\n\nexport function ActionSwapRollButton(props: ActionSwapRollButtonProps) {\n  return <ActionSwapButton {...props} animation=\"roll\" />;\n}\n\nexport function ActionSwapRollText(props: ActionSwapRollTextProps) {\n  return <ActionSwapText {...props} animation=\"roll\" />;\n}\n\nexport function ActionSwapRollIcon(props: ActionSwapRollIconProps) {\n  return <ActionSwapIcon {...props} animation=\"roll\" />;\n}\n"
        },
        {
          "path": "components/beui/components/motion/action-swap.tsx",
          "target": "@components/beui/components/motion/action-swap.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion, type HTMLMotionProps, type Variants } from \"motion/react\";\nimport { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { EASE_OUT, SPRING_PRESS, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type ActionSwapItem = {\n  id: string;\n  label: ReactNode;\n  icon?: ReactNode;\n  ariaLabel?: string;\n};\n\nexport type ActionSwapButtonVariant = \"primary\" | \"secondary\" | \"outline\" | \"ghost\";\nexport type ActionSwapButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\";\nexport type ActionSwapAnimation = \"blur\" | \"roll\" | \"cascade\";\n\n/** Animations with a single-element variant set (cascade animates per letter). */\ntype CoreAnimation = \"blur\" | \"roll\";\n\nexport interface ActionSwapButtonProps extends Omit<\n  HTMLMotionProps<\"button\">,\n  \"children\" | \"onChange\"\n> {\n  items: ActionSwapItem[];\n  value?: string;\n  defaultValue?: string;\n  onValueChange?: (value: string, item: ActionSwapItem) => void;\n  variant?: ActionSwapButtonVariant;\n  size?: ActionSwapButtonSize;\n  animation?: ActionSwapAnimation;\n  iconOnly?: boolean;\n  cycle?: boolean;\n}\n\nexport interface ActionSwapTextProps {\n  value: string;\n  children: ReactNode;\n  animation?: ActionSwapAnimation;\n  className?: string;\n}\n\nexport interface ActionSwapIconProps {\n  value: string;\n  children: ReactNode;\n  animation?: ActionSwapAnimation;\n  className?: string;\n}\n\nconst BLUR_TRANSITION = { duration: 0.2, ease: \"easeInOut\" } as const;\nconst ROLL_TRANSITION = SPRING_SWAP;\nconst ROLL_EXIT_TRANSITION = { duration: 0.14, ease: EASE_OUT } as const;\nconst SWAP_BLUR = \"blur(8px)\";\nconst ROLL_BLUR = \"blur(3px)\";\n\n// Cascade rolls the label one letter at a time, left to right. The leaving\n// and landing strings overlap as independent layers (no shared cells), so\n// proportional glyph widths never jitter. Exits cascade at half the enter\n// stagger so the tail of the old label lingers briefly.\nconst CASCADE_STAGGER = 0.025;\n\nconst CASCADE_LETTER_VARIANTS: Variants = {\n  initial: { opacity: 0, y: \"105%\", filter: ROLL_BLUR },\n  animate: (delay: number = 0) => ({\n    opacity: 1,\n    y: \"0%\",\n    filter: \"blur(0px)\",\n    transition: { ...SPRING_SWAP, delay },\n  }),\n  exit: (delay: number = 0) => ({\n    opacity: 0,\n    y: \"-105%\",\n    filter: ROLL_BLUR,\n    transition: { duration: 0.16, ease: EASE_OUT, delay: delay * 0.5 },\n  }),\n};\n\nconst TEXT_VARIANTS: Record<CoreAnimation, Variants> = {\n  blur: {\n    initial: { opacity: 0, scale: 0.94, filter: SWAP_BLUR },\n    animate: {\n      opacity: 1,\n      scale: 1,\n      filter: \"blur(0px)\",\n      transition: BLUR_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      scale: 0.94,\n      filter: SWAP_BLUR,\n      transition: BLUR_TRANSITION,\n    },\n  },\n  roll: {\n    initial: { opacity: 0, y: \"90%\", filter: ROLL_BLUR },\n    animate: {\n      opacity: 1,\n      y: \"0%\",\n      filter: \"blur(0px)\",\n      transition: ROLL_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      y: \"-90%\",\n      filter: ROLL_BLUR,\n      transition: ROLL_EXIT_TRANSITION,\n    },\n  },\n};\n\nconst ICON_VARIANTS: Record<CoreAnimation, Variants> = {\n  blur: {\n    initial: { opacity: 0, scale: 0.25, filter: SWAP_BLUR },\n    animate: {\n      opacity: 1,\n      scale: 1,\n      filter: \"blur(0px)\",\n      transition: BLUR_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      scale: 0.25,\n      filter: SWAP_BLUR,\n      transition: BLUR_TRANSITION,\n    },\n  },\n  roll: {\n    initial: { opacity: 0, y: 12, filter: ROLL_BLUR },\n    animate: {\n      opacity: 1,\n      y: 0,\n      filter: \"blur(0px)\",\n      transition: ROLL_TRANSITION,\n    },\n    exit: {\n      opacity: 0,\n      y: -12,\n      filter: ROLL_BLUR,\n      transition: ROLL_EXIT_TRANSITION,\n    },\n  },\n};\n\nconst VARIANT_CLASS: Record<ActionSwapButtonVariant, string> = {\n  primary: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n  secondary: \"border border-border bg-card text-foreground hover:border-border\",\n  outline: \"border border-border bg-transparent text-foreground hover:bg-primary/5\",\n  ghost: \"text-muted-foreground hover:bg-primary/5 hover:text-foreground\",\n};\n\nconst SIZE_CLASS: Record<ActionSwapButtonSize, string> = {\n  sm: \"h-8 gap-1.5 rounded-full px-3 text-xs\",\n  md: \"h-10 gap-2 rounded-full px-4 text-sm\",\n  lg: \"h-12 gap-2.5 rounded-full px-5 text-base\",\n  icon: \"h-10 w-10 rounded-full\",\n};\n\nexport function ActionSwapText({\n  value,\n  children,\n  animation = \"blur\",\n  className,\n}: ActionSwapTextProps) {\n  const reduce = useReducedMotion();\n\n  // Cascade needs a plain string to split into letters; non-string content\n  // and reduced motion fall back to the closest single-element animation.\n  const label = typeof children === \"string\" ? children : null;\n  const cascade = animation === \"cascade\" && label !== null && !reduce;\n  const coreAnimation: CoreAnimation =\n    animation === \"cascade\" ? \"roll\" : animation;\n\n  return (\n    <span\n      className={cn(\n        \"relative -my-[0.08em] inline-block max-w-full whitespace-nowrap py-[0.08em] align-bottom\",\n        className,\n      )}\n      style={{\n        clipPath: \"inset(0 -999px)\",\n        WebkitClipPath: \"inset(0 -999px)\",\n      }}\n    >\n      <span\n        aria-hidden\n        className=\"invisible inline-block whitespace-nowrap\"\n      >\n        {cascade\n          ? label.split(\"\").map((char, index) => (\n              <span\n                // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity.\n                key={index}\n                className=\"inline-block whitespace-pre\"\n              >\n                {char}\n              </span>\n            ))\n          : children}\n      </span>\n      {cascade ? (\n        <>\n          {/* Letters are decorative fragments; readers get the whole label. */}\n          <span className=\"sr-only\">{label}</span>\n          <AnimatePresence initial={false}>\n            <motion.span\n              key={`cascade-${value}`}\n              aria-hidden\n              initial=\"initial\"\n              animate=\"animate\"\n              exit=\"exit\"\n              className=\"absolute left-0 top-[0.08em] inline-block whitespace-pre\"\n            >\n              {label.split(\"\").map((char, i) => (\n                <motion.span\n                  // biome-ignore lint/suspicious/noArrayIndexKey: position is the slot identity — the letter at a position is exactly what rolls.\n                  key={i}\n                  custom={i * CASCADE_STAGGER}\n                  variants={CASCADE_LETTER_VARIANTS}\n                  className=\"inline-block whitespace-pre will-change-[opacity,filter,transform]\"\n                >\n                  {char}\n                </motion.span>\n              ))}\n            </motion.span>\n          </AnimatePresence>\n        </>\n      ) : (\n        <AnimatePresence initial={false}>\n          <motion.span\n            key={`${animation}-${value}`}\n            variants={TEXT_VARIANTS[coreAnimation]}\n            initial={reduce ? false : \"initial\"}\n            animate={reduce ? { opacity: 1, filter: \"blur(0px)\", scale: 1, y: 0 } : \"animate\"}\n            exit={reduce ? undefined : \"exit\"}\n            // Truncation lives on the layer that holds the text — the layer\n            // moves as a whole, so clipping it never eats the roll.\n            className=\"absolute left-0 top-[0.08em] inline-block max-w-full truncate will-change-[opacity,filter,transform]\"\n          >\n            {children}\n          </motion.span>\n        </AnimatePresence>\n      )}\n    </span>\n  );\n}\n\nexport function ActionSwapIcon({\n  value,\n  children,\n  animation = \"blur\",\n  className,\n}: ActionSwapIconProps) {\n  const reduce = useReducedMotion();\n  // Icons are single elements — cascade maps to its closest motion, roll.\n  const coreAnimation: CoreAnimation =\n    animation === \"cascade\" ? \"roll\" : animation;\n\n  return (\n    <span className={cn(\"relative inline-grid shrink-0 place-items-center overflow-hidden\", className)}>\n      <AnimatePresence mode=\"popLayout\" initial={false}>\n        <motion.span\n          key={`${animation}-${value}`}\n          aria-hidden\n          variants={ICON_VARIANTS[coreAnimation]}\n          initial={reduce ? false : \"initial\"}\n          animate={reduce ? { opacity: 1, filter: \"blur(0px)\", scale: 1, y: 0 } : \"animate\"}\n          exit={reduce ? undefined : \"exit\"}\n          className=\"col-start-1 row-start-1 inline-flex items-center justify-center will-change-[opacity,filter,transform]\"\n        >\n          {children}\n        </motion.span>\n      </AnimatePresence>\n    </span>\n  );\n}\n\nexport function ActionSwapButton({\n  items,\n  value,\n  defaultValue,\n  onValueChange,\n  variant = \"secondary\",\n  size = \"md\",\n  animation = \"blur\",\n  iconOnly = size === \"icon\",\n  cycle = true,\n  className,\n  disabled,\n  onClick,\n  ...rest\n}: ActionSwapButtonProps) {\n  const reduce = useReducedMotion();\n  const [internalValue, setInternalValue] = useState(defaultValue ?? items[0]?.id);\n  const currentValue = value ?? internalValue;\n  const activeIndex = Math.max(0, items.findIndex((item) => item.id === currentValue));\n  const activeItem = items[activeIndex] ?? items[0];\n  const hasIcon = items.some((item) => item.icon);\n  const nextItem = cycle && items.length > 0 ? items[(activeIndex + 1) % items.length] : undefined;\n\n  if (!activeItem) return null;\n\n  const accessibleLabel = activeItem.ariaLabel ?? (iconOnly && typeof activeItem.label === \"string\" ? activeItem.label : undefined);\n\n  return (\n    <motion.button\n      type=\"button\"\n      disabled={disabled}\n      whileTap={reduce || disabled ? undefined : { scale: 0.97 }}\n      transition={SPRING_PRESS}\n      className={cn(\n        \"inline-flex items-center justify-center overflow-hidden font-medium transition-colors\",\n        \"disabled:pointer-events-none disabled:opacity-50\",\n        VARIANT_CLASS[variant],\n        SIZE_CLASS[size],\n        className,\n      )}\n      aria-label={accessibleLabel}\n      onClick={(event) => {\n        onClick?.(event);\n        if (event.defaultPrevented || disabled || !cycle || !nextItem) return;\n        if (value === undefined) setInternalValue(nextItem.id);\n        onValueChange?.(nextItem.id, nextItem);\n      }}\n      {...rest}\n    >\n      {hasIcon ? (\n        <ActionSwapIcon value={activeItem.id} animation={animation} className=\"h-4 w-4\">\n          {activeItem.icon ?? null}\n        </ActionSwapIcon>\n      ) : null}\n      {!iconOnly ? (\n        <ActionSwapText value={activeItem.id} animation={animation}>\n          {activeItem.label}\n        </ActionSwapText>\n      ) : null}\n    </motion.button>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/components/agents/agent-disclosure.tsx",
          "target": "@components/beui/components/agents/agent-disclosure.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, type HTMLMotionProps, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface AgentDisclosureProps\n  extends Omit<HTMLMotionProps<\"div\">, \"animate\" | \"initial\"> {\n  open: boolean;\n  openHeight?: CSSProperties[\"height\"];\n}\n\n/** Shared transform-only reveal for collapsible agent content. */\nexport function AgentDisclosure({\n  open,\n  openHeight = \"auto\",\n  className,\n  style,\n  transition,\n  ...props\n}: AgentDisclosureProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.div\n      {...props}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        reduce\n          ? { opacity: open ? 1 : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              clipPath: open ? \"inset(0 0 0% 0)\" : \"inset(0 0 100% 0)\",\n              y: open ? 0 : -4,\n            }\n      }\n      transition={\n        transition ?? {\n          duration: reduce ? 0 : open ? 0.22 : 0.14,\n          ease: EASE_OUT,\n        }\n      }\n      className={cn(\"overflow-hidden\", className)}\n      style={{\n        ...style,\n        height: open ? openHeight : 0,\n        pointerEvents: open ? undefined : \"none\",\n        transformOrigin: \"top\",\n      }}\n    />\n  );\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-streaming-response",
      "type": "registry:block",
      "title": "Beui Streaming Response",
      "description": "Streaming Response",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/streaming-response.tsx",
          "target": "@components/beui/components/agents/streaming-response.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  Check,\n  ChevronDown,\n  Copy,\n  RotateCcw,\n  ThumbsDown,\n  ThumbsUp,\n} from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useEffect,\n  useId,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  type CitationItem,\n  CitationList,\n  CitationStack,\n} from \"@/components/beui/components/agents/citations\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport { EASE_OUT, SPRING_PRESS, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type StreamingResponseStatus = \"streaming\" | \"complete\" | \"error\";\nexport type StreamingResponseFeedback = \"up\" | \"down\" | null;\n\nexport interface StreamingResponseProps {\n  /** Rendered response content. Pass plain text or the output of a Markdown renderer. */\n  children: ReactNode;\n  status?: StreamingResponseStatus;\n  /** Plain-text value copied by the built-in copy action. */\n  copyText?: string;\n  /** Overrides the built-in clipboard action. */\n  onCopy?: () => void | Promise<void>;\n  onRetry?: () => void;\n  /** Optional sources shown as a compact footer disclosure after streaming. */\n  sources?: CitationItem[];\n  sourcesOpen?: boolean;\n  defaultSourcesOpen?: boolean;\n  onSourcesOpenChange?: (open: boolean) => void;\n  sourceIdPrefix?: string;\n  feedback?: StreamingResponseFeedback;\n  defaultFeedback?: StreamingResponseFeedback;\n  onFeedbackChange?: (feedback: StreamingResponseFeedback) => void;\n  /** Set false when a surrounding conversation log announces streamed text. */\n  announce?: boolean;\n  /** Hides the built-in completion actions without changing response status. */\n  showActions?: boolean;\n  className?: string;\n  contentClassName?: string;\n  actionsClassName?: string;\n}\n\nfunction ResponseAction({\n  label,\n  active = false,\n  onClick,\n  children,\n}: {\n  label: string;\n  active?: boolean;\n  onClick: () => void;\n  children: ReactNode;\n}) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.button\n      type=\"button\"\n      aria-label={label}\n      title={label}\n      aria-pressed={label === \"Helpful\" || label === \"Not helpful\" ? active : undefined}\n      onClick={onClick}\n      whileTap={reduce ? undefined : { scale: 0.9 }}\n      transition={SPRING_PRESS}\n      className={cn(\n        \"grid size-7 place-items-center rounded-md text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\",\n        active && \"bg-muted text-foreground\",\n      )}\n    >\n      {children}\n    </motion.button>\n  );\n}\n\nexport function StreamingResponse({\n  children,\n  status = \"streaming\",\n  copyText,\n  onCopy,\n  onRetry,\n  sources = [],\n  sourcesOpen,\n  defaultSourcesOpen = false,\n  onSourcesOpenChange,\n  sourceIdPrefix,\n  feedback,\n  defaultFeedback = null,\n  onFeedbackChange,\n  announce = true,\n  showActions = true,\n  className,\n  contentClassName,\n  actionsClassName,\n}: StreamingResponseProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const [copied, setCopied] = useState(false);\n  const [internalFeedback, setInternalFeedback] =\n    useState<StreamingResponseFeedback>(defaultFeedback);\n  const [internalSourcesOpen, setInternalSourcesOpen] =\n    useState(defaultSourcesOpen);\n  const copyTimer = useRef<number | undefined>(undefined);\n  const currentFeedback = feedback ?? internalFeedback;\n  const currentSourcesOpen = sourcesOpen ?? internalSourcesOpen;\n  const streaming = status === \"streaming\";\n  const complete = status === \"complete\";\n  const canCopy = Boolean(copyText || onCopy);\n  const hasSources = sources.length > 0;\n  const shouldShowActions =\n    showActions && !streaming && (canCopy || onRetry || complete || hasSources);\n  const sourcesContentId = `${baseId}-sources`;\n  const resolvedSourcePrefix =\n    sourceIdPrefix ?? `response-source-${baseId.replace(/:/g, \"\")}`;\n\n  useEffect(\n    () => () => {\n      if (copyTimer.current) window.clearTimeout(copyTimer.current);\n    },\n    [],\n  );\n\n  const handleCopy = useCallback(async () => {\n    if (onCopy) await onCopy();\n    else if (copyText) await navigator.clipboard?.writeText(copyText);\n\n    setCopied(true);\n    if (copyTimer.current) window.clearTimeout(copyTimer.current);\n    copyTimer.current = window.setTimeout(() => setCopied(false), 1600);\n  }, [copyText, onCopy]);\n\n  const setFeedback = (next: Exclude<StreamingResponseFeedback, null>) => {\n    const value = currentFeedback === next ? null : next;\n    if (feedback === undefined) setInternalFeedback(value);\n    onFeedbackChange?.(value);\n  };\n\n  const setSourcesOpen = useCallback(\n    (next: boolean) => {\n      if (sourcesOpen === undefined) setInternalSourcesOpen(next);\n      onSourcesOpenChange?.(next);\n    },\n    [onSourcesOpenChange, sourcesOpen],\n  );\n\n  return (\n    <div\n      data-state={status}\n      aria-busy={streaming}\n      className={cn(\"w-full\", className)}\n    >\n      <div\n        aria-live={announce ? \"polite\" : \"off\"}\n        className={cn(\n          \"text-sm leading-6 text-foreground/90 [&_a]:font-medium [&_a]:underline [&_a]:underline-offset-4 [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.9em] [&_ol]:my-3 [&_ol]:list-decimal [&_ol]:space-y-1 [&_ol]:pl-5 [&_p+p]:mt-3 [&_pre]:my-3 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:border [&_pre]:border-border [&_pre]:bg-muted/45 [&_pre]:p-3 [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_ul]:my-3 [&_ul]:list-disc [&_ul]:space-y-1 [&_ul]:pl-5\",\n          contentClassName,\n        )}\n      >\n        {children}\n      </div>\n\n      <AnimatePresence initial={false}>\n        {shouldShowActions ? (\n          <motion.div\n            initial={reduce ? { opacity: 0 } : { opacity: 0, y: 4 }}\n            animate={{ opacity: 1, y: 0 }}\n            exit={{ opacity: 0 }}\n            transition={{ duration: reduce ? 0.12 : 0.22, ease: EASE_OUT }}\n            className=\"mt-3\"\n          >\n            <div className={cn(\"flex items-center gap-0.5\", actionsClassName)}>\n              {canCopy ? (\n                <ResponseAction\n                  label={copied ? \"Copied\" : \"Copy response\"}\n                  onClick={handleCopy}\n                >\n                  {copied ? (\n                    <Check className=\"size-3.5\" />\n                  ) : (\n                    <Copy className=\"size-3.5\" />\n                  )}\n                </ResponseAction>\n              ) : null}\n              {onRetry ? (\n                <ResponseAction label=\"Retry response\" onClick={onRetry}>\n                  <RotateCcw className=\"size-3.5\" />\n                </ResponseAction>\n              ) : null}\n              {complete ? (\n                <>\n                  <ResponseAction\n                    label=\"Helpful\"\n                    active={currentFeedback === \"up\"}\n                    onClick={() => setFeedback(\"up\")}\n                  >\n                    <ThumbsUp className=\"size-3.5\" />\n                  </ResponseAction>\n                  <ResponseAction\n                    label=\"Not helpful\"\n                    active={currentFeedback === \"down\"}\n                    onClick={() => setFeedback(\"down\")}\n                  >\n                    <ThumbsDown className=\"size-3.5\" />\n                  </ResponseAction>\n                </>\n              ) : null}\n              {hasSources ? (\n                <button\n                  type=\"button\"\n                  aria-expanded={currentSourcesOpen}\n                  aria-controls={sourcesContentId}\n                  onClick={() => setSourcesOpen(!currentSourcesOpen)}\n                  className=\"group ml-1 inline-flex min-h-7 items-center gap-2 rounded-md px-1.5 text-xs text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n                >\n                  <CitationStack citations={sources} />\n                  <span className=\"tabular-nums\">\n                    {sources.length} {sources.length === 1 ? \"source\" : \"sources\"}\n                  </span>\n                  <motion.span\n                    aria-hidden=\"true\"\n                    animate={{ rotate: currentSourcesOpen ? 180 : 0 }}\n                    transition={reduce ? { duration: 0 } : SPRING_SWAP}\n                    className=\"text-muted-foreground/50 group-hover:text-muted-foreground\"\n                  >\n                    <ChevronDown className=\"size-3\" />\n                  </motion.span>\n                </button>\n              ) : null}\n            </div>\n\n            {hasSources ? (\n              <AgentDisclosure\n                id={sourcesContentId}\n                open={currentSourcesOpen}\n              >\n                <CitationList\n                  citations={sources}\n                  idPrefix={resolvedSourcePrefix}\n                  className=\"mt-2 rounded-lg bg-muted p-2\"\n                />\n              </AgentDisclosure>\n            ) : null}\n          </motion.div>\n        ) : null}\n      </AnimatePresence>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/citations.tsx",
          "target": "@components/beui/components/agents/citations.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\n/* eslint-disable @next/next/no-img-element */\n\nimport { BookOpenText, ChevronDown, ExternalLink, Globe2 } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useId,\n  useState,\n} from \"react\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport { EASE_OUT, SPRING_LAYOUT, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { useFavicon } from \"@/components/beui/lib/hooks/use-favicon\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface CitationItem {\n  id: string;\n  title: ReactNode;\n  domain?: ReactNode;\n  url?: string;\n}\n\nexport interface CitationsProps {\n  citations: CitationItem[];\n  title?: ReactNode;\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  idPrefix?: string;\n  className?: string;\n}\n\nexport interface CitationProps {\n  citationId: string;\n  index: number;\n  /** Must match the related Citations idPrefix. */\n  idPrefix: string;\n  className?: string;\n}\n\nexport interface CitationListProps {\n  citations: CitationItem[];\n  idPrefix?: string;\n  className?: string;\n}\n\nexport interface CitationStackProps {\n  citations: CitationItem[];\n  limit?: number;\n  className?: string;\n}\n\nfunction citationTargetId(prefix: string, citationId: string) {\n  return `${prefix}-${citationId.replace(/[^a-zA-Z0-9_-]/g, \"-\")}`;\n}\n\nexport function Citation({\n  citationId,\n  index,\n  idPrefix,\n  className,\n}: CitationProps) {\n  return (\n    <a\n      href={`#${citationTargetId(idPrefix, citationId)}`}\n      aria-label={`View citation ${index}`}\n      className={cn(\n        \"mx-0.5 inline-flex min-w-4 -translate-y-0.5 items-center justify-center rounded-md bg-muted/60 px-1 py-0.5 text-[10px] font-semibold leading-none text-muted-foreground no-underline outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\",\n        className,\n      )}\n    >\n      {index}\n    </a>\n  );\n}\n\nexport function CitationFavicon({\n  url,\n  className,\n}: {\n  url?: string;\n  className?: string;\n}) {\n  const favicon = useFavicon(url);\n\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={cn(\n        \"grid size-5 shrink-0 place-items-center text-muted-foreground\",\n        className,\n      )}\n    >\n      {favicon.src ? (\n        // biome-ignore lint/performance/noImgElement: Dynamic cross-site favicons keep this framework-agnostic registry component portable.\n        <img\n          ref={favicon.ref}\n          src={favicon.src}\n          alt=\"\"\n          width={16}\n          height={16}\n          referrerPolicy=\"no-referrer\"\n          className=\"size-4 rounded-sm object-contain\"\n        />\n      ) : (\n        <Globe2 className=\"size-3.5\" />\n      )}\n    </span>\n  );\n}\n\nexport function CitationStack({\n  citations,\n  limit = 3,\n  className,\n}: CitationStackProps) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={cn(\"flex -space-x-1.5\", className)}\n    >\n      {citations.slice(0, limit).map((citation) => (\n        <CitationFavicon\n          key={citation.id}\n          url={citation.url}\n          className=\"size-6 rounded-full bg-background ring-2 ring-background\"\n        />\n      ))}\n    </span>\n  );\n}\n\nfunction CitationRow({\n  citation,\n  index,\n  idPrefix,\n}: {\n  citation: CitationItem;\n  index: number;\n  idPrefix: string;\n}) {\n  const content = (\n    <>\n      <CitationFavicon url={citation.url} />\n      <span className=\"flex min-w-0 flex-1 flex-wrap items-baseline gap-x-2 gap-y-0.5\">\n        <span className=\"truncate text-sm font-medium text-foreground/80 transition-colors group-hover/citation:text-foreground\">\n          {citation.title}\n        </span>\n        {citation.domain ? (\n          <span className=\"min-w-0 truncate text-xs text-muted-foreground/60\">\n            {citation.domain}\n          </span>\n        ) : null}\n      </span>\n      <span className=\"flex shrink-0 items-center gap-1.5\">\n        <span className=\"grid size-5 place-items-center rounded-md bg-foreground/[0.05] text-[10px] font-semibold tabular-nums text-muted-foreground\">\n          {index}\n        </span>\n        {citation.url ? (\n          <ExternalLink className=\"size-3.5 text-muted-foreground/40 transition-colors group-hover/citation:text-muted-foreground\" />\n        ) : null}\n      </span>\n    </>\n  );\n  const className =\n    \"group/citation flex items-center gap-2 rounded-md px-1.5 py-1 outline-none focus-visible:ring-2 focus-visible:ring-ring\";\n  const id = citationTargetId(idPrefix, citation.id);\n\n  return citation.url ? (\n    <a\n      id={id}\n      href={citation.url}\n      target=\"_blank\"\n      rel=\"noreferrer noopener\"\n      className={className}\n    >\n      {content}\n    </a>\n  ) : (\n    <div id={id} className={className}>\n      {content}\n    </div>\n  );\n}\n\nexport function CitationList({\n  citations,\n  idPrefix,\n  className,\n}: CitationListProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const resolvedPrefix =\n    idPrefix ?? `citation-list-${baseId.replace(/:/g, \"\")}`;\n\n  return (\n    <div className={cn(\"grid gap-0.5\", className)}>\n      <AnimatePresence mode=\"popLayout\">\n        {citations.map((citation, index) => (\n          <motion.div\n            layout=\"position\"\n            key={citation.id}\n            initial={reduce ? { opacity: 1 } : { opacity: 0, y: 6 }}\n            animate={{ opacity: 1, y: 0 }}\n            exit={reduce ? { opacity: 0 } : { opacity: 0, y: -3 }}\n            transition={\n              reduce\n                ? { duration: 0 }\n                : {\n                    opacity: { duration: 0.18, ease: EASE_OUT },\n                    y: SPRING_LAYOUT,\n                    layout: SPRING_LAYOUT,\n                  }\n            }\n          >\n            <CitationRow\n              citation={citation}\n              index={index + 1}\n              idPrefix={resolvedPrefix}\n            />\n          </motion.div>\n        ))}\n      </AnimatePresence>\n    </div>\n  );\n}\n\nexport function Citations({\n  citations,\n  title = \"Sources\",\n  open,\n  defaultOpen = false,\n  onOpenChange,\n  idPrefix,\n  className,\n}: CitationsProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const contentId = `${baseId}-content`;\n  const resolvedPrefix =\n    idPrefix ?? `citation-${baseId.replace(/:/g, \"\")}`;\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const currentOpen = open ?? internalOpen;\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [onOpenChange, open],\n  );\n\n  return (\n    <div className={cn(\"w-full text-sm\", className)}>\n      <button\n        type=\"button\"\n        aria-expanded={currentOpen}\n        aria-controls={contentId}\n        onClick={() => setOpen(!currentOpen)}\n        className=\"group -ml-1 flex min-h-8 items-center gap-2 rounded-lg px-1 text-left text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n      >\n        <BookOpenText className=\"size-4\" />\n        <span className=\"font-medium\">{title}</span>\n        <span className=\"rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-semibold tabular-nums\">\n          {citations.length}\n        </span>\n        <motion.span\n          aria-hidden=\"true\"\n          animate={{ rotate: currentOpen ? 180 : 0 }}\n          transition={reduce ? { duration: 0 } : SPRING_SWAP}\n          className=\"text-muted-foreground/60\"\n        >\n          <ChevronDown className=\"size-3.5\" />\n        </motion.span>\n      </button>\n\n      <AgentDisclosure\n        id={contentId}\n        open={currentOpen}\n      >\n        <CitationList\n          citations={citations}\n          idPrefix={resolvedPrefix}\n          className=\"mt-1\"\n        />\n      </AgentDisclosure>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-disclosure.tsx",
          "target": "@components/beui/components/agents/agent-disclosure.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, type HTMLMotionProps, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface AgentDisclosureProps\n  extends Omit<HTMLMotionProps<\"div\">, \"animate\" | \"initial\"> {\n  open: boolean;\n  openHeight?: CSSProperties[\"height\"];\n}\n\n/** Shared transform-only reveal for collapsible agent content. */\nexport function AgentDisclosure({\n  open,\n  openHeight = \"auto\",\n  className,\n  style,\n  transition,\n  ...props\n}: AgentDisclosureProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.div\n      {...props}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        reduce\n          ? { opacity: open ? 1 : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              clipPath: open ? \"inset(0 0 0% 0)\" : \"inset(0 0 100% 0)\",\n              y: open ? 0 : -4,\n            }\n      }\n      transition={\n        transition ?? {\n          duration: reduce ? 0 : open ? 0.22 : 0.14,\n          ease: EASE_OUT,\n        }\n      }\n      className={cn(\"overflow-hidden\", className)}\n      style={{\n        ...style,\n        height: open ? openHeight : 0,\n        pointerEvents: open ? undefined : \"none\",\n        transformOrigin: \"top\",\n      }}\n    />\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/lib/hooks/use-favicon.ts",
          "target": "@components/beui/lib/hooks/use-favicon.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useCallback, useState } from \"react\";\nimport { getFaviconUrl } from \"@/components/beui/lib/favicon\";\n\n/**\n * Resolves a site favicon and drops it once it is known to be unusable, so\n * callers can draw their own glyph instead of a broken image. Plenty of sites\n * answer `/favicon.ico` with a 403 or 404, and `onError` is not enough to catch\n * it: an image the browser starts loading from server-rendered HTML usually\n * fails before React attaches a handler, and that event is never replayed.\n * `decode()` settles on the image's final state instead of relying on an event\n * firing at the right moment.\n */\nexport function useFavicon(url?: string) {\n  const resolved = url ? getFaviconUrl(url) : null;\n  const [failedSrc, setFailedSrc] = useState<string | null>(null);\n  const src = resolved && resolved !== failedSrc ? resolved : null;\n\n  const ref = useCallback(\n    (img: HTMLImageElement | null) => {\n      if (!img || !src) return;\n\n      let released = false;\n      img.decode().catch(() => {\n        if (!released) setFailedSrc(src);\n      });\n\n      // The node is going away or the source changed; a late rejection then\n      // describes an image we are no longer showing.\n      return () => {\n        released = true;\n      };\n    },\n    [src],\n  );\n\n  return { src, ref };\n}\n"
        },
        {
          "path": "components/beui/lib/favicon.ts",
          "target": "@components/beui/lib/favicon.ts",
          "type": "registry:component",
          "content": "/** Resolve a website URL to its conventional root favicon location. */\nexport function getFaviconUrl(value: string) {\n  try {\n    return new URL(\"/favicon.ico\", value).toString();\n  } catch {\n    return null;\n  }\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-image-generation",
      "type": "registry:block",
      "title": "Beui Image Generation",
      "description": "Image Generation",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/image-generation.tsx",
          "target": "@components/beui/components/agents/image-generation.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Check, CircleAlert, RotateCcw } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { useEffect, useRef } from \"react\";\nimport { EASE_IN_OUT, EASE_OUT, SPRING_PRESS } from \"@/components/beui/lib/ease\";\nimport { useHoverCapable } from \"@/components/beui/lib/hooks/use-hover-capable\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type ImageGenerationStatus =\n  | \"queued\"\n  | \"generating\"\n  | \"refining\"\n  | \"complete\"\n  | \"error\";\n\nexport interface ImageGenerationProps {\n  /** The completed media. Pass an img, Next Image, canvas, video, or custom preview. */\n  children?: ReactNode;\n  status?: ImageGenerationStatus;\n  /** Accessible description. Defaults to a description derived from prompt. */\n  label?: string;\n  prompt?: string;\n  resolution?: string;\n  /** CSS aspect ratio reserved before generated media is available. */\n  aspectRatio?: CSSProperties[\"aspectRatio\"];\n  size?: \"compact\" | \"fluid\";\n  /** Lets the active dither cluster follow fine-pointer movement. */\n  interactive?: boolean;\n  statusText?: string;\n  showStatus?: boolean;\n  onRetry?: () => void;\n  className?: string;\n  mediaClassName?: string;\n  statusClassName?: string;\n}\n\nconst STATUS_TEXT: Record<ImageGenerationStatus, string> = {\n  queued: \"Waiting to generate\",\n  generating: \"Generating image\",\n  refining: \"Refining details\",\n  complete: \"Image ready\",\n  error: \"Generation failed\",\n};\n\nconst MEDIA_STATE: Record<\n  ImageGenerationStatus,\n  { filter: string; opacity: number; scale: number }\n> = {\n  queued: { filter: \"blur(4px) saturate(0.75)\", opacity: 0, scale: 1.02 },\n  generating: { filter: \"blur(3px) saturate(0.85)\", opacity: 0, scale: 1.015 },\n  refining: { filter: \"blur(1.5px) saturate(0.95)\", opacity: 0.62, scale: 1.005 },\n  complete: { filter: \"blur(0px) saturate(1)\", opacity: 1, scale: 1 },\n  error: { filter: \"blur(2px) saturate(0.5)\", opacity: 0.28, scale: 1 },\n};\n\nconst OVERLAY_OPACITY: Record<ImageGenerationStatus, number> = {\n  queued: 1,\n  generating: 1,\n  refining: 0.48,\n  complete: 0,\n  error: 0,\n};\n\nconst DOT_GAP = 10;\nconst TWO_PI = Math.PI * 2;\n\nfunction DitherMark({\n  status,\n  reduce,\n}: {\n  status: ImageGenerationStatus;\n  reduce: boolean;\n}) {\n  if (status === \"complete\") {\n    return <Check aria-hidden=\"true\" className=\"size-3.5\" />;\n  }\n\n  if (status === \"error\") {\n    return <CircleAlert aria-hidden=\"true\" className=\"size-3.5\" />;\n  }\n\n  return (\n    <motion.span\n      aria-hidden=\"true\"\n      animate={reduce ? undefined : { rotate: 360 }}\n      transition={{\n        duration: 2.4,\n        ease: EASE_IN_OUT,\n        repeat: Number.POSITIVE_INFINITY,\n      }}\n      className=\"grid size-3.5 grid-cols-2 place-items-center gap-0.5\"\n    >\n      <span className=\"size-1 rounded-[1px] bg-current\" />\n      <span className=\"size-1 rounded-[1px] bg-current opacity-55\" />\n      <span className=\"size-1 rounded-[1px] bg-current opacity-55\" />\n      <span className=\"size-1 rounded-[1px] bg-current\" />\n    </motion.span>\n  );\n}\n\nfunction DitherField({\n  interactive,\n  reduce,\n  status,\n}: {\n  interactive: boolean;\n  reduce: boolean;\n  status: ImageGenerationStatus;\n}) {\n  const canHover = useHoverCapable();\n  const canvasRef = useRef<HTMLCanvasElement>(null);\n\n  useEffect(() => {\n    const canvas = canvasRef.current;\n    const context = canvas?.getContext(\"2d\");\n    if (!canvas || !context) return;\n\n    let frame = 0;\n    let width = 0;\n    let height = 0;\n    let dotColor = \"currentColor\";\n    const pointer = {\n      x: 0,\n      y: 0,\n      targetX: 0,\n      targetY: 0,\n      inside: false,\n    };\n    const pointerEnabled = interactive && canHover && !reduce;\n\n    const resize = () => {\n      const rect = canvas.getBoundingClientRect();\n      width = rect.width || canvas.clientWidth || 208;\n      height = rect.height || canvas.clientHeight || 208;\n      const dpr = Math.min(window.devicePixelRatio || 1, 2);\n\n      canvas.width = Math.round(width * dpr);\n      canvas.height = Math.round(height * dpr);\n      context.setTransform(dpr, 0, 0, dpr, 0, 0);\n      dotColor = window.getComputedStyle(canvas).color;\n      pointer.x = width / 2;\n      pointer.y = height / 2;\n      pointer.targetX = pointer.x;\n      pointer.targetY = pointer.y;\n    };\n\n    const draw = (time: number) => {\n      context.clearRect(0, 0, width, height);\n\n      if (!pointer.inside) {\n        pointer.targetX =\n          width / 2 + (reduce ? 0 : Math.sin(time / 1700) * width * 0.12);\n        pointer.targetY =\n          height / 2 + (reduce ? 0 : Math.cos(time / 2100) * height * 0.1);\n      }\n\n      const follow = reduce ? 1 : pointer.inside ? 0.16 : 0.045;\n      pointer.x += (pointer.targetX - pointer.x) * follow;\n      pointer.y += (pointer.targetY - pointer.y) * follow;\n\n      const radius = Math.min(width, height) * 0.38;\n      const columns = Math.ceil(width / DOT_GAP) + 1;\n      const rows = Math.ceil(height / DOT_GAP) + 1;\n      const offsetX = (width - (columns - 1) * DOT_GAP) / 2;\n      const offsetY = (height - (rows - 1) * DOT_GAP) / 2;\n\n      context.fillStyle = dotColor;\n\n      for (let row = 0; row < rows; row += 1) {\n        for (let column = 0; column < columns; column += 1) {\n          const anchorX = offsetX + column * DOT_GAP;\n          const anchorY = offsetY + row * DOT_GAP;\n          const deltaX = anchorX - pointer.x;\n          const deltaY = anchorY - pointer.y;\n          const distance = Math.hypot(deltaX, deltaY);\n          const proximity = Math.max(0, 1 - distance / radius);\n          const influence = proximity * proximity * (3 - 2 * proximity);\n          const displacement = influence * influence * 9;\n          const directionX = distance > 0 ? deltaX / distance : 0;\n          const directionY = distance > 0 ? deltaY / distance : 0;\n          const x = anchorX + directionX * displacement;\n          const y = anchorY + directionY * displacement;\n          const dotRadius = 0.65 + influence * 0.85;\n\n          context.globalAlpha = 0.17 + influence * 0.72;\n          context.beginPath();\n          context.arc(x, y, dotRadius, 0, TWO_PI);\n          context.fill();\n        }\n      }\n\n      context.globalAlpha = 1;\n      if (!reduce) frame = window.requestAnimationFrame(draw);\n    };\n\n    const handlePointerMove = (event: PointerEvent) => {\n      if (!pointerEnabled) return;\n      const rect = canvas.getBoundingClientRect();\n      pointer.inside = true;\n      pointer.targetX = event.clientX - rect.left;\n      pointer.targetY = event.clientY - rect.top;\n    };\n\n    const handlePointerLeave = () => {\n      pointer.inside = false;\n    };\n\n    const resizeObserver =\n      typeof ResizeObserver === \"undefined\"\n        ? null\n        : new ResizeObserver(resize);\n\n    resize();\n    resizeObserver?.observe(canvas);\n    canvas.addEventListener(\"pointermove\", handlePointerMove, { passive: true });\n    canvas.addEventListener(\"pointerleave\", handlePointerLeave);\n    draw(0);\n\n    return () => {\n      if (frame) window.cancelAnimationFrame(frame);\n      resizeObserver?.disconnect();\n      canvas.removeEventListener(\"pointermove\", handlePointerMove);\n      canvas.removeEventListener(\"pointerleave\", handlePointerLeave);\n    };\n  }, [canHover, interactive, reduce]);\n\n  return (\n    <motion.div\n      aria-hidden=\"true\"\n      initial={false}\n      animate={{ opacity: OVERLAY_OPACITY[status] }}\n      transition={{ duration: reduce ? 0 : 0.4, ease: EASE_OUT }}\n      className=\"absolute inset-0 overflow-hidden bg-muted\"\n    >\n      <canvas\n        ref={canvasRef}\n        className=\"absolute inset-0 size-full text-foreground\"\n      />\n    </motion.div>\n  );\n}\n\nexport function ImageGeneration({\n  children,\n  status = \"generating\",\n  label,\n  prompt,\n  resolution = \"1024 × 1024\",\n  aspectRatio = \"1 / 1\",\n  size = \"compact\",\n  interactive = true,\n  statusText,\n  showStatus = true,\n  onRetry,\n  className,\n  mediaClassName,\n  statusClassName,\n}: ImageGenerationProps) {\n  const reduce = useReducedMotion() ?? false;\n  const active =\n    status === \"queued\" || status === \"generating\" || status === \"refining\";\n  const mediaState = MEDIA_STATE[status];\n  const resolvedStatusText = statusText ?? STATUS_TEXT[status];\n  const resolvedLabel =\n    label ?? (prompt ? `${resolvedStatusText}: ${prompt}` : resolvedStatusText);\n\n  return (\n    <div\n      data-slot=\"image-generation\"\n      data-state={status}\n      aria-busy={active}\n      className={cn(\"w-full\", className)}\n    >\n      <div\n        className={cn(\n          \"w-full\",\n          size === \"compact\" && \"mx-auto max-w-52\",\n        )}\n      >\n        <div\n          role=\"img\"\n          aria-label={resolvedLabel}\n          style={{ aspectRatio }}\n          className=\"relative isolate w-full overflow-hidden rounded-xl bg-muted\"\n        >\n          <motion.div\n            aria-hidden={children ? undefined : true}\n            initial={false}\n            animate={\n              reduce\n                ? { opacity: mediaState.opacity }\n                : {\n                    filter: mediaState.filter,\n                    opacity: mediaState.opacity,\n                    scale: mediaState.scale,\n                  }\n            }\n            transition={\n              reduce ? { duration: 0 } : { duration: 0.4, ease: EASE_OUT }\n            }\n            className={cn(\n              \"absolute inset-0 [&>*]:size-full [&>*]:object-cover [&_img]:size-full [&_img]:object-cover\",\n              mediaClassName,\n            )}\n          >\n            {children}\n          </motion.div>\n\n          <AnimatePresence initial={false}>\n            {active ? (\n              <motion.div\n                key=\"dither-field\"\n                initial={{ opacity: 0 }}\n                animate={{ opacity: 1 }}\n                exit={{ opacity: 0 }}\n                transition={{ duration: reduce ? 0 : 0.25, ease: EASE_OUT }}\n                className=\"absolute inset-0\"\n              >\n                <DitherField\n                  interactive={interactive}\n                  reduce={reduce}\n                  status={status}\n                />\n              </motion.div>\n            ) : null}\n          </AnimatePresence>\n\n          {resolution ? (\n            <span className=\"absolute top-2 right-2 z-10 rounded-full bg-background/75 px-2 py-0.5 font-mono text-[10px] tabular-nums text-muted-foreground\">\n              {resolution}\n            </span>\n          ) : null}\n        </div>\n\n        {showStatus || prompt ? (\n          <div className=\"mt-3 text-left\">\n            {showStatus ? (\n              <div\n                aria-live=\"polite\"\n                className={cn(\n                  \"flex min-h-5 items-center gap-2 text-sm font-medium text-foreground\",\n                  status === \"error\" && \"text-destructive\",\n                  statusClassName,\n                )}\n              >\n                <DitherMark status={status} reduce={reduce} />\n                <AnimatePresence mode=\"popLayout\" initial={false}>\n                  <motion.span\n                    key={resolvedStatusText}\n                    initial={reduce ? false : { opacity: 0, y: 4 }}\n                    animate={{ opacity: 1, y: 0 }}\n                    exit={reduce ? undefined : { opacity: 0, y: -4 }}\n                    transition={{\n                      duration: reduce ? 0 : 0.15,\n                      ease: EASE_OUT,\n                    }}\n                  >\n                    {resolvedStatusText}\n                  </motion.span>\n                </AnimatePresence>\n              </div>\n            ) : null}\n            {prompt ? (\n              <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n                “{prompt}”\n              </p>\n            ) : null}\n          </div>\n        ) : null}\n\n        {status === \"error\" && onRetry ? (\n          <motion.button\n            type=\"button\"\n            onClick={onRetry}\n            whileTap={reduce ? undefined : { scale: 0.96 }}\n            transition={SPRING_PRESS}\n            className=\"mt-3 inline-flex min-h-10 items-center gap-2 rounded-full px-3 text-sm font-medium text-foreground outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring\"\n          >\n            <RotateCcw aria-hidden=\"true\" className=\"size-4\" />\n            Try again\n          </motion.button>\n        ) : null}\n      </div>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/hooks/use-hover-capable.ts",
          "target": "@components/beui/lib/hooks/use-hover-capable.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/**\n * Returns true only on devices that have a true hover (mouse / trackpad).\n * Touch devices fire phantom `:hover` on tap that sticks until tap-elsewhere\n * — gate hover-only effects (scale lifts, magnetic pulls) behind this.\n */\nexport function useHoverCapable() {\n  const [canHover, setCanHover] = useState(false);\n\n  useEffect(() => {\n    if (typeof window === \"undefined\" || !window.matchMedia) return;\n    const mq = window.matchMedia(\"(hover: hover) and (pointer: fine)\");\n    const update = () => setCanHover(mq.matches);\n    update();\n    mq.addEventListener?.(\"change\", update);\n    return () => mq.removeEventListener?.(\"change\", update);\n  }, []);\n\n  return canHover;\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-tool-approval",
      "type": "registry:block",
      "title": "Beui Tool Approval",
      "description": "Tool Approval",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "shiki@^3.0.0",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/tool-approval.tsx",
          "target": "@components/beui/components/agents/tool-approval.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  Check,\n  ChevronDown,\n  CircleAlert,\n  LoaderCircle,\n  ShieldCheck,\n  X,\n} from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useEffect,\n  useId,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  AgentCode,\n  type AgentCodeLanguage,\n} from \"@/components/beui/components/agents/agent-code\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport { EASE_OUT, SPRING_PRESS, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type ToolApprovalStatus =\n  | \"pending\"\n  | \"approving\"\n  | \"approved\"\n  | \"denied\"\n  | \"running\"\n  | \"complete\"\n  | \"error\";\n\nexport interface ToolApprovalParameter {\n  id: string;\n  label: ReactNode;\n  value: ReactNode;\n}\n\nexport interface ToolApprovalCodeProps {\n  code: string;\n  language?: AgentCodeLanguage;\n  className?: string;\n}\n\nexport interface ToolApprovalProps {\n  tool: ReactNode;\n  title?: ReactNode;\n  description?: ReactNode;\n  parameters?: ToolApprovalParameter[];\n  status?: ToolApprovalStatus;\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  onApprove?: () => void;\n  onAlwaysAllow?: () => void;\n  onDeny?: () => void;\n  className?: string;\n}\n\nfunction getStatusCopy(status: ToolApprovalStatus) {\n  if (status === \"approving\") return \"Approving\";\n  if (status === \"approved\") return \"Approved\";\n  if (status === \"denied\") return \"Denied\";\n  if (status === \"running\") return \"Running\";\n  if (status === \"complete\") return \"Completed\";\n  if (status === \"error\") return \"Failed\";\n  return \"Approval required\";\n}\n\nfunction getStatusBadgeClass(status: ToolApprovalStatus) {\n  if (status === \"pending\") {\n    return \"border-amber-500/30 bg-amber-500/10 text-amber-600 dark:text-amber-400\";\n  }\n  if (status === \"approving\" || status === \"running\") {\n    return \"border-blue-500/30 bg-blue-500/10 text-blue-600 dark:text-blue-400\";\n  }\n  if (status === \"approved\" || status === \"complete\") {\n    return \"border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400\";\n  }\n  return \"border-rose-500/30 bg-rose-500/10 text-rose-600 dark:text-rose-400\";\n}\n\nexport function ToolApprovalCode({\n  code,\n  language = \"bash\",\n  className,\n}: ToolApprovalCodeProps) {\n  return (\n    <AgentCode\n      code={code}\n      language={language}\n      className={cn(\n        // Parameter values sit in a narrow grid column with nowhere to scroll\n        // on touch, so they wrap instead of clipping (as ToolResultOutput does).\n        \"whitespace-pre-wrap break-words rounded-lg border border-border/50 bg-muted/30 px-2.5 py-2\",\n        className,\n      )}\n    />\n  );\n}\n\nexport function ToolApproval({\n  tool,\n  title = \"Allow this tool to run?\",\n  description,\n  parameters = [],\n  status = \"pending\",\n  open,\n  defaultOpen = false,\n  onOpenChange,\n  onApprove,\n  onAlwaysAllow,\n  onDeny,\n  className,\n}: ToolApprovalProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const detailsId = `${baseId}-details`;\n  const previousStatus = useRef(status);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const currentOpen = open ?? internalOpen;\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [onOpenChange, open],\n  );\n  const busy = status === \"approving\" || status === \"running\";\n  const pending = status === \"pending\";\n  const error = status === \"error\";\n\n  useEffect(() => {\n    if (previousStatus.current === \"pending\" && status !== \"pending\") {\n      setOpen(false);\n    }\n    previousStatus.current = status;\n  }, [setOpen, status]);\n\n  return (\n    <div\n      data-state={status}\n      aria-busy={busy}\n      className={cn(\n        \"w-full overflow-hidden rounded-lg border border-border/60 bg-muted/20 text-sm\",\n        className,\n      )}\n    >\n      <div className=\"flex items-start gap-3 p-4\">\n        <span\n          aria-hidden=\"true\"\n          className={cn(\n            \"mt-0.5 grid size-8 shrink-0 place-items-center rounded-md border border-border/60 bg-background text-muted-foreground\",\n            error && \"text-destructive\",\n          )}\n        >\n          {busy ? (\n            <LoaderCircle className={cn(\"size-4\", !reduce && \"animate-spin\")} />\n          ) : error ? (\n            <CircleAlert className=\"size-4\" />\n          ) : status === \"denied\" ? (\n            <X className=\"size-4\" />\n          ) : status === \"approved\" || status === \"complete\" ? (\n            <Check className=\"size-4\" />\n          ) : (\n            <ShieldCheck className=\"size-4\" />\n          )}\n        </span>\n\n        <div className=\"min-w-0 flex-1\">\n          <div className=\"flex min-w-0 items-start justify-between gap-3\">\n            <div className=\"min-w-0\">\n              <div className=\"font-medium text-foreground\">{title}</div>\n              <div className=\"mt-0.5 truncate font-mono text-xs text-muted-foreground\">\n                {tool}\n              </div>\n            </div>\n            <span\n              className={cn(\n                \"shrink-0 rounded-full border px-2 py-0.5 text-[11px] font-medium transition-colors\",\n                getStatusBadgeClass(status),\n              )}\n            >\n              {getStatusCopy(status)}\n            </span>\n          </div>\n          {description ? (\n            <p className=\"mt-2 leading-5 text-muted-foreground\">{description}</p>\n          ) : null}\n\n          {parameters.length ? (\n            <button\n              type=\"button\"\n              aria-expanded={currentOpen}\n              aria-controls={detailsId}\n              onClick={() => setOpen(!currentOpen)}\n              className=\"mt-2 inline-flex items-center gap-1 rounded-md text-xs font-medium text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n            >\n              View details\n              <motion.span\n                aria-hidden=\"true\"\n                animate={{ rotate: currentOpen ? 180 : 0 }}\n                transition={reduce ? { duration: 0 } : SPRING_SWAP}\n              >\n                <ChevronDown className=\"size-3.5\" />\n              </motion.span>\n            </button>\n          ) : null}\n        </div>\n      </div>\n\n      <AgentDisclosure\n        id={detailsId}\n        open={currentOpen}\n      >\n        <dl className=\"mx-4 mb-4 grid gap-2 rounded-lg border border-border/50 bg-background/70 p-3\">\n          {parameters.map((parameter) => (\n            <div\n              key={parameter.id}\n              className=\"grid grid-cols-[minmax(0,7rem)_minmax(0,1fr)] items-center gap-3 text-xs\"\n            >\n              <dt className=\"text-muted-foreground\">{parameter.label}</dt>\n              <dd className=\"min-w-0 break-words font-mono text-foreground/85\">\n                {parameter.value}\n              </dd>\n            </div>\n          ))}\n        </dl>\n      </AgentDisclosure>\n\n      <AnimatePresence initial={false}>\n        {pending ? (\n          <motion.div\n            initial={reduce ? { opacity: 0 } : { opacity: 0, y: 4 }}\n            animate={{ opacity: 1, y: 0 }}\n            exit={{ opacity: 0 }}\n            transition={{ duration: reduce ? 0.12 : 0.22, ease: EASE_OUT }}\n            className=\"flex flex-wrap items-center gap-2 border-t border-border/60 px-4 py-3\"\n          >\n            <motion.button\n              type=\"button\"\n              onClick={onApprove}\n              whileTap={reduce ? undefined : { scale: 0.97 }}\n              transition={SPRING_PRESS}\n              className=\"rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n            >\n              Allow once\n            </motion.button>\n            {onAlwaysAllow ? (\n              <motion.button\n                type=\"button\"\n                onClick={onAlwaysAllow}\n                whileTap={reduce ? undefined : { scale: 0.97 }}\n                transition={SPRING_PRESS}\n                className=\"rounded-md border border-border/60 bg-background px-3 py-1.5 text-xs font-medium text-foreground outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring\"\n              >\n                Always allow\n              </motion.button>\n            ) : null}\n            <button\n              type=\"button\"\n              onClick={onDeny}\n              className=\"rounded-md px-3 py-1.5 text-xs font-medium text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n            >\n              Deny\n            </button>\n          </motion.div>\n        ) : null}\n      </AnimatePresence>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-code.tsx",
          "target": "@components/beui/components/agents/agent-code.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  type CSSProperties,\n  Fragment,\n  useEffect,\n  useState,\n} from \"react\";\nimport { createHighlighter, type Highlighter } from \"shiki\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type AgentCodeLanguage =\n  | \"bash\"\n  | \"diff\"\n  | \"json\"\n  | \"text\"\n  | \"tsx\"\n  | \"typescript\";\n\nexport interface AgentCodeToken {\n  content: string;\n  offset: number;\n  light?: string;\n  dark?: string;\n}\n\nexport type AgentCodeTokenLines = AgentCodeToken[][];\n\nexport interface AgentCodeProps {\n  code: string;\n  language?: AgentCodeLanguage;\n  className?: string;\n}\n\nexport interface AgentCodeLineProps {\n  code: string;\n  tokens?: AgentCodeToken[];\n  className?: string;\n}\n\nconst LIGHT_THEME = \"github-light-high-contrast\";\nconst DARK_THEME = \"github-dark-high-contrast\";\nlet agentCodeHighlighter: Promise<Highlighter> | null = null;\nconst tokenCache = new Map<string, AgentCodeTokenLines>();\n\nfunction getAgentCodeHighlighter() {\n  if (!agentCodeHighlighter) {\n    agentCodeHighlighter = createHighlighter({\n      themes: [LIGHT_THEME, DARK_THEME],\n      langs: [\"bash\", \"diff\", \"json\", \"tsx\", \"typescript\"],\n    });\n  }\n  return agentCodeHighlighter;\n}\n\nfunction tokenCacheKey(code: string, language: AgentCodeLanguage) {\n  return `${language}\\u0000${code}`;\n}\n\nexport function useAgentCodeTokens(\n  code: string,\n  language: AgentCodeLanguage,\n) {\n  const key = tokenCacheKey(code, language);\n  const cached = tokenCache.get(key);\n  const [result, setResult] = useState<{\n    key: string;\n    code: string;\n    language: AgentCodeLanguage;\n    lines: AgentCodeTokenLines;\n  } | null>(cached ? { key, code, language, lines: cached } : null);\n\n  useEffect(() => {\n    const current = tokenCache.get(key);\n    if (current) {\n      setResult({ key, code, language, lines: current });\n      return;\n    }\n\n    let cancelled = false;\n    getAgentCodeHighlighter().then((highlighter) => {\n      if (cancelled) return;\n      const lines = highlighter\n        .codeToTokensWithThemes(code, {\n          lang: language,\n          themes: {\n            light: LIGHT_THEME,\n            dark: DARK_THEME,\n          },\n        })\n        .map((line) =>\n          line.map((token) => ({\n            content: token.content,\n            offset: token.offset,\n            light: token.variants.light?.color,\n            dark: token.variants.dark?.color,\n          })),\n      );\n      tokenCache.set(key, lines);\n      setResult({ key, code, language, lines });\n    });\n    return () => {\n      cancelled = true;\n    };\n  }, [code, key, language]);\n\n  if (result?.key === key) return result.lines;\n  if (result?.language === language && code.startsWith(result.code)) {\n    return result.lines;\n  }\n  return null;\n}\n\nexport function AgentCodeLine({\n  code,\n  tokens,\n  className,\n}: AgentCodeLineProps) {\n  return (\n    <span className={className}>\n      {tokens\n        ? tokens.map((token) => (\n            <span\n              key={`${token.offset}-${token.content}`}\n              style={\n                {\n                  \"--agent-code-light\": token.light ?? \"currentColor\",\n                  \"--agent-code-dark\": token.dark ?? token.light ?? \"currentColor\",\n                } as CSSProperties\n              }\n              className=\"text-[var(--agent-code-light)] dark:text-[var(--agent-code-dark)]\"\n            >\n              {token.content}\n            </span>\n          ))\n        : code}\n    </span>\n  );\n}\n\nexport function AgentCode({\n  code,\n  language = \"bash\",\n  className,\n}: AgentCodeProps) {\n  const tokens = useAgentCodeTokens(code, language);\n  let offset = 0;\n  const lines = code.split(\"\\n\").map((content) => {\n    const line = { content, offset };\n    offset += content.length + 1;\n    return line;\n  });\n\n  return (\n    <pre\n      className={cn(\n        \"m-0 overflow-x-auto whitespace-pre font-mono text-xs leading-5 text-foreground/85\",\n        className,\n      )}\n    >\n      <code>\n        {lines.map((line, index) => (\n          <Fragment key={line.offset}>\n            <AgentCodeLine code={line.content} tokens={tokens?.[index]} />\n            {index < lines.length - 1 ? \"\\n\" : null}\n          </Fragment>\n        ))}\n      </code>\n    </pre>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-disclosure.tsx",
          "target": "@components/beui/components/agents/agent-disclosure.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, type HTMLMotionProps, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface AgentDisclosureProps\n  extends Omit<HTMLMotionProps<\"div\">, \"animate\" | \"initial\"> {\n  open: boolean;\n  openHeight?: CSSProperties[\"height\"];\n}\n\n/** Shared transform-only reveal for collapsible agent content. */\nexport function AgentDisclosure({\n  open,\n  openHeight = \"auto\",\n  className,\n  style,\n  transition,\n  ...props\n}: AgentDisclosureProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.div\n      {...props}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        reduce\n          ? { opacity: open ? 1 : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              clipPath: open ? \"inset(0 0 0% 0)\" : \"inset(0 0 100% 0)\",\n              y: open ? 0 : -4,\n            }\n      }\n      transition={\n        transition ?? {\n          duration: reduce ? 0 : open ? 0.22 : 0.14,\n          ease: EASE_OUT,\n        }\n      }\n      className={cn(\"overflow-hidden\", className)}\n      style={{\n        ...style,\n        height: open ? openHeight : 0,\n        pointerEvents: open ? undefined : \"none\",\n        transformOrigin: \"top\",\n      }}\n    />\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-citations",
      "type": "registry:block",
      "title": "Beui Citations",
      "description": "Citations",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/citations.tsx",
          "target": "@components/beui/components/agents/citations.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\n/* eslint-disable @next/next/no-img-element */\n\nimport { BookOpenText, ChevronDown, ExternalLink, Globe2 } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useId,\n  useState,\n} from \"react\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport { EASE_OUT, SPRING_LAYOUT, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport { useFavicon } from \"@/components/beui/lib/hooks/use-favicon\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface CitationItem {\n  id: string;\n  title: ReactNode;\n  domain?: ReactNode;\n  url?: string;\n}\n\nexport interface CitationsProps {\n  citations: CitationItem[];\n  title?: ReactNode;\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  idPrefix?: string;\n  className?: string;\n}\n\nexport interface CitationProps {\n  citationId: string;\n  index: number;\n  /** Must match the related Citations idPrefix. */\n  idPrefix: string;\n  className?: string;\n}\n\nexport interface CitationListProps {\n  citations: CitationItem[];\n  idPrefix?: string;\n  className?: string;\n}\n\nexport interface CitationStackProps {\n  citations: CitationItem[];\n  limit?: number;\n  className?: string;\n}\n\nfunction citationTargetId(prefix: string, citationId: string) {\n  return `${prefix}-${citationId.replace(/[^a-zA-Z0-9_-]/g, \"-\")}`;\n}\n\nexport function Citation({\n  citationId,\n  index,\n  idPrefix,\n  className,\n}: CitationProps) {\n  return (\n    <a\n      href={`#${citationTargetId(idPrefix, citationId)}`}\n      aria-label={`View citation ${index}`}\n      className={cn(\n        \"mx-0.5 inline-flex min-w-4 -translate-y-0.5 items-center justify-center rounded-md bg-muted/60 px-1 py-0.5 text-[10px] font-semibold leading-none text-muted-foreground no-underline outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\",\n        className,\n      )}\n    >\n      {index}\n    </a>\n  );\n}\n\nexport function CitationFavicon({\n  url,\n  className,\n}: {\n  url?: string;\n  className?: string;\n}) {\n  const favicon = useFavicon(url);\n\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={cn(\n        \"grid size-5 shrink-0 place-items-center text-muted-foreground\",\n        className,\n      )}\n    >\n      {favicon.src ? (\n        // biome-ignore lint/performance/noImgElement: Dynamic cross-site favicons keep this framework-agnostic registry component portable.\n        <img\n          ref={favicon.ref}\n          src={favicon.src}\n          alt=\"\"\n          width={16}\n          height={16}\n          referrerPolicy=\"no-referrer\"\n          className=\"size-4 rounded-sm object-contain\"\n        />\n      ) : (\n        <Globe2 className=\"size-3.5\" />\n      )}\n    </span>\n  );\n}\n\nexport function CitationStack({\n  citations,\n  limit = 3,\n  className,\n}: CitationStackProps) {\n  return (\n    <span\n      aria-hidden=\"true\"\n      className={cn(\"flex -space-x-1.5\", className)}\n    >\n      {citations.slice(0, limit).map((citation) => (\n        <CitationFavicon\n          key={citation.id}\n          url={citation.url}\n          className=\"size-6 rounded-full bg-background ring-2 ring-background\"\n        />\n      ))}\n    </span>\n  );\n}\n\nfunction CitationRow({\n  citation,\n  index,\n  idPrefix,\n}: {\n  citation: CitationItem;\n  index: number;\n  idPrefix: string;\n}) {\n  const content = (\n    <>\n      <CitationFavicon url={citation.url} />\n      <span className=\"flex min-w-0 flex-1 flex-wrap items-baseline gap-x-2 gap-y-0.5\">\n        <span className=\"truncate text-sm font-medium text-foreground/80 transition-colors group-hover/citation:text-foreground\">\n          {citation.title}\n        </span>\n        {citation.domain ? (\n          <span className=\"min-w-0 truncate text-xs text-muted-foreground/60\">\n            {citation.domain}\n          </span>\n        ) : null}\n      </span>\n      <span className=\"flex shrink-0 items-center gap-1.5\">\n        <span className=\"grid size-5 place-items-center rounded-md bg-foreground/[0.05] text-[10px] font-semibold tabular-nums text-muted-foreground\">\n          {index}\n        </span>\n        {citation.url ? (\n          <ExternalLink className=\"size-3.5 text-muted-foreground/40 transition-colors group-hover/citation:text-muted-foreground\" />\n        ) : null}\n      </span>\n    </>\n  );\n  const className =\n    \"group/citation flex items-center gap-2 rounded-md px-1.5 py-1 outline-none focus-visible:ring-2 focus-visible:ring-ring\";\n  const id = citationTargetId(idPrefix, citation.id);\n\n  return citation.url ? (\n    <a\n      id={id}\n      href={citation.url}\n      target=\"_blank\"\n      rel=\"noreferrer noopener\"\n      className={className}\n    >\n      {content}\n    </a>\n  ) : (\n    <div id={id} className={className}>\n      {content}\n    </div>\n  );\n}\n\nexport function CitationList({\n  citations,\n  idPrefix,\n  className,\n}: CitationListProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const resolvedPrefix =\n    idPrefix ?? `citation-list-${baseId.replace(/:/g, \"\")}`;\n\n  return (\n    <div className={cn(\"grid gap-0.5\", className)}>\n      <AnimatePresence mode=\"popLayout\">\n        {citations.map((citation, index) => (\n          <motion.div\n            layout=\"position\"\n            key={citation.id}\n            initial={reduce ? { opacity: 1 } : { opacity: 0, y: 6 }}\n            animate={{ opacity: 1, y: 0 }}\n            exit={reduce ? { opacity: 0 } : { opacity: 0, y: -3 }}\n            transition={\n              reduce\n                ? { duration: 0 }\n                : {\n                    opacity: { duration: 0.18, ease: EASE_OUT },\n                    y: SPRING_LAYOUT,\n                    layout: SPRING_LAYOUT,\n                  }\n            }\n          >\n            <CitationRow\n              citation={citation}\n              index={index + 1}\n              idPrefix={resolvedPrefix}\n            />\n          </motion.div>\n        ))}\n      </AnimatePresence>\n    </div>\n  );\n}\n\nexport function Citations({\n  citations,\n  title = \"Sources\",\n  open,\n  defaultOpen = false,\n  onOpenChange,\n  idPrefix,\n  className,\n}: CitationsProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const contentId = `${baseId}-content`;\n  const resolvedPrefix =\n    idPrefix ?? `citation-${baseId.replace(/:/g, \"\")}`;\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const currentOpen = open ?? internalOpen;\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (open === undefined) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [onOpenChange, open],\n  );\n\n  return (\n    <div className={cn(\"w-full text-sm\", className)}>\n      <button\n        type=\"button\"\n        aria-expanded={currentOpen}\n        aria-controls={contentId}\n        onClick={() => setOpen(!currentOpen)}\n        className=\"group -ml-1 flex min-h-8 items-center gap-2 rounded-lg px-1 text-left text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n      >\n        <BookOpenText className=\"size-4\" />\n        <span className=\"font-medium\">{title}</span>\n        <span className=\"rounded-full bg-muted px-1.5 py-0.5 text-[10px] font-semibold tabular-nums\">\n          {citations.length}\n        </span>\n        <motion.span\n          aria-hidden=\"true\"\n          animate={{ rotate: currentOpen ? 180 : 0 }}\n          transition={reduce ? { duration: 0 } : SPRING_SWAP}\n          className=\"text-muted-foreground/60\"\n        >\n          <ChevronDown className=\"size-3.5\" />\n        </motion.span>\n      </button>\n\n      <AgentDisclosure\n        id={contentId}\n        open={currentOpen}\n      >\n        <CitationList\n          citations={citations}\n          idPrefix={resolvedPrefix}\n          className=\"mt-1\"\n        />\n      </AgentDisclosure>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-disclosure.tsx",
          "target": "@components/beui/components/agents/agent-disclosure.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, type HTMLMotionProps, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface AgentDisclosureProps\n  extends Omit<HTMLMotionProps<\"div\">, \"animate\" | \"initial\"> {\n  open: boolean;\n  openHeight?: CSSProperties[\"height\"];\n}\n\n/** Shared transform-only reveal for collapsible agent content. */\nexport function AgentDisclosure({\n  open,\n  openHeight = \"auto\",\n  className,\n  style,\n  transition,\n  ...props\n}: AgentDisclosureProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.div\n      {...props}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        reduce\n          ? { opacity: open ? 1 : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              clipPath: open ? \"inset(0 0 0% 0)\" : \"inset(0 0 100% 0)\",\n              y: open ? 0 : -4,\n            }\n      }\n      transition={\n        transition ?? {\n          duration: reduce ? 0 : open ? 0.22 : 0.14,\n          ease: EASE_OUT,\n        }\n      }\n      className={cn(\"overflow-hidden\", className)}\n      style={{\n        ...style,\n        height: open ? openHeight : 0,\n        pointerEvents: open ? undefined : \"none\",\n        transformOrigin: \"top\",\n      }}\n    />\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/lib/hooks/use-favicon.ts",
          "target": "@components/beui/lib/hooks/use-favicon.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useCallback, useState } from \"react\";\nimport { getFaviconUrl } from \"@/components/beui/lib/favicon\";\n\n/**\n * Resolves a site favicon and drops it once it is known to be unusable, so\n * callers can draw their own glyph instead of a broken image. Plenty of sites\n * answer `/favicon.ico` with a 403 or 404, and `onError` is not enough to catch\n * it: an image the browser starts loading from server-rendered HTML usually\n * fails before React attaches a handler, and that event is never replayed.\n * `decode()` settles on the image's final state instead of relying on an event\n * firing at the right moment.\n */\nexport function useFavicon(url?: string) {\n  const resolved = url ? getFaviconUrl(url) : null;\n  const [failedSrc, setFailedSrc] = useState<string | null>(null);\n  const src = resolved && resolved !== failedSrc ? resolved : null;\n\n  const ref = useCallback(\n    (img: HTMLImageElement | null) => {\n      if (!img || !src) return;\n\n      let released = false;\n      img.decode().catch(() => {\n        if (!released) setFailedSrc(src);\n      });\n\n      // The node is going away or the source changed; a late rejection then\n      // describes an image we are no longer showing.\n      return () => {\n        released = true;\n      };\n    },\n    [src],\n  );\n\n  return { src, ref };\n}\n"
        },
        {
          "path": "components/beui/lib/favicon.ts",
          "target": "@components/beui/lib/favicon.ts",
          "type": "registry:component",
          "content": "/** Resolve a website URL to its conventional root favicon location. */\nexport function getFaviconUrl(value: string) {\n  try {\n    return new URL(\"/favicon.ico\", value).toString();\n  } catch {\n    return null;\n  }\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-agent-activity",
      "type": "registry:block",
      "title": "Beui Agent Activity",
      "description": "Agent Activity",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/agent-activity/index.tsx",
          "target": "@components/beui/components/agents/agent-activity/index.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { ChevronDown } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type ReactNode,\n  useCallback,\n  useEffect,\n  useId,\n  useLayoutEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport { ThinkingShimmer } from \"@/components/beui/components/agents/loading-states/thinking-shimmer\";\nimport { AgentDisclosure } from \"@/components/beui/components/agents/agent-disclosure\";\nimport {\n  EASE_OUT,\n  SPRING_LAYOUT,\n  SPRING_SWAP,\n} from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport { ActivityRow } from \"./activity-row\";\nimport type {\n  AgentActivityContentType,\n  AgentActivityItem,\n  AgentActivityProps,\n} from \"./types\";\n\nexport type {\n  AgentActivityContentType,\n  AgentActivityItem,\n  AgentActivityProps,\n  AgentActivitySearch,\n  AgentActivityStatus,\n  AgentActivityStep,\n  AgentActivityText,\n  AgentActivityTool,\n  AgentActivityTrace,\n  AgentSearchResult,\n  AgentStepStatus,\n  AgentTraceKind,\n} from \"./types\";\n\nfunction formatDuration(duration: number) {\n  const seconds = Math.max(0, Math.round(duration));\n  if (seconds < 60) return `${seconds}s`;\n\n  const minutes = Math.floor(seconds / 60);\n  const remainder = seconds % 60;\n  return remainder === 0 ? `${minutes}m` : `${minutes}m ${remainder}s`;\n}\n\nfunction useControllableOpen({\n  open,\n  defaultOpen,\n  onOpenChange,\n}: {\n  open?: boolean;\n  defaultOpen: boolean;\n  onOpenChange?: (open: boolean) => void;\n}) {\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const controlled = open !== undefined;\n  const currentOpen = open ?? internalOpen;\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (!controlled) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [controlled, onOpenChange],\n  );\n\n  return [currentOpen, setOpen] as const;\n}\n\nfunction getContentType(items: AgentActivityItem[]): AgentActivityContentType {\n  const first = items[0]?.type;\n  return first && items.every((item) => item.type === first) ? first : \"mixed\";\n}\n\nfunction getActiveLabel(type: AgentActivityContentType) {\n  if (type === \"search\") return \"Searching the web…\";\n  if (type === \"tool\") return \"Running tools…\";\n  if (type === \"trace\") return \"Working through the run…\";\n  if (type === \"mixed\") return \"Working through it…\";\n  return \"Thinking…\";\n}\n\nfunction getSummary(\n  type: AgentActivityContentType,\n  items: AgentActivityItem[],\n  duration: number,\n): ReactNode {\n  if (type === \"step\" || type === \"text\") {\n    return (\n      <>\n        Thought for <span className=\"tabular-nums\">{formatDuration(duration)}</span>\n      </>\n    );\n  }\n  if (type === \"search\") return \"Searched the web\";\n  if (type === \"tool\") {\n    return `Ran ${items.length} ${items.length === 1 ? \"tool\" : \"tools\"}`;\n  }\n  if (type === \"trace\") {\n    const messages = items.filter(\n      (item) =>\n        item.type === \"trace\" &&\n        (item.kind === \"thinking\" || item.kind === \"message\"),\n    ).length;\n    const tools = items.length - messages;\n    return `${tools} ${tools === 1 ? \"tool call\" : \"tool calls\"}, ${messages} ${messages === 1 ? \"message\" : \"messages\"}`;\n  }\n  return `Completed ${items.length} ${items.length === 1 ? \"step\" : \"steps\"}`;\n}\n\nexport function AgentActivity({\n  items,\n  contentType: initialContentType,\n  status = \"working\",\n  duration = 0,\n  open,\n  defaultOpen = false,\n  onOpenChange,\n  collapseOnComplete = true,\n  activeLabel,\n  summary,\n  renderWorkingStatus,\n  renderCompletedStatus,\n  maxHeight = 208,\n  className,\n  contentClassName,\n}: AgentActivityProps) {\n  const reduce = useReducedMotion() ?? false;\n  const baseId = useId();\n  const triggerId = `${baseId}-trigger`;\n  const contentId = `${baseId}-content`;\n  const contentRef = useRef<HTMLDivElement>(null);\n  const viewportRef = useRef<HTMLDivElement>(null);\n  const previousStatus = useRef(status);\n  const [contentHeight, setContentHeight] = useState(0);\n  const [currentOpen, setOpen] = useControllableOpen({\n    open,\n    defaultOpen,\n    onOpenChange,\n  });\n  const working = status === \"working\";\n  const expanded = working || currentOpen;\n  const contentType = items.length\n    ? getContentType(items)\n    : (initialContentType ?? \"mixed\");\n  const cappedHeight = Math.min(contentHeight, Math.max(0, maxHeight));\n  const viewportHeight = working ? Math.max(0, maxHeight) : cappedHeight;\n  const capped = contentHeight > maxHeight;\n  const streamOffset = working\n    ? Math.min(0, viewportHeight - contentHeight)\n    : 0;\n\n  useLayoutEffect(() => {\n    const node = contentRef.current;\n    if (!node) return;\n\n    const measure = () => setContentHeight(node.offsetHeight);\n    measure();\n\n    if (typeof ResizeObserver === \"undefined\") return;\n    const observer = new ResizeObserver(measure);\n    observer.observe(node);\n    return () => observer.disconnect();\n  }, []);\n\n  useEffect(() => {\n    if (previousStatus.current === \"working\" && status === \"complete\") {\n      setOpen(!collapseOnComplete);\n    }\n    previousStatus.current = status;\n  }, [collapseOnComplete, setOpen, status]);\n\n  const toggle = () => {\n    const next = !currentOpen;\n    setOpen(next);\n    if (next) requestAnimationFrame(() => viewportRef.current?.scrollTo({ top: 0 }));\n  };\n\n  const liveLabel = activeLabel ?? getActiveLabel(contentType);\n  const completedSummary = summary ?? getSummary(contentType, items, duration);\n  const maskImage = capped\n    ? working\n      ? \"linear-gradient(to bottom, transparent, black 12px)\"\n      : \"linear-gradient(to bottom, transparent, black 12px, black calc(100% - 12px), transparent)\"\n    : undefined;\n\n  return (\n    <div\n      data-state={working ? \"working\" : expanded ? \"open\" : \"closed\"}\n      data-content={contentType}\n      aria-busy={working}\n      className={cn(\"w-full text-sm\", className)}\n    >\n      {working ? (\n        <div\n          id={triggerId}\n          role=\"status\"\n          className=\"flex h-7 min-w-0 items-center text-muted-foreground\"\n        >\n          {renderWorkingStatus\n            ? renderWorkingStatus({ label: liveLabel, duration })\n            : <ThinkingShimmer>{liveLabel}</ThinkingShimmer>}\n        </div>\n      ) : (\n        <button\n          id={triggerId}\n          type=\"button\"\n          aria-expanded={expanded}\n          aria-controls={contentId}\n          onClick={toggle}\n          className=\"group flex h-7 min-w-0 items-center gap-1.5 rounded-md text-left font-medium text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n        >\n          <span className=\"truncate\">\n            {renderCompletedStatus\n              ? renderCompletedStatus({ summary: completedSummary, duration })\n              : completedSummary}\n          </span>\n          <motion.span\n            aria-hidden=\"true\"\n            animate={{ rotate: expanded ? 180 : 0 }}\n            transition={reduce ? { duration: 0 } : SPRING_SWAP}\n            className=\"inline-flex shrink-0 text-muted-foreground/70 group-hover:text-foreground\"\n          >\n            <ChevronDown className=\"size-3.5\" />\n          </motion.span>\n        </button>\n      )}\n\n      <AgentDisclosure\n        id={contentId}\n        role=\"region\"\n        aria-labelledby={triggerId}\n        open={expanded}\n        openHeight={viewportHeight}\n      >\n        <div\n          ref={viewportRef}\n          className={cn(\n            \"scrollbar-hide pr-1\",\n            capped && expanded && !working ? \"overflow-y-auto\" : \"overflow-y-hidden\",\n          )}\n          style={{ height: viewportHeight, maskImage, WebkitMaskImage: maskImage }}\n        >\n          <motion.div\n            ref={contentRef}\n            role=\"list\"\n            initial={false}\n            animate={{ y: streamOffset }}\n            transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n            className={cn(\"space-y-0.5 py-2\", contentClassName)}\n          >\n            <AnimatePresence mode=\"popLayout\">\n              {items.map((item) => (\n                <motion.div\n                  layout=\"position\"\n                  key={item.id}\n                  role=\"listitem\"\n                  initial={reduce ? { opacity: 1 } : { opacity: 0, y: 6 }}\n                  animate={{ opacity: 1, y: 0 }}\n                  exit={reduce ? { opacity: 0 } : { opacity: 0, y: -3 }}\n                  transition={\n                    reduce\n                      ? { duration: 0 }\n                      : {\n                          opacity: { duration: 0.18, ease: EASE_OUT },\n                          y: SPRING_LAYOUT,\n                          layout: SPRING_LAYOUT,\n                        }\n                  }\n                >\n                  <ActivityRow item={item} />\n                </motion.div>\n              ))}\n            </AnimatePresence>\n          </motion.div>\n        </div>\n      </AgentDisclosure>\n    </div>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/agents/loading-states/thinking-shimmer.tsx",
          "target": "@components/beui/components/agents/loading-states/thinking-shimmer.tsx",
          "type": "registry:component",
          "content": "import * as React from \"react\";\nimport type { ReactNode } from \"react\";\nimport { TextShimmer } from \"@/components/beui/components/motion/text-shimmer\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface ThinkingShimmerProps {\n  /** Loading message shown to the user. */\n  children?: ReactNode;\n  /** Seconds taken for one shimmer pass. */\n  duration?: number;\n  className?: string;\n}\n\nexport function ThinkingShimmer({\n  children = \"Thinking…\",\n  duration = 1.8,\n  className,\n}: ThinkingShimmerProps) {\n  return (\n    <TextShimmer\n      as=\"span\"\n      duration={duration}\n      className={cn(\"font-medium\", className)}\n    >\n      {children}\n    </TextShimmer>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/text-shimmer.tsx",
          "target": "@components/beui/components/motion/text-shimmer.tsx",
          "type": "registry:component",
          "content": "import * as React from \"react\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport type { ElementType, ReactNode } from \"react\";\nimport {\n  TEXT_SHIMMER_CLASS_NAME,\n  TEXT_SHIMMER_KEYFRAMES,\n  textShimmerStyle,\n} from \"@/components/beui/lib/text-shimmer\";\n\nexport interface TextShimmerProps {\n  children: ReactNode;\n  as?: ElementType;\n  duration?: number;\n  className?: string;\n}\n\nexport function TextShimmer({ children, as: Comp = \"span\", duration = 2.5, className }: TextShimmerProps) {\n  return (\n    <>\n      <style>\n        {TEXT_SHIMMER_KEYFRAMES}\n      </style>\n      <Comp\n        style={textShimmerStyle(duration)}\n        className={cn(\n          \"inline-block\",\n          TEXT_SHIMMER_CLASS_NAME,\n          className,\n        )}\n      >\n        {children}\n      </Comp>\n    </>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/lib/text-shimmer.ts",
          "target": "@components/beui/lib/text-shimmer.ts",
          "type": "registry:component",
          "content": "import type { CSSProperties } from \"react\";\n\n// The reduced-motion rule travels with the component. app/globals.css calms CSS\n// animation globally, but the registry bundles imports only, so an installed\n// copy never receives that reset.\n//\n// `!important` because the sweep is an inline style, which outranks a plain rule\n// in a media query. It selects a marker class carried by TEXT_SHIMMER_CLASS_NAME\n// so it also reaches consumers that build their own span out of these exports.\nexport const TEXT_SHIMMER_KEYFRAMES =\n  \"@keyframes beui-text-shimmer{from{background-position:200% 0}to{background-position:-200% 0}}\" +\n  \"@media (prefers-reduced-motion: reduce){.beui-text-shimmer{animation:none !important}}\";\n\nexport const TEXT_SHIMMER_CLASS_NAME =\n  \"beui-text-shimmer bg-[length:200%_100%] bg-clip-text text-transparent bg-[linear-gradient(110deg,var(--muted-foreground)_30%,var(--foreground)_50%,var(--muted-foreground)_70%)]\";\n\nexport function textShimmerStyle(duration: number): CSSProperties {\n  return {\n    animation: `beui-text-shimmer ${duration}s linear infinite`,\n  };\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-disclosure.tsx",
          "target": "@components/beui/components/agents/agent-disclosure.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, type HTMLMotionProps, useReducedMotion } from \"motion/react\";\nimport type { CSSProperties } from \"react\";\nimport { EASE_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface AgentDisclosureProps\n  extends Omit<HTMLMotionProps<\"div\">, \"animate\" | \"initial\"> {\n  open: boolean;\n  openHeight?: CSSProperties[\"height\"];\n}\n\n/** Shared transform-only reveal for collapsible agent content. */\nexport function AgentDisclosure({\n  open,\n  openHeight = \"auto\",\n  className,\n  style,\n  transition,\n  ...props\n}: AgentDisclosureProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <motion.div\n      {...props}\n      aria-hidden={!open}\n      inert={!open}\n      initial={false}\n      animate={\n        reduce\n          ? { opacity: open ? 1 : 0 }\n          : {\n              opacity: open ? 1 : 0,\n              clipPath: open ? \"inset(0 0 0% 0)\" : \"inset(0 0 100% 0)\",\n              y: open ? 0 : -4,\n            }\n      }\n      transition={\n        transition ?? {\n          duration: reduce ? 0 : open ? 0.22 : 0.14,\n          ease: EASE_OUT,\n        }\n      }\n      className={cn(\"overflow-hidden\", className)}\n      style={{\n        ...style,\n        height: open ? openHeight : 0,\n        pointerEvents: open ? undefined : \"none\",\n        transformOrigin: \"top\",\n      }}\n    />\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/components/agents/agent-activity/activity-row.tsx",
          "target": "@components/beui/components/agents/agent-activity/activity-row.tsx",
          "type": "registry:component",
          "content": "import * as React from \"react\";\nimport {\n  Check,\n  Circle,\n  FileText,\n  Globe2,\n  ImageIcon,\n  MessageSquare,\n  PencilLine,\n  Search,\n  Sparkles,\n  SquareTerminal,\n  Wrench,\n} from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { EASE_OUT, SPRING_LAYOUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport type {\n  AgentActivityItem,\n  AgentActivitySearch,\n  AgentActivityStep,\n  AgentActivityText,\n  AgentActivityTool,\n  AgentActivityTrace,\n  AgentSearchResult,\n} from \"./types\";\n\nfunction StepRow({ item }: { item: AgentActivityStep }) {\n  const state = item.status ?? \"complete\";\n\n  return (\n    <div className=\"flex min-h-7 items-start gap-2.5 rounded-md px-1.5 py-1\">\n      <span\n        aria-hidden=\"true\"\n        className=\"mt-0.5 grid size-4 shrink-0 place-items-center text-muted-foreground/70\"\n      >\n        {state === \"complete\" ? (\n          <Check className=\"size-4\" strokeWidth={1.8} />\n        ) : state === \"active\" ? (\n          <span className=\"relative grid size-3 place-items-center\">\n            <motion.span\n              className=\"absolute inset-0 rounded-full bg-foreground/10\"\n              animate={{ opacity: [0.35, 0.8, 0.35] }}\n              transition={{ duration: 1.5, repeat: Number.POSITIVE_INFINITY }}\n            />\n            <span className=\"size-1.5 rounded-full bg-foreground/60\" />\n          </span>\n        ) : (\n          <Circle className=\"size-3\" strokeWidth={1.5} />\n        )}\n      </span>\n      <span\n        className={cn(\n          \"min-w-0 flex-1 leading-5\",\n          state === \"pending\" ? \"text-muted-foreground/55\" : \"text-foreground/90\",\n        )}\n      >\n        {item.label}\n      </span>\n      {item.meta ? (\n        <span className=\"shrink-0 leading-5 text-muted-foreground/55\">\n          {item.meta}\n        </span>\n      ) : null}\n    </div>\n  );\n}\n\nfunction TextRow({ item }: { item: AgentActivityText }) {\n  return (\n    <div className=\"rounded-md px-1.5 py-1 leading-5 text-muted-foreground\">\n      {item.content}\n    </div>\n  );\n}\n\nfunction SearchResultRow({\n  result,\n}: {\n  result: AgentSearchResult;\n}) {\n  const content = (\n    <>\n      <span\n        aria-hidden=\"true\"\n        className=\"grid size-5 shrink-0 place-items-center text-muted-foreground\"\n      >\n        {result.icon ?? <Globe2 className=\"size-3\" strokeWidth={2} />}\n      </span>\n      <span className=\"min-w-0 truncate font-medium text-foreground/90\">\n        {result.title}\n      </span>\n      {result.domain ? (\n        <span className=\"min-w-0 truncate text-muted-foreground/55\">\n          {result.domain}\n        </span>\n      ) : null}\n    </>\n  );\n  const className = cn(\n    \"flex min-h-7 items-center gap-2 rounded-md px-1.5 py-1 text-left outline-none transition-colors\",\n    result.url && \"focus-visible:ring-2 focus-visible:ring-ring\",\n  );\n\n  return result.url ? (\n    <a href={result.url} className={className}>\n      {content}\n    </a>\n  ) : (\n    <div className={className}>{content}</div>\n  );\n}\n\nfunction SearchRow({ item }: { item: AgentActivitySearch }) {\n  const reduce = useReducedMotion() ?? false;\n  const enter = reduce ? { opacity: 1 } : { opacity: 0, y: 6 };\n  const visible = { opacity: 1, y: 0 };\n  const exit = reduce ? { opacity: 0 } : { opacity: 0, y: -3 };\n  const transition = reduce\n    ? { duration: 0 }\n    : {\n        opacity: { duration: 0.18, ease: EASE_OUT },\n        y: SPRING_LAYOUT,\n        layout: SPRING_LAYOUT,\n      };\n\n  return (\n    <div className=\"space-y-0.5\">\n      <div className=\"flex min-h-7 items-center gap-2.5 rounded-md px-1.5 py-1 text-muted-foreground\">\n        <Search aria-hidden=\"true\" className=\"size-4 shrink-0\" strokeWidth={1.7} />\n        <span className=\"min-w-0 truncate\">{item.query}</span>\n      </div>\n      {item.results?.length ? (\n        <div className=\"space-y-0.5 pl-4\">\n          <AnimatePresence initial mode=\"popLayout\">\n            {item.results.map((result) => (\n              <motion.div\n                layout=\"position\"\n                key={result.id}\n                initial={enter}\n                animate={visible}\n                exit={exit}\n                transition={transition}\n              >\n                <SearchResultRow result={result} />\n              </motion.div>\n            ))}\n          </AnimatePresence>\n        </div>\n      ) : null}\n      <AnimatePresence initial>\n        {item.moreCount ? (\n          <motion.div\n            key=\"more-results\"\n            initial={enter}\n            animate={visible}\n            exit={exit}\n            transition={transition}\n            className=\"px-1.5 py-1 pl-8 text-muted-foreground/55\"\n          >\n            +{item.moreCount} more\n          </motion.div>\n        ) : null}\n      </AnimatePresence>\n    </div>\n  );\n}\n\nfunction ActionIcon({ action }: { action: string }) {\n  if (action === \"read\") return <FileText className=\"size-4\" />;\n  if (action === \"edit\" || action === \"write\") {\n    return <PencilLine className=\"size-4\" />;\n  }\n  if (action === \"run\") return <SquareTerminal className=\"size-4\" />;\n  return <Wrench className=\"size-4\" />;\n}\n\nfunction ToolRow({ item }: { item: AgentActivityTool }) {\n  const action = item.action.charAt(0).toUpperCase() + item.action.slice(1);\n\n  return (\n    <div className=\"flex min-h-8 min-w-0 items-center gap-2.5 rounded-md px-1.5 py-0.5 leading-5\">\n      <span\n        aria-hidden=\"true\"\n        className=\"grid size-4 shrink-0 place-items-center text-muted-foreground/70\"\n      >\n        <ActionIcon action={item.action} />\n      </span>\n      <span className=\"shrink-0 font-medium text-foreground/90\">{action}</span>\n      <span className=\"min-w-0 flex-1 truncate rounded-lg bg-muted/80 px-2.5 py-1 font-mono text-xs text-muted-foreground/70\">\n        {item.target}\n      </span>\n      {typeof item.additions === \"number\" || typeof item.deletions === \"number\" ? (\n        <span className=\"flex shrink-0 items-center gap-2 font-mono tabular-nums\">\n          {typeof item.additions === \"number\" ? (\n            <span className=\"text-emerald-500\">+{item.additions}</span>\n          ) : null}\n          {typeof item.deletions === \"number\" ? (\n            <span className=\"text-rose-500\">−{item.deletions}</span>\n          ) : null}\n        </span>\n      ) : null}\n    </div>\n  );\n}\n\nfunction TraceIcon({ kind }: { kind: AgentActivityTrace[\"kind\"] }) {\n  if (kind === \"thinking\") return <Sparkles className=\"size-4\" />;\n  if (kind === \"message\") return <MessageSquare className=\"size-4\" />;\n  if (kind === \"write\") return <PencilLine className=\"size-4\" />;\n  if (kind === \"run\") return <SquareTerminal className=\"size-4\" />;\n  if (kind === \"read\") return <ImageIcon className=\"size-4\" />;\n  return <Wrench className=\"size-4\" />;\n}\n\nfunction TraceRow({ item }: { item: AgentActivityTrace }) {\n  return (\n    <div className=\"grid min-h-8 grid-cols-[1rem_auto_minmax(0,1fr)] items-center gap-2.5 rounded-md px-1.5 py-0.5\">\n      <span\n        aria-hidden=\"true\"\n        className=\"grid size-4 place-items-center text-muted-foreground/70\"\n      >\n        {item.icon ?? <TraceIcon kind={item.kind} />}\n      </span>\n      <span className=\"font-medium text-foreground/90\">{item.label}</span>\n      {item.detail ? (\n        <span className=\"min-w-0 truncate rounded-lg bg-muted/80 px-2.5 py-1 font-mono text-xs text-muted-foreground/70\">\n          {item.detail}\n        </span>\n      ) : (\n        <span />\n      )}\n    </div>\n  );\n}\n\nexport function ActivityRow({ item }: { item: AgentActivityItem }) {\n  if (item.type === \"text\") return <TextRow item={item} />;\n  if (item.type === \"search\") return <SearchRow item={item} />;\n  if (item.type === \"tool\") return <ToolRow item={item} />;\n  if (item.type === \"trace\") return <TraceRow item={item} />;\n  return <StepRow item={item} />;\n}\n"
        },
        {
          "path": "components/beui/components/agents/agent-activity/types.ts",
          "target": "@components/beui/components/agents/agent-activity/types.ts",
          "type": "registry:component",
          "content": "import type { ReactNode } from \"react\";\n\nexport type AgentActivityStatus = \"working\" | \"complete\";\nexport type AgentStepStatus = \"pending\" | \"active\" | \"complete\";\n\nexport interface AgentActivityStep {\n  id: string;\n  type: \"step\";\n  label: ReactNode;\n  status?: AgentStepStatus;\n  meta?: ReactNode;\n}\n\nexport interface AgentActivityText {\n  id: string;\n  type: \"text\";\n  content: ReactNode;\n}\n\nexport interface AgentSearchResult {\n  id: string;\n  title: ReactNode;\n  domain?: ReactNode;\n  url?: string;\n  icon?: ReactNode;\n}\n\nexport interface AgentActivitySearch {\n  id: string;\n  type: \"search\";\n  query: ReactNode;\n  results?: AgentSearchResult[];\n  moreCount?: number;\n}\n\nexport interface AgentActivityTool {\n  id: string;\n  type: \"tool\";\n  action: \"read\" | \"edit\" | \"run\" | (string & {});\n  target: ReactNode;\n  additions?: number;\n  deletions?: number;\n}\n\nexport type AgentTraceKind =\n  | \"thinking\"\n  | \"message\"\n  | \"write\"\n  | \"run\"\n  | \"read\"\n  | (string & {});\n\nexport interface AgentActivityTrace {\n  id: string;\n  type: \"trace\";\n  kind: AgentTraceKind;\n  label: ReactNode;\n  detail?: ReactNode;\n  icon?: ReactNode;\n}\n\nexport type AgentActivityItem =\n  | AgentActivityStep\n  | AgentActivityText\n  | AgentActivitySearch\n  | AgentActivityTool\n  | AgentActivityTrace;\n\nexport type AgentActivityContentType = AgentActivityItem[\"type\"] | \"mixed\";\n\nexport interface AgentActivityProps {\n  /** Chronological activity entries. Append or update items as events stream. */\n  items: AgentActivityItem[];\n  /** Expected activity kind before the first streamed item arrives. */\n  contentType?: AgentActivityContentType;\n  /** Current run phase. Active runs always stay expanded. */\n  status?: AgentActivityStatus;\n  /** Elapsed run time, in seconds. Used by the step-only summary. */\n  duration?: number;\n  /** Controlled expanded state used after the run completes. */\n  open?: boolean;\n  /** Initial expanded state used after the run completes. */\n  defaultOpen?: boolean;\n  /** Called when the completed activity disclosure changes state. */\n  onOpenChange?: (open: boolean) => void;\n  /** Collapse the disclosure when status changes from working to complete. */\n  collapseOnComplete?: boolean;\n  /** Optional label shown while the run is active. */\n  activeLabel?: ReactNode;\n  /** Optional completed summary. Derived from the item types by default. */\n  summary?: ReactNode;\n  /** Optional renderer for the contents of the active status row. */\n  renderWorkingStatus?: (context: {\n    label: ReactNode;\n    duration: number;\n  }) => ReactNode;\n  /** Optional renderer for the contents before the built-in disclosure chevron. */\n  renderCompletedStatus?: (context: {\n    summary: ReactNode;\n    duration: number;\n  }) => ReactNode;\n  /** Maximum visible activity height before the stream begins gliding. */\n  maxHeight?: number;\n  className?: string;\n  contentClassName?: string;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-reasoning-text",
      "type": "registry:block",
      "title": "Beui Reasoning Text",
      "description": "Agent Loading States Reasoning Text",
      "dependencies": [
        "clsx@^2.1.1",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/loading-states/reasoning-text.tsx",
          "target": "@components/beui/components/agents/loading-states/reasoning-text.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { useEffect, useId, useState, type ReactNode } from \"react\";\nimport { Loader } from \"@/components/beui/components/motion/loader\";\nimport { TextScramble } from \"@/components/beui/components/motion/text-scramble\";\nimport { EASE_OUT, SPRING_SWAP } from \"@/components/beui/lib/ease\";\nimport {\n  TEXT_SHIMMER_CLASS_NAME,\n  TEXT_SHIMMER_KEYFRAMES,\n  textShimmerStyle,\n} from \"@/components/beui/lib/text-shimmer\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nconst DEFAULT_PHRASES = [\n  \"Thinking\",\n  \"Reading the context\",\n  \"Connecting the details\",\n  \"Forming a response\",\n];\n\nconst CASCADE_STAGGER = 0.025;\n\nexport type ReasoningTextVariant = \"cascade\" | \"swap\" | \"scramble\";\n\nexport interface ReasoningTextProps {\n  /** Phrases cycled through while the agent works. */\n  phrases?: string[];\n  /** Animation used when the active phrase changes. */\n  variant?: ReasoningTextVariant;\n  /** Milliseconds each phrase remains visible. */\n  interval?: number;\n  /** Seconds taken for one shimmer pass. */\n  shimmerDuration?: number;\n  /** Optional leading visual. Defaults to a terminal-style ASCII loader. */\n  indicator?: ReactNode;\n  className?: string;\n}\n\ntype PhraseProps = {\n  phrase: string;\n  reduce: boolean;\n  shimmerDuration: number;\n};\n\nfunction CascadePhrase({\n  phrase,\n  reduce,\n  shimmerDuration,\n}: PhraseProps) {\n  const text = `${phrase}…`;\n\n  if (reduce) {\n    return (\n      <span\n        className={cn(\n          \"col-start-1 row-start-1 inline-block justify-self-start whitespace-pre\",\n          TEXT_SHIMMER_CLASS_NAME,\n        )}\n        style={textShimmerStyle(shimmerDuration)}\n      >\n        {text}\n      </span>\n    );\n  }\n\n  return (\n    <AnimatePresence initial={false}>\n      <motion.span\n        key={phrase}\n        className=\"col-start-1 row-start-1 inline-block justify-self-start whitespace-pre\"\n        initial=\"initial\"\n        animate=\"animate\"\n        exit=\"exit\"\n      >\n        {text.split(\"\").map((character, characterIndex) => (\n          <motion.span\n            // biome-ignore lint/suspicious/noArrayIndexKey: position is the stable cascade slot identity.\n            key={characterIndex}\n            custom={characterIndex * CASCADE_STAGGER}\n            variants={{\n              initial: { opacity: 0, y: \"100%\" },\n              animate: (delay: number) => ({\n                opacity: 1,\n                y: \"0%\",\n                transition: { ...SPRING_SWAP, delay },\n              }),\n              exit: (delay: number) => ({\n                opacity: 0,\n                y: \"-100%\",\n                transition: {\n                  duration: 0.14,\n                  ease: EASE_OUT,\n                  delay: delay * 0.45,\n                },\n              }),\n            }}\n            className={cn(\n              \"inline-block whitespace-pre will-change-[opacity,transform]\",\n              TEXT_SHIMMER_CLASS_NAME,\n            )}\n            style={textShimmerStyle(shimmerDuration)}\n          >\n            {character}\n          </motion.span>\n        ))}\n      </motion.span>\n    </AnimatePresence>\n  );\n}\n\nfunction SwapPhrase({ phrase, reduce, shimmerDuration }: PhraseProps) {\n  return (\n    <AnimatePresence initial={false}>\n      <motion.span\n        key={phrase}\n        className={cn(\n          \"col-start-1 row-start-1 inline-block justify-self-start whitespace-nowrap will-change-[opacity,transform]\",\n          TEXT_SHIMMER_CLASS_NAME,\n        )}\n        style={textShimmerStyle(shimmerDuration)}\n        initial={reduce ? { opacity: 0 } : { opacity: 0, y: 3 }}\n        animate={reduce ? { opacity: 1 } : { opacity: 1, y: 0 }}\n        exit={reduce ? { opacity: 0 } : { opacity: 0, y: -3 }}\n        transition={{\n          duration: reduce ? 0.12 : 0.2,\n          ease: EASE_OUT,\n        }}\n      >\n        {phrase}…\n      </motion.span>\n    </AnimatePresence>\n  );\n}\n\nfunction ScramblePhrase({\n  phrase,\n  shimmerDuration,\n}: PhraseProps) {\n  const target = `${phrase}…`;\n\n  return (\n    <TextScramble\n      text={target}\n      className={cn(\n        \"col-start-1 row-start-1 justify-self-start tabular-nums\",\n        TEXT_SHIMMER_CLASS_NAME,\n      )}\n      style={textShimmerStyle(shimmerDuration)}\n    />\n  );\n}\n\nexport function ReasoningText({\n  phrases = DEFAULT_PHRASES,\n  variant = \"cascade\",\n  interval = 1800,\n  shimmerDuration = 2.2,\n  indicator,\n  className,\n}: ReasoningTextProps) {\n  const reduce = useReducedMotion() ?? false;\n  const [index, setIndex] = useState(0);\n  const statusId = useId();\n  const safePhrases = phrases.length > 0 ? phrases : DEFAULT_PHRASES;\n  const phrase = safePhrases[index % safePhrases.length];\n  const longestPhrase = safePhrases.reduce((longest, current) =>\n    current.length > longest.length ? current : longest,\n  );\n  const phraseProps = { phrase, reduce, shimmerDuration };\n\n  useEffect(() => {\n    if (safePhrases.length < 2) return;\n\n    const timer = window.setInterval(() => {\n      setIndex((current) => (current + 1) % safePhrases.length);\n    }, Math.max(600, interval));\n\n    return () => window.clearInterval(timer);\n  }, [interval, safePhrases.length]);\n\n  return (\n    <>\n      <style>{TEXT_SHIMMER_KEYFRAMES}</style>\n      <span\n        role=\"status\"\n        aria-live=\"polite\"\n        aria-labelledby={statusId}\n        className={cn(\n          \"inline-flex items-center gap-2 text-sm font-medium text-muted-foreground\",\n          className,\n        )}\n      >\n        <span aria-hidden=\"true\" className=\"inline-flex size-3 shrink-0 items-center justify-center\">\n          {indicator ?? (\n            <Loader\n              variant=\"ascii-line\"\n              size={14}\n              speed={0.8}\n              label=\"Reasoning\"\n            />\n          )}\n        </span>\n\n        <span aria-hidden=\"true\" className=\"grid overflow-hidden text-left\">\n          <span className=\"invisible col-start-1 row-start-1 whitespace-nowrap\">\n            {longestPhrase}…\n          </span>\n          {variant === \"cascade\" ? (\n            <CascadePhrase {...phraseProps} />\n          ) : variant === \"scramble\" ? (\n            <ScramblePhrase {...phraseProps} />\n          ) : (\n            <SwapPhrase {...phraseProps} />\n          )}\n        </span>\n\n        <span id={statusId} className=\"sr-only\">\n          {phrase}\n        </span>\n      </span>\n    </>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/loader.tsx",
          "target": "@components/beui/components/motion/loader.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { useEffect, useId, useState } from \"react\";\nimport { EASE_IN_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type LoaderVariant =\n  | \"spinner\"\n  | \"dots\"\n  | \"bars\"\n  | \"dot-matrix\"\n  | \"dither\"\n  | \"ascii\"\n  | \"ascii-line\"\n  | \"ascii-braille\"\n  | \"ascii-blocks\"\n  | \"ascii-bounce\"\n  | \"morph\"\n  | \"comet\"\n  | \"scramble\"\n  | \"metaballs\"\n  | \"newton\"\n  | \"helix\"\n  | \"percent\";\n\n// Terminal-style frame sets — the loaders CLI AI agents cycle through.\nconst ASCII_SETS: Record<string, string[]> = {\n  ascii: [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"],\n  \"ascii-line\": [\"|\", \"/\", \"-\", \"\\\\\"],\n  \"ascii-braille\": [\"⣾\", \"⣽\", \"⣻\", \"⢿\", \"⡿\", \"⣟\", \"⣯\", \"⣷\"],\n  \"ascii-blocks\": [\"▁\", \"▂\", \"▃\", \"▄\", \"▅\", \"▆\", \"▇\", \"█\", \"▇\", \"▆\", \"▅\", \"▄\", \"▃\", \"▂\"],\n  \"ascii-bounce\": [\"⠁\", \"⠂\", \"⠄\", \"⡀\", \"⢀\", \"⠠\", \"⠐\", \"⠈\"],\n};\n\nexport interface LoaderProps {\n  /** Which animation to render. */\n  variant?: LoaderVariant;\n  /** Base square size in px. Everything scales from this. */\n  size?: number;\n  /** Seconds per animation cycle. */\n  speed?: number;\n  /** Accessible label announced to screen readers. */\n  label?: string;\n  className?: string;\n}\n\n// Reduced motion keeps a calm opacity pulse and drops every transform.\nconst REDUCED = {\n  animate: { opacity: [1, 0.4, 1] },\n  transition: { duration: 1.4, ease: EASE_IN_OUT, repeat: Infinity },\n};\n\nexport function Loader({\n  variant = \"spinner\",\n  size = 32,\n  speed = 1,\n  label = \"Loading\",\n  className,\n}: LoaderProps) {\n  const reduce = useReducedMotion() ?? false;\n\n  return (\n    <span\n      role=\"status\"\n      aria-label={label}\n      className={cn(\n        \"inline-flex items-center justify-center text-foreground\",\n        className,\n      )}\n    >\n      {variant === \"spinner\" && <Spinner size={size} speed={speed} reduce={reduce} />}\n      {variant === \"dots\" && <Dots size={size} speed={speed} reduce={reduce} />}\n      {variant === \"bars\" && <Bars size={size} speed={speed} reduce={reduce} />}\n      {variant === \"dot-matrix\" && (\n        <DotMatrix size={size} speed={speed} reduce={reduce} />\n      )}\n      {variant === \"dither\" && <Dither size={size} speed={speed} reduce={reduce} />}\n      {ASCII_SETS[variant] && (\n        <Ascii frames={ASCII_SETS[variant]} size={size} speed={speed} reduce={reduce} />\n      )}\n      {variant === \"morph\" && <Morph size={size} speed={speed} reduce={reduce} />}\n      {variant === \"comet\" && <Comet size={size} speed={speed} reduce={reduce} />}\n      {variant === \"scramble\" && (\n        <Scramble size={size} speed={speed} reduce={reduce} />\n      )}\n      {variant === \"metaballs\" && (\n        <Metaballs size={size} speed={speed} reduce={reduce} />\n      )}\n      {variant === \"newton\" && <Newton size={size} speed={speed} reduce={reduce} />}\n      {variant === \"helix\" && <Helix size={size} speed={speed} reduce={reduce} />}\n      {variant === \"percent\" && (\n        <Percent size={size} speed={speed} reduce={reduce} />\n      )}\n      <span className=\"sr-only\">{label}</span>\n    </span>\n  );\n}\n\ninterface PartProps {\n  size: number;\n  speed: number;\n  reduce: boolean;\n}\n\nfunction Spinner({ size, speed, reduce }: PartProps) {\n  const stroke = Math.max(2, size * 0.09);\n  const r = (size - stroke) / 2;\n  return (\n    <motion.svg\n      width={size}\n      height={size}\n      viewBox={`0 0 ${size} ${size}`}\n      animate={reduce ? REDUCED.animate : { rotate: 360 }}\n      transition={\n        reduce\n          ? REDUCED.transition\n          : { duration: speed, ease: \"linear\", repeat: Infinity }\n      }\n    >\n      <circle\n        cx={size / 2}\n        cy={size / 2}\n        r={r}\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeOpacity={0.2}\n        strokeWidth={stroke}\n      />\n      <path\n        d={`M ${size / 2} ${size / 2 - r} A ${r} ${r} 0 0 1 ${size / 2 + r} ${size / 2}`}\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={stroke}\n        strokeLinecap=\"round\"\n      />\n    </motion.svg>\n  );\n}\n\nfunction Dots({ size, speed, reduce }: PartProps) {\n  const dot = size * 0.24;\n  return (\n    <span className=\"flex items-center\" style={{ gap: size * 0.14 }}>\n      {[0, 1, 2].map((i) => (\n        <motion.span\n          key={i}\n          className=\"rounded-full bg-current\"\n          style={{ width: dot, height: dot }}\n          animate={\n            reduce\n              ? { opacity: [0.4, 1, 0.4] }\n              : { y: [0, -size * 0.3, 0], opacity: [0.5, 1, 0.5] }\n          }\n          transition={{\n            duration: speed,\n            ease: EASE_IN_OUT,\n            repeat: Infinity,\n            delay: i * speed * 0.16,\n          }}\n        />\n      ))}\n    </span>\n  );\n}\n\nfunction Ascii({\n  frames,\n  size,\n  speed,\n  reduce,\n}: PartProps & { frames: string[] }) {\n  const [frame, setFrame] = useState(0);\n  useEffect(() => {\n    // Reduced motion slows the cycle rather than stopping it — it's a glyph\n    // swap, not on-screen movement.\n    const step = ((reduce ? speed * 2.5 : speed) / frames.length) * 1000;\n    const id = setInterval(\n      () => setFrame((f) => (f + 1) % frames.length),\n      step,\n    );\n    return () => clearInterval(id);\n  }, [frames.length, speed, reduce]);\n\n  return (\n    <span\n      className=\"font-mono leading-none tabular-nums\"\n      style={{ fontSize: size, lineHeight: 1 }}\n    >\n      {frames[frame % frames.length]}\n    </span>\n  );\n}\n\n// Each shape is sampled at the same number of points and emitted as an SVG\n// path with identical command structure, so framer tweens the `d` attribute\n// point-to-point — a real morph, not a snap. (clip-path polygon strings don't\n// interpolate reliably in framer, which left the shapes broken.)\nconst MORPH_POINTS = 24;\n\nfunction ngonRadius(ang: number, n: number, phase = 0) {\n  const seg = (2 * Math.PI) / n;\n  const a = ang - phase;\n  const local = (((a % seg) + seg) % seg) - seg / 2;\n  return Math.cos(Math.PI / n) / Math.cos(local);\n}\n\nfunction morphPath(radiusAt: (ang: number) => number) {\n  const parts: string[] = [];\n  for (let i = 0; i < MORPH_POINTS; i++) {\n    const ang = (i / MORPH_POINTS) * 2 * Math.PI - Math.PI / 2;\n    const r = Math.min(1.05, radiusAt(ang));\n    const x = (50 + Math.cos(ang) * 46 * r).toFixed(2);\n    const y = (50 + Math.sin(ang) * 46 * r).toFixed(2);\n    parts.push(`${i === 0 ? \"M\" : \"L\"}${x} ${y}`);\n  }\n  return `${parts.join(\" \")} Z`;\n}\n\nconst MORPH_PATHS = [\n  morphPath(() => 1), // circle\n  morphPath((a) => ngonRadius(a, 4, Math.PI / 4)), // square\n  morphPath((a) => ngonRadius(a, 3)), // triangle\n  morphPath((a) => ngonRadius(a, 6)), // hexagon\n  morphPath((a) => ngonRadius(a, 4)), // diamond\n];\n\n// Each shape appears twice in a row so it fully forms and HOLDS before the\n// next morph. Even keyframe spacing then alternates hold / morph segments.\nconst MORPH_SEQ = [...MORPH_PATHS.flatMap((p) => [p, p]), MORPH_PATHS[0]];\n// Rotation and scale only change across the morph segments, staying put on the\n// holds, so a settled shape sits still.\nconst MORPH_ROT = [0, 0, 72, 72, 144, 144, 216, 216, 288, 288, 360];\nconst MORPH_SCALE = [1, 1, 0.88, 0.88, 1, 1, 0.88, 0.88, 1, 1, 1];\n\nfunction Morph({ size, speed, reduce }: PartProps) {\n  return (\n    <motion.svg\n      width={size}\n      height={size}\n      viewBox=\"0 0 100 100\"\n      role=\"img\"\n      animate={\n        reduce\n          ? { opacity: [1, 0.4, 1] }\n          : { rotate: MORPH_ROT, scale: MORPH_SCALE }\n      }\n      transition={\n        reduce\n          ? { duration: 1.4, ease: EASE_IN_OUT, repeat: Infinity }\n          : { duration: speed * 5, ease: EASE_IN_OUT, repeat: Infinity }\n      }\n    >\n      <title>Loading</title>\n      <motion.path\n        fill=\"currentColor\"\n        d={MORPH_PATHS[0]}\n        animate={reduce ? undefined : { d: MORPH_SEQ }}\n        transition={\n          reduce\n            ? undefined\n            : { duration: speed * 5, ease: EASE_IN_OUT, repeat: Infinity }\n        }\n      />\n    </motion.svg>\n  );\n}\n\nconst COMET_TRAIL = [0, 1, 2, 3, 4, 5];\n\nfunction Comet({ size, speed, reduce }: PartProps) {\n  const head = size * 0.2;\n  const r = size / 2 - head / 2;\n  return (\n    <span className=\"relative\" style={{ width: size, height: size }}>\n      <motion.span\n        className=\"absolute inset-0\"\n        animate={reduce ? REDUCED.animate : { rotate: 360 }}\n        transition={\n          reduce\n            ? REDUCED.transition\n            : { duration: speed, ease: \"linear\", repeat: Infinity }\n        }\n      >\n        {COMET_TRAIL.map((i) => {\n          const scale = 1 - i * 0.13;\n          const sz = head * scale;\n          return (\n            <span\n              key={i}\n              className=\"absolute top-1/2 left-1/2 rounded-full bg-current\"\n              style={{\n                width: sz,\n                height: sz,\n                marginLeft: -sz / 2,\n                marginTop: -sz / 2,\n                opacity: 1 - i * 0.16,\n                transform: `rotate(${-i * 15}deg) translateY(${-r}px)`,\n              }}\n            />\n          );\n        })}\n      </motion.span>\n    </span>\n  );\n}\n\nconst SCRAMBLE_TARGET = \"LOADING\";\nconst SCRAMBLE_GLYPHS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789<>/*#@\";\n\nfunction Scramble({ size, speed, reduce }: PartProps) {\n  const [text, setText] = useState(SCRAMBLE_TARGET);\n  useEffect(() => {\n    if (reduce) {\n      setText(SCRAMBLE_TARGET);\n      return;\n    }\n    let tick = 0;\n    const total = SCRAMBLE_TARGET.length + 4;\n    const id = setInterval(\n      () => {\n        const reveal = tick % total;\n        let s = \"\";\n        for (let i = 0; i < SCRAMBLE_TARGET.length; i++) {\n          s +=\n            i < reveal\n              ? SCRAMBLE_TARGET[i]\n              : SCRAMBLE_GLYPHS[\n                  Math.floor(Math.random() * SCRAMBLE_GLYPHS.length)\n                ];\n        }\n        setText(s);\n        tick++;\n      },\n      (speed / SCRAMBLE_TARGET.length) * 1000 * 0.55,\n    );\n    return () => clearInterval(id);\n  }, [speed, reduce]);\n\n  return (\n    <span\n      className=\"font-mono font-medium tracking-[0.2em] tabular-nums\"\n      style={{ fontSize: size * 0.42 }}\n    >\n      {text}\n    </span>\n  );\n}\n\nfunction Metaballs({ size, speed, reduce }: PartProps) {\n  const id = useId().replace(/:/g, \"\");\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 100 100\" role=\"img\">\n      <title>Loading</title>\n      <defs>\n        <filter id={id}>\n          <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"5\" result=\"b\" />\n          <feColorMatrix\n            in=\"b\"\n            values=\"1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 20 -8\"\n          />\n        </filter>\n      </defs>\n      <g filter={`url(#${id})`} fill=\"currentColor\">\n        <motion.circle\n          cy=\"50\"\n          r=\"15\"\n          animate={reduce ? { opacity: [0.4, 1, 0.4] } : { cx: [30, 70, 30] }}\n          transition={{ duration: speed * 1.6, ease: EASE_IN_OUT, repeat: Infinity }}\n          cx={reduce ? 40 : 30}\n        />\n        <motion.circle\n          cy=\"50\"\n          r=\"15\"\n          animate={reduce ? { opacity: [0.4, 1, 0.4] } : { cx: [70, 30, 70] }}\n          transition={{ duration: speed * 1.6, ease: EASE_IN_OUT, repeat: Infinity }}\n          cx={reduce ? 60 : 70}\n        />\n      </g>\n    </svg>\n  );\n}\n\nconst NEWTON_BALLS = [0, 1, 2, 3, 4];\n\nfunction Newton({ size, speed, reduce }: PartProps) {\n  const d = size * 0.2;\n  const out = d * 1.1;\n  // Only the end balls move: the left slides out and back on the first half,\n  // then the right on the second half — the impact appears to jump the three\n  // still middle balls. Pure horizontal slide, no swing, no strings.\n  const moves: Record<number, { x: number[]; times: number[] }> = {\n    0: { x: [0, -out, 0, 0], times: [0, 0.28, 0.5, 1] },\n    4: { x: [0, 0, out, 0], times: [0, 0.5, 0.78, 1] },\n  };\n\n  return (\n    <span className=\"flex items-center justify-center\" style={{ height: d }}>\n      {NEWTON_BALLS.map((i) => {\n        const move = moves[i];\n        return (\n          <motion.span\n            key={i}\n            className=\"rounded-full bg-current\"\n            style={{ width: d, height: d }}\n            animate={reduce || !move ? undefined : { x: move.x }}\n            transition={\n              reduce || !move\n                ? undefined\n                : {\n                    duration: speed * 1.5,\n                    ease: EASE_IN_OUT,\n                    repeat: Infinity,\n                    times: move.times,\n                  }\n            }\n          />\n        );\n      })}\n    </span>\n  );\n}\n\nfunction Helix({ size, speed, reduce }: PartProps) {\n  const rows = 7;\n  const dot = size * 0.14;\n  const amp = size * 0.32;\n  return (\n    <span className=\"relative\" style={{ width: size, height: size }}>\n      {Array.from({ length: rows }, (_, r) => {\n        const top = (r / (rows - 1)) * (size - dot);\n        const delay = (r / rows) * speed;\n        return (\n          <span key={`row-${top}`}>\n            <motion.span\n              className=\"absolute rounded-full bg-current\"\n              style={{ width: dot, height: dot, left: size / 2 - dot / 2, top }}\n              animate={\n                reduce\n                  ? { opacity: [0.4, 1, 0.4] }\n                  : {\n                      x: [amp, -amp, amp],\n                      scale: [1, 0.5, 1],\n                      opacity: [1, 0.45, 1],\n                    }\n              }\n              transition={{\n                duration: speed,\n                ease: EASE_IN_OUT,\n                repeat: Infinity,\n                delay,\n              }}\n            />\n            <motion.span\n              className=\"absolute rounded-full bg-current\"\n              style={{ width: dot, height: dot, left: size / 2 - dot / 2, top }}\n              animate={\n                reduce\n                  ? { opacity: [0.4, 1, 0.4] }\n                  : {\n                      x: [-amp, amp, -amp],\n                      scale: [0.5, 1, 0.5],\n                      opacity: [0.45, 1, 0.45],\n                    }\n              }\n              transition={{\n                duration: speed,\n                ease: EASE_IN_OUT,\n                repeat: Infinity,\n                delay,\n              }}\n            />\n          </span>\n        );\n      })}\n    </span>\n  );\n}\n\nfunction Percent({ size, speed, reduce }: PartProps) {\n  const [p, setP] = useState(0);\n  useEffect(() => {\n    const dur = (reduce ? speed * 2 : speed) * 1000;\n    const start = { t: 0 };\n    const tickMs = 40;\n    const id = setInterval(() => {\n      start.t += tickMs;\n      const next = Math.min(100, Math.round((start.t / dur) * 100));\n      setP(next);\n      if (next >= 100) start.t = 0;\n    }, tickMs);\n    return () => clearInterval(id);\n  }, [speed, reduce]);\n\n  return (\n    <span\n      className=\"flex flex-col items-center\"\n      style={{ gap: size * 0.14, width: size * 1.4 }}\n    >\n      <span\n        className=\"font-mono font-medium tabular-nums\"\n        style={{ fontSize: size * 0.42, lineHeight: 1 }}\n      >\n        {p}%\n      </span>\n      <span\n        className=\"w-full overflow-hidden rounded-full bg-current/15\"\n        style={{ height: Math.max(3, size * 0.1) }}\n      >\n        <span\n          className=\"block h-full rounded-full bg-current\"\n          style={{ width: `${p}%` }}\n        />\n      </span>\n    </span>\n  );\n}\n\nfunction Bars({ size, speed, reduce }: PartProps) {\n  const bar = size * 0.16;\n  return (\n    <span className=\"flex items-center\" style={{ gap: size * 0.1, height: size }}>\n      {[0, 1, 2, 3].map((i) => (\n        <motion.span\n          key={i}\n          className=\"rounded-full bg-current\"\n          style={{ width: bar, height: size, originY: 1 }}\n          animate={\n            reduce ? { opacity: [0.4, 1, 0.4] } : { scaleY: [0.3, 1, 0.3] }\n          }\n          transition={{\n            duration: speed,\n            ease: EASE_IN_OUT,\n            repeat: Infinity,\n            delay: i * speed * 0.12,\n          }}\n        />\n      ))}\n    </span>\n  );\n}\n\nfunction DotMatrix({ size, speed, reduce }: PartProps) {\n  const n = 3;\n  const gap = size * 0.14;\n  const dot = (size - gap * (n - 1)) / n;\n  const cells = Array.from({ length: n * n }, (_, idx) => idx);\n  return (\n    <span\n      className=\"grid\"\n      style={{\n        gap,\n        gridTemplateColumns: `repeat(${n}, ${dot}px)`,\n      }}\n    >\n      {cells.map((idx) => {\n        const x = idx % n;\n        const y = Math.floor(idx / n);\n        // Diagonal wave: cells light in order of their distance from the corner.\n        const delay = ((x + y) / (2 * (n - 1))) * speed;\n        return (\n          <motion.span\n            key={idx}\n            className=\"rounded-full bg-current\"\n            style={{ width: dot, height: dot }}\n            animate={\n              reduce\n                ? { opacity: [0.3, 1, 0.3] }\n                : { opacity: [0.2, 1, 0.2], scale: [0.7, 1, 0.7] }\n            }\n            transition={{\n              duration: speed,\n              ease: EASE_IN_OUT,\n              repeat: Infinity,\n              delay,\n            }}\n          />\n        );\n      })}\n    </span>\n  );\n}\n\n// Ordered Bayer 4x4 matrix — the classic dithering threshold pattern. Cells\n// light in this order, so the fill shimmers like a dissolving halftone.\nconst BAYER_4 = [\n  0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5,\n];\n\nfunction Dither({ size, speed, reduce }: PartProps) {\n  const n = 4;\n  const gap = Math.max(1, size * 0.05);\n  const cell = (size - gap * (n - 1)) / n;\n  return (\n    <span\n      className=\"grid\"\n      style={{ gap, gridTemplateColumns: `repeat(${n}, ${cell}px)` }}\n    >\n      {BAYER_4.map((order, idx) => (\n        <motion.span\n          // biome-ignore lint/suspicious/noArrayIndexKey: fixed matrix cells, order never changes\n          key={idx}\n          className=\"bg-current\"\n          style={{ width: cell, height: cell }}\n          animate={reduce ? { opacity: [0.3, 1, 0.3] } : { opacity: [0.1, 1, 0.1] }}\n          transition={{\n            duration: speed,\n            ease: EASE_IN_OUT,\n            repeat: Infinity,\n            delay: (order / BAYER_4.length) * speed,\n          }}\n        />\n      ))}\n    </span>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/components/motion/text-scramble.tsx",
          "target": "@components/beui/components/motion/text-scramble.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useReducedMotion } from \"motion/react\";\nimport {\n  useEffect,\n  useRef,\n  useState,\n  type CSSProperties,\n} from \"react\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nconst DEFAULT_GLYPHS = \"ABCDEFGHJKLMNPQRSTUVWXYZ0123456789#%&@$?/\";\n\nexport interface TextScrambleProps {\n  /** Final text revealed by the scramble animation. */\n  text: string;\n  /** Maximum animation duration in milliseconds. */\n  duration?: number;\n  /** Characters sampled while unresolved positions are scrambling. */\n  glyphs?: string;\n  className?: string;\n  style?: CSSProperties;\n}\n\n/** Character scramble that resolves to `text` and respects reduced motion. */\nexport function TextScramble({\n  text,\n  duration,\n  glyphs = DEFAULT_GLYPHS,\n  className,\n  style,\n}: TextScrambleProps) {\n  const reduce = useReducedMotion() ?? false;\n  const [display, setDisplay] = useState(text);\n  const mounted = useRef(false);\n\n  useEffect(() => {\n    if (!mounted.current) {\n      mounted.current = true;\n      setDisplay(text);\n      return;\n    }\n\n    if (reduce || !glyphs) {\n      setDisplay(text);\n      return;\n    }\n\n    const characters = text.split(\"\");\n    const startedAt = performance.now();\n    const animationDuration = duration\n      ?? Math.min(760, Math.max(420, characters.length * 32));\n    let frame = 0;\n    let lastUpdate = 0;\n\n    const animate = (now: number) => {\n      if (now - lastUpdate >= 40) {\n        lastUpdate = now;\n        const progress = Math.min((now - startedAt) / animationDuration, 1);\n        const settled = Math.floor(progress * characters.length);\n        setDisplay(characters.map((character, index) => {\n          if (index < settled || character === \" \") return character;\n          return glyphs[Math.floor(Math.random() * glyphs.length)];\n        }).join(\"\"));\n      }\n\n      if (now - startedAt < animationDuration) {\n        frame = requestAnimationFrame(animate);\n      } else {\n        setDisplay(text);\n      }\n    };\n\n    frame = requestAnimationFrame(animate);\n    return () => cancelAnimationFrame(frame);\n  }, [duration, glyphs, reduce, text]);\n\n  return (\n    <span className={cn(\"inline-block whitespace-pre\", className)} style={style}>\n      <span className=\"sr-only\">{text}</span>\n      <span aria-hidden=\"true\">{reduce ? text : display}</span>\n    </span>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/text-shimmer.ts",
          "target": "@components/beui/lib/text-shimmer.ts",
          "type": "registry:component",
          "content": "import type { CSSProperties } from \"react\";\n\n// The reduced-motion rule travels with the component. app/globals.css calms CSS\n// animation globally, but the registry bundles imports only, so an installed\n// copy never receives that reset.\n//\n// `!important` because the sweep is an inline style, which outranks a plain rule\n// in a media query. It selects a marker class carried by TEXT_SHIMMER_CLASS_NAME\n// so it also reaches consumers that build their own span out of these exports.\nexport const TEXT_SHIMMER_KEYFRAMES =\n  \"@keyframes beui-text-shimmer{from{background-position:200% 0}to{background-position:-200% 0}}\" +\n  \"@media (prefers-reduced-motion: reduce){.beui-text-shimmer{animation:none !important}}\";\n\nexport const TEXT_SHIMMER_CLASS_NAME =\n  \"beui-text-shimmer bg-[length:200%_100%] bg-clip-text text-transparent bg-[linear-gradient(110deg,var(--muted-foreground)_30%,var(--foreground)_50%,var(--muted-foreground)_70%)]\";\n\nexport function textShimmerStyle(duration: number): CSSProperties {\n  return {\n    animation: `beui-text-shimmer ${duration}s linear infinite`,\n  };\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-thinking-shimmer",
      "type": "registry:block",
      "title": "Beui Thinking Shimmer",
      "description": "Agent Loading States Thinking Shimmer",
      "dependencies": [
        "clsx@^2.1.1",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/loading-states/thinking-shimmer.tsx",
          "target": "@components/beui/components/agents/loading-states/thinking-shimmer.tsx",
          "type": "registry:component",
          "content": "import * as React from \"react\";\nimport type { ReactNode } from \"react\";\nimport { TextShimmer } from \"@/components/beui/components/motion/text-shimmer\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface ThinkingShimmerProps {\n  /** Loading message shown to the user. */\n  children?: ReactNode;\n  /** Seconds taken for one shimmer pass. */\n  duration?: number;\n  className?: string;\n}\n\nexport function ThinkingShimmer({\n  children = \"Thinking…\",\n  duration = 1.8,\n  className,\n}: ThinkingShimmerProps) {\n  return (\n    <TextShimmer\n      as=\"span\"\n      duration={duration}\n      className={cn(\"font-medium\", className)}\n    >\n      {children}\n    </TextShimmer>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/text-shimmer.tsx",
          "target": "@components/beui/components/motion/text-shimmer.tsx",
          "type": "registry:component",
          "content": "import * as React from \"react\";\nimport { cn } from \"@/components/beui/lib/utils\";\nimport type { ElementType, ReactNode } from \"react\";\nimport {\n  TEXT_SHIMMER_CLASS_NAME,\n  TEXT_SHIMMER_KEYFRAMES,\n  textShimmerStyle,\n} from \"@/components/beui/lib/text-shimmer\";\n\nexport interface TextShimmerProps {\n  children: ReactNode;\n  as?: ElementType;\n  duration?: number;\n  className?: string;\n}\n\nexport function TextShimmer({ children, as: Comp = \"span\", duration = 2.5, className }: TextShimmerProps) {\n  return (\n    <>\n      <style>\n        {TEXT_SHIMMER_KEYFRAMES}\n      </style>\n      <Comp\n        style={textShimmerStyle(duration)}\n        className={cn(\n          \"inline-block\",\n          TEXT_SHIMMER_CLASS_NAME,\n          className,\n        )}\n      >\n        {children}\n      </Comp>\n    </>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/lib/text-shimmer.ts",
          "target": "@components/beui/lib/text-shimmer.ts",
          "type": "registry:component",
          "content": "import type { CSSProperties } from \"react\";\n\n// The reduced-motion rule travels with the component. app/globals.css calms CSS\n// animation globally, but the registry bundles imports only, so an installed\n// copy never receives that reset.\n//\n// `!important` because the sweep is an inline style, which outranks a plain rule\n// in a media query. It selects a marker class carried by TEXT_SHIMMER_CLASS_NAME\n// so it also reaches consumers that build their own span out of these exports.\nexport const TEXT_SHIMMER_KEYFRAMES =\n  \"@keyframes beui-text-shimmer{from{background-position:200% 0}to{background-position:-200% 0}}\" +\n  \"@media (prefers-reduced-motion: reduce){.beui-text-shimmer{animation:none !important}}\";\n\nexport const TEXT_SHIMMER_CLASS_NAME =\n  \"beui-text-shimmer bg-[length:200%_100%] bg-clip-text text-transparent bg-[linear-gradient(110deg,var(--muted-foreground)_30%,var(--foreground)_50%,var(--muted-foreground)_70%)]\";\n\nexport function textShimmerStyle(duration: number): CSSProperties {\n  return {\n    animation: `beui-text-shimmer ${duration}s linear infinite`,\n  };\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-agent-progress",
      "type": "registry:block",
      "title": "Beui Agent Progress",
      "description": "Agent Loading States Agent Progress",
      "dependencies": [
        "clsx@^2.1.1",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/loading-states/agent-progress.tsx",
          "target": "@components/beui/components/agents/loading-states/agent-progress.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { useEffect, useState } from \"react\";\nimport { EASE_IN_OUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nconst GRID_CELLS = [\n  { id: \"top-left\", delay: 0 },\n  { id: \"top-center\", delay: 0.14 },\n  { id: \"top-right\", delay: 0.28 },\n  { id: \"middle-left\", delay: 0.42 },\n  { id: \"middle-center\", delay: 0.56 },\n  { id: \"middle-right\", delay: 0.7 },\n  { id: \"bottom-left\", delay: 0.84 },\n  { id: \"bottom-center\", delay: 0.98 },\n  { id: \"bottom-right\", delay: 1.12 },\n];\n\nexport interface AgentProgressProps {\n  /** Verb describing the agent's current activity. */\n  label?: string;\n  /** Controlled elapsed time in seconds. */\n  elapsedSeconds?: number;\n  /** Starting time for the internal timer, in seconds. */\n  initialSeconds?: number;\n  /** Whether the internal timer should advance. Ignored when elapsedSeconds is provided. */\n  running?: boolean;\n  className?: string;\n}\n\nfunction formatElapsed(totalSeconds: number) {\n  const safeSeconds = Math.max(0, totalSeconds);\n  const minutes = Math.floor(safeSeconds / 60);\n  const seconds = (safeSeconds % 60).toFixed(1);\n  return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;\n}\n\nexport function AgentProgress({\n  label = \"Churning\",\n  elapsedSeconds,\n  initialSeconds = 0,\n  running = true,\n  className,\n}: AgentProgressProps) {\n  const reduce = useReducedMotion() ?? false;\n  const [internalSeconds, setInternalSeconds] = useState(initialSeconds);\n\n  useEffect(() => {\n    if (elapsedSeconds !== undefined || !running) return;\n\n    const startedAt = performance.now() - initialSeconds * 1000;\n    const timer = window.setInterval(() => {\n      setInternalSeconds((performance.now() - startedAt) / 1000);\n    }, 100);\n\n    return () => window.clearInterval(timer);\n  }, [elapsedSeconds, initialSeconds, running]);\n\n  const elapsed = elapsedSeconds ?? internalSeconds;\n\n  return (\n    <span\n      role=\"status\"\n      aria-label={`${label}, in progress`}\n      className={cn(\n        \"inline-flex items-center gap-3 font-mono text-sm text-muted-foreground\",\n        className,\n      )}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"grid size-5 shrink-0 grid-cols-3 gap-[2px]\"\n      >\n        {GRID_CELLS.map(({ id, delay }) => (\n          <motion.span\n            key={id}\n            className=\"rounded-[1px] bg-current\"\n            animate={\n              reduce\n                ? { opacity: [0.35, 0.8, 0.35] }\n                : {\n                    opacity: [0.28, 1, 0.28],\n                    scale: [0.72, 1, 0.72],\n                  }\n            }\n            transition={{\n              duration: 1.55,\n              ease: EASE_IN_OUT,\n              repeat: Infinity,\n              delay,\n            }}\n          />\n        ))}\n      </span>\n      <span className=\"font-sans font-medium\">{label}</span>\n      <span\n        aria-hidden=\"true\"\n        className=\"tabular-nums text-muted-foreground/70\"\n      >\n        {formatElapsed(elapsed)}\n      </span>\n    </span>\n  );\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-ai-sidebar",
      "type": "registry:block",
      "title": "Beui Ai Sidebar",
      "description": "AI Sidebar",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/ai-sidebar.tsx",
          "target": "@components/beui/components/agents/ai-sidebar.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  ArrowDown,\n  ArrowUp,\n  Bookmark,\n  FileText,\n  Folder,\n  FolderInput,\n  FolderOpen,\n  type LucideIcon,\n  MoreHorizontal,\n  Pencil,\n  Undo2,\n} from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  type DragEvent,\n  type KeyboardEvent,\n  type ReactNode,\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport {\n  MorphPopover,\n  MorphPopoverContent,\n  MorphPopoverTrigger,\n} from \"@/components/beui/components/motion/popover-morph\";\nimport { EASE_OUT, SPRING_LAYOUT } from \"@/components/beui/lib/ease\";\nimport { useTouchCapable } from \"@/components/beui/lib/hooks/use-touch-capable\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport type SidebarResourceKind =\n  | \"folder\"\n  | \"project\"\n  | \"file\"\n  | \"bookmark\";\n\nexport interface SidebarResource {\n  id: string;\n  label: string;\n  kind: SidebarResourceKind;\n  children?: SidebarResource[];\n  disabled?: boolean;\n}\n\nexport type SidebarResourceDropPosition = \"before\" | \"inside\" | \"after\";\n\nexport interface SidebarResourceMove {\n  itemId: string;\n  targetId: string | null;\n  position: SidebarResourceDropPosition;\n}\n\n/**\n * The moves this row can make right now, the same four the keyboard offers on\n * `Alt+Shift+Arrow`. A pointer drag is the fast path for them; a finger has no\n * drag to give, so the row menu carries them too. Absent keys are moves this\n * row cannot make from where it sits.\n */\nexport interface SidebarResourceMoveCommands {\n  up?: () => void;\n  down?: () => void;\n  into?: { label: string; run: () => void };\n  out?: () => void;\n}\n\nexport interface SidebarResourceMenuControls {\n  close: () => void;\n  rename: () => void;\n  moves: SidebarResourceMoveCommands;\n}\n\nexport interface AISidebarProps {\n  items?: SidebarResource[];\n  defaultItems?: SidebarResource[];\n  onItemsChange?: (items: SidebarResource[]) => void;\n  /** Reject the promise to roll the optimistic move back. */\n  onMove?: (move: SidebarResourceMove) => void | Promise<void>;\n  onMoveError?: (error: unknown, move: SidebarResourceMove) => void;\n  onRename?: (item: SidebarResource, label: string) => void | Promise<void>;\n  activeId?: string | null;\n  defaultActiveId?: string | null;\n  onActiveChange?: (id: string) => void;\n  defaultExpandedIds?: string[];\n  renderIcon?: (item: SidebarResource) => ReactNode;\n  renderMenu?: (\n    item: SidebarResource,\n    controls: SidebarResourceMenuControls,\n  ) => ReactNode;\n  ariaLabel?: string;\n  className?: string;\n}\n\ninterface FlatResource {\n  item: SidebarResource;\n  depth: number;\n  parentId: string | null;\n}\n\ninterface DropTarget {\n  id: string | null;\n  position: SidebarResourceDropPosition;\n}\n\nconst ROW_REVEAL = {\n  duration: 0.16,\n  ease: EASE_OUT,\n} as const;\n\nfunction canContain(item: SidebarResource) {\n  return item.kind === \"folder\" || item.kind === \"project\";\n}\n\nfunction flattenResources(\n  items: SidebarResource[],\n  expanded: Set<string>,\n  depth = 0,\n  parentId: string | null = null,\n): FlatResource[] {\n  return items.flatMap((item) => {\n    const row = { item, depth, parentId };\n    if (!item.children?.length || !expanded.has(item.id)) return [row];\n    return [\n      row,\n      ...flattenResources(item.children, expanded, depth + 1, item.id),\n    ];\n  });\n}\n\nfunction findResource(\n  items: SidebarResource[],\n  id: string,\n): SidebarResource | undefined {\n  for (const item of items) {\n    if (item.id === id) return item;\n    const child = item.children ? findResource(item.children, id) : undefined;\n    if (child) return child;\n  }\n}\n\nfunction containsResource(item: SidebarResource, id: string): boolean {\n  return (\n    item.id === id ||\n    item.children?.some((child) => containsResource(child, id)) === true\n  );\n}\n\nfunction removeResource(\n  items: SidebarResource[],\n  id: string,\n): { items: SidebarResource[]; removed?: SidebarResource } {\n  let removed: SidebarResource | undefined;\n  const next: SidebarResource[] = [];\n\n  for (const item of items) {\n    if (item.id === id) {\n      removed = item;\n      continue;\n    }\n\n    if (item.children?.length) {\n      const childResult = removeResource(item.children, id);\n      if (childResult.removed) {\n        removed = childResult.removed;\n        next.push({ ...item, children: childResult.items });\n        continue;\n      }\n    }\n\n    next.push(item);\n  }\n\n  return { items: next, removed };\n}\n\nfunction insertResource(\n  items: SidebarResource[],\n  resource: SidebarResource,\n  targetId: string | null,\n  position: SidebarResourceDropPosition,\n): SidebarResource[] {\n  if (targetId === null) return [...items, resource];\n\n  const next: SidebarResource[] = [];\n  for (const item of items) {\n    if (item.id === targetId) {\n      if (position === \"before\") next.push(resource, item);\n      else if (position === \"after\") next.push(item, resource);\n      else next.push({ ...item, children: [...(item.children ?? []), resource] });\n      continue;\n    }\n\n    if (item.children?.length) {\n      next.push({\n        ...item,\n        children: insertResource(item.children, resource, targetId, position),\n      });\n    } else {\n      next.push(item);\n    }\n  }\n  return next;\n}\n\nfunction moveResource(\n  items: SidebarResource[],\n  move: SidebarResourceMove,\n): SidebarResource[] | null {\n  const source = findResource(items, move.itemId);\n  if (!source || source.disabled) return null;\n  if (move.targetId && containsResource(source, move.targetId)) return null;\n\n  const target = move.targetId ? findResource(items, move.targetId) : undefined;\n  if (\n    move.position === \"inside\" &&\n    (!target || target.disabled || !canContain(target))\n  )\n    return null;\n\n  const removed = removeResource(items, move.itemId);\n  if (!removed.removed) return null;\n  return insertResource(\n    removed.items,\n    removed.removed,\n    move.targetId,\n    move.position,\n  );\n}\n\nfunction renameResource(\n  items: SidebarResource[],\n  id: string,\n  label: string,\n): SidebarResource[] {\n  return items.map((item) => ({\n    ...item,\n    label: item.id === id ? label : item.label,\n    children: item.children\n      ? renameResource(item.children, id, label)\n      : undefined,\n  }));\n}\n\nfunction defaultIcon(item: SidebarResource, expanded: boolean) {\n  const Icon =\n    item.kind === \"folder\" || item.kind === \"project\"\n      ? expanded\n        ? FolderOpen\n        : Folder\n      : item.kind === \"bookmark\"\n          ? Bookmark\n          : FileText;\n  return <Icon className=\"size-4\" />;\n}\n\nfunction MarqueeLabel({ active, children }: { active: boolean; children: string }) {\n  const reduce = useReducedMotion() ?? false;\n  const viewportRef = useRef<HTMLSpanElement>(null);\n  const labelRef = useRef<HTMLSpanElement>(null);\n  const [distance, setDistance] = useState(0);\n\n  useEffect(() => {\n    const measure = () => {\n      const viewport = viewportRef.current;\n      const label = labelRef.current;\n      if (!viewport || !label) return;\n      setDistance(label.scrollWidth > viewport.clientWidth ? label.scrollWidth + 24 : 0);\n    };\n    measure();\n    const observer = new ResizeObserver(measure);\n    if (viewportRef.current) observer.observe(viewportRef.current);\n    if (labelRef.current) observer.observe(labelRef.current);\n    return () => observer.disconnect();\n  }, []);\n\n  const running = active && distance > 0 && !reduce;\n\n  return (\n    <span ref={viewportRef} className=\"block min-w-0 flex-1 overflow-hidden\">\n      <motion.span\n        className=\"flex w-max items-center gap-6 whitespace-nowrap\"\n        animate={{ x: running ? [0, -distance] : 0 }}\n        transition={\n          running\n            ? {\n                duration: Math.max(2.4, distance / 34),\n                ease: \"linear\",\n                repeat: Number.POSITIVE_INFINITY,\n                repeatDelay: 2,\n              }\n            : ROW_REVEAL\n        }\n      >\n        <span ref={labelRef}>{children}</span>\n        {running ? <span aria-hidden=\"true\">{children}</span> : null}\n      </motion.span>\n    </span>\n  );\n}\n\nfunction ResourceMenuAction({\n  icon: Icon,\n  onSelect,\n  children,\n}: {\n  icon: LucideIcon;\n  onSelect: () => void;\n  children: ReactNode;\n}) {\n  return (\n    <button\n      type=\"button\"\n      onClick={onSelect}\n      className=\"flex h-8 w-full items-center gap-2 rounded-lg px-2.5 text-left text-xs text-foreground outline-none transition-colors hover:bg-muted focus-visible:bg-muted focus-visible:ring-2 focus-visible:ring-ring\"\n    >\n      <Icon aria-hidden=\"true\" className=\"size-3.5 shrink-0\" />\n      <span className=\"min-w-0 truncate\">{children}</span>\n    </button>\n  );\n}\n\ninterface ResourceRowProps {\n  row: FlatResource;\n  active: boolean;\n  expanded: boolean;\n  focused: boolean;\n  draggingId: string | null;\n  dropTarget: DropTarget | null;\n  menuOpen: boolean;\n  moves: SidebarResourceMoveCommands;\n  renaming: boolean;\n  onDragEnd: () => void;\n  onDragOver: (event: DragEvent<HTMLDivElement>, row: FlatResource) => void;\n  onDragStart: (event: DragEvent<HTMLDivElement>, id: string) => void;\n  onDrop: (event: DragEvent<HTMLDivElement>) => void;\n  onFocus: () => void;\n  onKeyDown: (event: KeyboardEvent<HTMLDivElement>) => void;\n  onMenuOpenChange: (open: boolean) => void;\n  onRenameCancel: () => void;\n  onRenameCommit: (label: string) => void;\n  onRenameStart: () => void;\n  onSelect: () => void;\n  onToggle: () => void;\n  renderIcon?: (item: SidebarResource) => ReactNode;\n  renderMenu?: AISidebarProps[\"renderMenu\"];\n  setRef: (node: HTMLDivElement | null) => void;\n}\n\nfunction ResourceRow({\n  row,\n  active,\n  expanded,\n  focused,\n  draggingId,\n  dropTarget,\n  menuOpen,\n  moves,\n  renaming,\n  onDragEnd,\n  onDragOver,\n  onDragStart,\n  onDrop,\n  onFocus,\n  onKeyDown,\n  onMenuOpenChange,\n  onRenameCancel,\n  onRenameCommit,\n  onRenameStart,\n  onSelect,\n  onToggle,\n  renderIcon,\n  renderMenu,\n  setRef,\n}: ResourceRowProps) {\n  const reduce = useReducedMotion() ?? false;\n  const canTouch = useTouchCapable();\n  const [hovered, setHovered] = useState(false);\n  const inputRef = useRef<HTMLInputElement>(null);\n  const skipRenameBlurRef = useRef(false);\n  const draggedRef = useRef(false);\n  const [draft, setDraft] = useState(row.item.label);\n  const acceptsChildren = canContain(row.item);\n  const isDragging = draggingId === row.item.id;\n  const dropPosition = dropTarget?.id === row.item.id ? dropTarget.position : null;\n\n  useEffect(() => {\n    if (!renaming) return;\n    skipRenameBlurRef.current = false;\n    setDraft(row.item.label);\n    requestAnimationFrame(() => {\n      inputRef.current?.focus();\n      inputRef.current?.select();\n    });\n  }, [renaming, row.item.label]);\n\n  const runFromMenu = (action: () => void) => () => {\n    onMenuOpenChange(false);\n    action();\n  };\n\n  const menu = renderMenu?.(row.item, {\n    close: () => onMenuOpenChange(false),\n    rename: () => {\n      onMenuOpenChange(false);\n      onRenameStart();\n    },\n    moves,\n  }) ?? (\n    <>\n      <ResourceMenuAction icon={Pencil} onSelect={runFromMenu(onRenameStart)}>\n        Rename\n      </ResourceMenuAction>\n      {moves.up || moves.down || moves.into || moves.out ? (\n        <div aria-hidden=\"true\" className=\"my-1 h-px bg-border\" />\n      ) : null}\n      {moves.up ? (\n        <ResourceMenuAction icon={ArrowUp} onSelect={runFromMenu(moves.up)}>\n          Move up\n        </ResourceMenuAction>\n      ) : null}\n      {moves.down ? (\n        <ResourceMenuAction icon={ArrowDown} onSelect={runFromMenu(moves.down)}>\n          Move down\n        </ResourceMenuAction>\n      ) : null}\n      {moves.into ? (\n        <ResourceMenuAction\n          icon={FolderInput}\n          onSelect={runFromMenu(moves.into.run)}\n        >\n          Move into {moves.into.label}\n        </ResourceMenuAction>\n      ) : null}\n      {moves.out ? (\n        <ResourceMenuAction icon={Undo2} onSelect={runFromMenu(moves.out)}>\n          Move out\n        </ResourceMenuAction>\n      ) : null}\n    </>\n  );\n\n  return (\n    <motion.div\n      ref={setRef}\n      layout=\"position\"\n      transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n      role=\"treeitem\"\n      aria-level={row.depth + 1}\n      aria-selected={acceptsChildren ? undefined : active}\n      aria-expanded={acceptsChildren ? expanded : undefined}\n      aria-disabled={row.item.disabled || undefined}\n      tabIndex={focused ? 0 : -1}\n      draggable={!row.item.disabled && !renaming}\n      data-menu-open={menuOpen || undefined}\n      data-drop={dropPosition ?? undefined}\n      data-dragging={isDragging || undefined}\n      onFocus={onFocus}\n      onKeyDown={onKeyDown}\n      onClick={(event) => {\n        if (\n          event.defaultPrevented ||\n          draggedRef.current ||\n          renaming ||\n          row.item.disabled\n        )\n          return;\n        if (acceptsChildren) onToggle();\n        else onSelect();\n      }}\n      onDoubleClick={(event) => {\n        if (acceptsChildren || row.item.disabled) return;\n        event.preventDefault();\n        onRenameStart();\n      }}\n      onMouseEnter={() => setHovered(true)}\n      onMouseLeave={() => setHovered(false)}\n      onDragStartCapture={(event) => {\n        draggedRef.current = true;\n        onDragStart(event, row.item.id);\n      }}\n      onDragEndCapture={() => {\n        onDragEnd();\n        requestAnimationFrame(() => {\n          draggedRef.current = false;\n        });\n      }}\n      onDragOver={(event) => onDragOver(event, row)}\n      onDrop={onDrop}\n      className={cn(\n        \"group/resource relative flex min-h-9 min-w-0 cursor-pointer items-center gap-2.5 rounded-md pr-3 text-sm outline-none\",\n        \"text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n        \"focus-visible:bg-muted/70 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n        \"data-[menu-open=true]:bg-muted data-[menu-open=true]:text-foreground\",\n        \"data-[dragging=true]:opacity-40\",\n        \"data-[drop=inside]:bg-primary/10 data-[drop=inside]:ring-1 data-[drop=inside]:ring-primary/45\",\n        \"data-[drop=before]:before:absolute data-[drop=before]:before:-top-0.5 data-[drop=before]:before:right-2 data-[drop=before]:before:left-2 data-[drop=before]:before:h-0.5 data-[drop=before]:before:rounded-full data-[drop=before]:before:bg-primary\",\n        \"data-[drop=after]:after:absolute data-[drop=after]:after:-bottom-0.5 data-[drop=after]:after:right-2 data-[drop=after]:after:left-2 data-[drop=after]:after:h-0.5 data-[drop=after]:after:rounded-full data-[drop=after]:after:bg-primary\",\n        !acceptsChildren && active && \"bg-muted text-foreground\",\n        row.item.disabled && \"cursor-not-allowed opacity-45\",\n      )}\n      style={{ paddingLeft: `${12 + row.depth * 16}px` }}\n    >\n      <span aria-hidden=\"true\" className=\"grid size-5 shrink-0 place-items-center\">\n        {renderIcon?.(row.item) ?? defaultIcon(row.item, expanded)}\n      </span>\n\n      {renaming ? (\n        <input\n          ref={inputRef}\n          value={draft}\n          aria-label={`Rename ${row.item.label}`}\n          onChange={(event) => setDraft(event.target.value)}\n          draggable={false}\n          onClick={(event) => event.stopPropagation()}\n          onDoubleClick={(event) => event.stopPropagation()}\n          onBlur={() => {\n            if (!skipRenameBlurRef.current) onRenameCommit(draft);\n          }}\n          onKeyDown={(event) => {\n            event.stopPropagation();\n            if (event.key === \"Enter\") {\n              skipRenameBlurRef.current = true;\n              onRenameCommit(draft);\n            }\n            if (event.key === \"Escape\") {\n              skipRenameBlurRef.current = true;\n              onRenameCancel();\n            }\n          }}\n          className=\"mx-1 h-7 min-w-0 flex-1 rounded-md border border-border bg-background px-2 text-sm text-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n        />\n      ) : (\n        <MarqueeLabel active={hovered || menuOpen}>{row.item.label}</MarqueeLabel>\n      )}\n\n      {!renaming && !row.item.disabled ? (\n        <MorphPopover\n          open={menuOpen}\n          onOpenChange={onMenuOpenChange}\n        >\n          <MorphPopoverTrigger>\n            <button\n              type=\"button\"\n              draggable={false}\n              tabIndex={-1}\n              aria-label={`Actions for ${row.item.label}`}\n              onClick={(event) => event.stopPropagation()}\n              className={cn(\n                \"grid size-7 shrink-0 place-items-center rounded-lg outline-none transition-opacity hover:bg-foreground/5 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring group-hover/resource:opacity-100 group-data-[menu-open=true]/resource:opacity-100\",\n                // A finger never hovers, and this menu is the only path to\n                // rename and move without a drag — keep it on screen there.\n                canTouch ? \"opacity-100\" : \"opacity-0\",\n              )}\n            >\n              <MoreHorizontal aria-hidden=\"true\" className=\"size-4\" />\n            </button>\n          </MorphPopoverTrigger>\n          <MorphPopoverContent\n            side=\"bottom\"\n            align=\"end\"\n            sideOffset={8}\n            radius={12}\n            className=\"w-40 p-1.5\"\n          >\n            <div data-sidebar-resource-menu={row.item.id}>{menu}</div>\n          </MorphPopoverContent>\n        </MorphPopover>\n      ) : null}\n    </motion.div>\n  );\n}\n\nexport function AISidebar({\n  items,\n  defaultItems = [],\n  onItemsChange,\n  onMove,\n  onMoveError,\n  onRename,\n  activeId,\n  defaultActiveId = null,\n  onActiveChange,\n  defaultExpandedIds = [],\n  renderIcon,\n  renderMenu,\n  ariaLabel = \"Resources\",\n  className,\n}: AISidebarProps) {\n  const [internalItems, setInternalItems] = useState(items ?? defaultItems);\n  const [internalActiveId, setInternalActiveId] = useState(defaultActiveId);\n  const [expandedIds, setExpandedIds] = useState(\n    () => new Set(defaultExpandedIds),\n  );\n  const [focusedId, setFocusedId] = useState<string | null>(\n    activeId ?? defaultActiveId,\n  );\n  const [draggingId, setDraggingId] = useState<string | null>(null);\n  const [dropTarget, setDropTarget] = useState<DropTarget | null>(null);\n  const [menuOpenId, setMenuOpenId] = useState<string | null>(null);\n  const [renamingId, setRenamingId] = useState<string | null>(null);\n  const [announcement, setAnnouncement] = useState(\"\");\n  const rowRefs = useRef(new Map<string, HTMLDivElement>());\n  const movePendingRef = useRef(false);\n  const renderedItems = internalItems;\n  const selectedId = activeId ?? internalActiveId;\n\n  useEffect(() => {\n    if (items) setInternalItems(items);\n  }, [items]);\n\n  const flat = useMemo(\n    () => flattenResources(renderedItems, expandedIds),\n    [expandedIds, renderedItems],\n  );\n\n  // Which row carries the roving tabindex is resolved during render, never in\n  // a passive effect: an effect lands after the browser paints, so the first\n  // commit — and, on a server-rendered page, the markup itself — would have no\n  // tabbable row and Tab would skip the whole tree. The same hole opens again\n  // whenever a collapse or a rolled-back move takes the focused row out of it.\n  const focusedRow =\n    focusedId !== null && flat.some((row) => row.item.id === focusedId)\n      ? focusedId\n      : (flat[0]?.item.id ?? null);\n  if (focusedId !== focusedRow) setFocusedId(focusedRow);\n\n  useEffect(() => {\n    if (!menuOpenId) return;\n    const frame = requestAnimationFrame(() => {\n      const menus = Array.from(\n        document.querySelectorAll<HTMLElement>(\"[data-sidebar-resource-menu]\"),\n      );\n      menus\n        .find((menu) => menu.dataset.sidebarResourceMenu === menuOpenId)\n        ?.querySelector<HTMLElement>(\"button, a[href]\")\n        ?.focus();\n    });\n    return () => cancelAnimationFrame(frame);\n  }, [menuOpenId]);\n\n  const updateItems = useCallback(\n    (next: SidebarResource[]) => {\n      setInternalItems(next);\n      onItemsChange?.(next);\n    },\n    [onItemsChange],\n  );\n\n  const performMove = useCallback(\n    async (move: SidebarResourceMove) => {\n      if (movePendingRef.current) {\n        setAnnouncement(\"Wait for the current move to finish.\");\n        return;\n      }\n      const before = renderedItems;\n      const next = moveResource(before, move);\n      if (!next || next === before) return;\n\n      movePendingRef.current = true;\n      updateItems(next);\n      setDropTarget(null);\n      setDraggingId(null);\n      const moved = findResource(before, move.itemId);\n      const target = move.targetId ? findResource(before, move.targetId) : null;\n      setAnnouncement(\n        target\n          ? `Moved ${moved?.label ?? \"item\"} ${move.position} ${target.label}.`\n          : `Moved ${moved?.label ?? \"item\"} to the top level.`,\n      );\n\n      try {\n        await onMove?.(move);\n      } catch (error) {\n        updateItems(before);\n        setAnnouncement(`Move failed. ${moved?.label ?? \"Item\"} was restored.`);\n        onMoveError?.(error, move);\n      } finally {\n        movePendingRef.current = false;\n      }\n    },\n    [onMove, onMoveError, renderedItems, updateItems],\n  );\n\n  const focusRow = useCallback((id: string) => {\n    setFocusedId(id);\n    requestAnimationFrame(() => rowRefs.current.get(id)?.focus());\n  }, []);\n\n  const select = useCallback(\n    (id: string) => {\n      if (activeId === undefined) setInternalActiveId(id);\n      onActiveChange?.(id);\n    },\n    [activeId, onActiveChange],\n  );\n\n  const toggle = useCallback((id: string) => {\n    setExpandedIds((current) => {\n      const next = new Set(current);\n      if (next.has(id)) next.delete(id);\n      else next.add(id);\n      return next;\n    });\n  }, []);\n\n  // The same four moves `Alt+Shift+Arrow` performs, handed to the row menu so\n  // they survive on a device with no drag and no modifier keys.\n  const moveCommands = useCallback(\n    (row: FlatResource): SidebarResourceMoveCommands => {\n      if (row.item.disabled) return {};\n      const index = flat.findIndex(({ item }) => item.id === row.item.id);\n      const previous = flat[index - 1];\n      const next = flat[index + 1];\n      const parentId = row.parentId;\n      const commands: SidebarResourceMoveCommands = {};\n\n      if (previous) {\n        commands.up = () =>\n          void performMove({\n            itemId: row.item.id,\n            targetId: previous.item.id,\n            position: \"before\",\n          });\n      }\n      if (next) {\n        commands.down = () =>\n          void performMove({\n            itemId: row.item.id,\n            targetId: next.item.id,\n            position: \"after\",\n          });\n      }\n      // Only offer the reparent when it lands somewhere new — the row above a\n      // folder's first child is the folder it already lives in.\n      if (previous && canContain(previous.item) && previous.item.id !== parentId) {\n        commands.into = {\n          label: previous.item.label,\n          run: () => {\n            setExpandedIds((current) => new Set(current).add(previous.item.id));\n            void performMove({\n              itemId: row.item.id,\n              targetId: previous.item.id,\n              position: \"inside\",\n            });\n          },\n        };\n      }\n      if (parentId) {\n        commands.out = () =>\n          void performMove({\n            itemId: row.item.id,\n            targetId: parentId,\n            position: \"after\",\n          });\n      }\n\n      return commands;\n    },\n    [flat, performMove],\n  );\n\n  const handleKeyDown = useCallback(\n    (event: KeyboardEvent<HTMLDivElement>, row: FlatResource) => {\n      const index = flat.findIndex(({ item }) => item.id === row.item.id);\n      const previous = flat[index - 1];\n      const next = flat[index + 1];\n      const moveModifier = event.altKey && event.shiftKey;\n\n      if (event.key === \"ArrowDown\" && !moveModifier && next) {\n        event.preventDefault();\n        focusRow(next.item.id);\n        return;\n      }\n      if (event.key === \"ArrowUp\" && !moveModifier && previous) {\n        event.preventDefault();\n        focusRow(previous.item.id);\n        return;\n      }\n      if (event.key === \"Home\" && flat[0]) {\n        event.preventDefault();\n        focusRow(flat[0].item.id);\n        return;\n      }\n      if (event.key === \"End\" && flat.at(-1)) {\n        event.preventDefault();\n        focusRow(flat.at(-1)?.item.id ?? row.item.id);\n        return;\n      }\n\n      if (row.item.disabled) {\n        if (event.key === \"ArrowLeft\" && row.parentId) {\n          event.preventDefault();\n          focusRow(row.parentId);\n        } else if (\n          moveModifier ||\n          [\"ArrowRight\", \"Enter\", \" \", \"F2\", \"ContextMenu\"].includes(\n            event.key,\n          ) ||\n          (event.shiftKey && event.key === \"F10\")\n        ) {\n          event.preventDefault();\n        }\n        return;\n      }\n\n      if (moveModifier && event.key === \"ArrowUp\" && previous) {\n        event.preventDefault();\n        void performMove({ itemId: row.item.id, targetId: previous.item.id, position: \"before\" });\n        return;\n      }\n      if (moveModifier && event.key === \"ArrowDown\" && next) {\n        event.preventDefault();\n        void performMove({ itemId: row.item.id, targetId: next.item.id, position: \"after\" });\n        return;\n      }\n      if (moveModifier && event.key === \"ArrowRight\" && previous && canContain(previous.item)) {\n        event.preventDefault();\n        setExpandedIds((current) => new Set(current).add(previous.item.id));\n        void performMove({ itemId: row.item.id, targetId: previous.item.id, position: \"inside\" });\n        return;\n      }\n      if (moveModifier && event.key === \"ArrowLeft\" && row.parentId) {\n        event.preventDefault();\n        void performMove({ itemId: row.item.id, targetId: row.parentId, position: \"after\" });\n        return;\n      }\n\n      if (event.key === \"ArrowRight\" && canContain(row.item)) {\n        event.preventDefault();\n        if (!expandedIds.has(row.item.id)) toggle(row.item.id);\n        else if (next?.parentId === row.item.id) focusRow(next.item.id);\n      } else if (event.key === \"ArrowLeft\") {\n        event.preventDefault();\n        if (expandedIds.has(row.item.id)) toggle(row.item.id);\n        else if (row.parentId) focusRow(row.parentId);\n      } else if (event.key === \"Enter\" || event.key === \" \") {\n        event.preventDefault();\n        if (canContain(row.item)) toggle(row.item.id);\n        else select(row.item.id);\n      } else if (event.key === \"F2\") {\n        event.preventDefault();\n        setRenamingId(row.item.id);\n      } else if (event.key === \"ContextMenu\" || (event.shiftKey && event.key === \"F10\")) {\n        event.preventDefault();\n        setMenuOpenId(row.item.id);\n      }\n    },\n    [expandedIds, flat, focusRow, performMove, select, toggle],\n  );\n\n  return (\n    <>\n      <div\n      role=\"tree\"\n      aria-label={ariaLabel}\n      aria-multiselectable=\"false\"\n      onDragOver={(event) => {\n        if (!draggingId || event.target !== event.currentTarget) return;\n        event.preventDefault();\n        setDropTarget({ id: null, position: \"after\" });\n      }}\n      onDrop={(event) => {\n        event.preventDefault();\n        if (draggingId && dropTarget) {\n          void performMove({\n            itemId: draggingId,\n            targetId: dropTarget.id,\n            position: dropTarget.position,\n          });\n        }\n      }}\n      className={cn(\n        \"relative flex min-w-0 flex-col gap-0.5 [overflow-anchor:none] group-data-[state=collapsed]/sidebar:hidden\",\n        draggingId && \"select-none pb-9\",\n        className,\n      )}\n    >\n      <AnimatePresence initial={false}>\n        {flat.map((row) => (\n          <ResourceRow\n            key={row.item.id}\n            row={row}\n            active={selectedId === row.item.id}\n            expanded={expandedIds.has(row.item.id)}\n            focused={focusedRow === row.item.id}\n            draggingId={draggingId}\n            dropTarget={dropTarget}\n            menuOpen={menuOpenId === row.item.id}\n            moves={moveCommands(row)}\n            renaming={renamingId === row.item.id}\n            onFocus={() => setFocusedId(row.item.id)}\n            onSelect={() => select(row.item.id)}\n            onToggle={() => toggle(row.item.id)}\n            onKeyDown={(event) => handleKeyDown(event, row)}\n            onRenameStart={() => setRenamingId(row.item.id)}\n            onRenameCancel={() => setRenamingId(null)}\n            onRenameCommit={(label) => {\n              const trimmed = label.trim();\n              setRenamingId(null);\n              if (!trimmed || trimmed === row.item.label) return;\n              const before = renderedItems;\n              updateItems(renameResource(before, row.item.id, trimmed));\n              void Promise.resolve(onRename?.(row.item, trimmed)).catch(() => {\n                updateItems(before);\n                setAnnouncement(`Rename failed. ${row.item.label} was restored.`);\n              });\n            }}\n            onMenuOpenChange={(open) => {\n              setMenuOpenId(open ? row.item.id : null);\n              if (!open) focusRow(row.item.id);\n            }}\n            onDragStart={(event, id) => {\n              setDraggingId(id);\n              event.dataTransfer.effectAllowed = \"move\";\n              event.dataTransfer.setData(\"text/plain\", id);\n            }}\n            onDragEnd={() => {\n              setDraggingId(null);\n              setDropTarget(null);\n            }}\n            onDragOver={(event, targetRow) => {\n              if (!draggingId || draggingId === targetRow.item.id) return;\n              const source = findResource(renderedItems, draggingId);\n              if (source && containsResource(source, targetRow.item.id)) return;\n              event.preventDefault();\n              event.stopPropagation();\n              const rect = event.currentTarget.getBoundingClientRect();\n              const ratio = (event.clientY - rect.top) / rect.height;\n              const position =\n                !targetRow.item.disabled &&\n                canContain(targetRow.item) &&\n                ratio >= 0.25 &&\n                ratio <= 0.75\n                  ? \"inside\"\n                  : ratio < 0.5\n                    ? \"before\"\n                    : \"after\";\n              setDropTarget({ id: targetRow.item.id, position });\n            }}\n            onDrop={(event) => {\n              event.preventDefault();\n              event.stopPropagation();\n              if (draggingId && dropTarget) {\n                void performMove({\n                  itemId: draggingId,\n                  targetId: dropTarget.id,\n                  position: dropTarget.position,\n                });\n              }\n            }}\n            renderIcon={renderIcon}\n            renderMenu={renderMenu}\n            setRef={(node) => {\n              if (node) rowRefs.current.set(row.item.id, node);\n              else rowRefs.current.delete(row.item.id);\n            }}\n          />\n        ))}\n      </AnimatePresence>\n\n      {draggingId ? (\n        <div\n          aria-hidden=\"true\"\n          data-active={dropTarget?.id === null || undefined}\n          className=\"absolute inset-x-1 bottom-0 flex h-8 items-center justify-center rounded-lg border border-dashed border-border text-[10px] text-muted-foreground data-[active=true]:border-primary/50 data-[active=true]:bg-primary/10 data-[active=true]:text-foreground\"\n        >\n          Move to top level\n        </div>\n      ) : null}\n\n      </div>\n      <span className=\"sr-only\" aria-live=\"polite\">\n        {announcement}\n      </span>\n    </>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/popover-morph.tsx",
          "target": "@components/beui/components/motion/popover-morph.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n  cloneElement,\n  createContext,\n  isValidElement,\n  type ReactElement,\n  type ReactNode,\n  type Ref,\n  useCallback,\n  useContext,\n  useEffect,\n  useId,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { usePopoverPortalPosition } from \"@/components/beui/components/motion/popover-position\";\nimport { EASE_OUT, SPRING_PANEL } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\ntype Side = \"top\" | \"bottom\";\ntype Align = \"start\" | \"end\";\n\ntype MorphContextValue = {\n  open: boolean;\n  setOpen: (open: boolean) => void;\n  toggle: () => void;\n  triggerId: string;\n  contentId: string;\n  /** The element the panel measures against — see `registerTrigger`. */\n  triggerRef: React.MutableRefObject<HTMLElement | null>;\n  registerTrigger: (node: HTMLElement | null) => void;\n  contentRef: React.MutableRefObject<HTMLDivElement | null>;\n};\n\nconst MorphContext = createContext<MorphContextValue | null>(null);\n\nfunction useMorphContext(component: string) {\n  const ctx = useContext(MorphContext);\n  if (!ctx) throw new Error(`${component} must be used within <MorphPopover>`);\n  return ctx;\n}\n\nexport interface MorphPopoverProps {\n  children: ReactNode;\n  /** Controlled open state. */\n  open?: boolean;\n  /** Uncontrolled initial open state. */\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  className?: string;\n}\n\n/**\n * A popover whose panel morphs open from the trigger corner: it's laid out at\n * full size but clipped to the corner nearest the trigger, then unclips as one\n * piece. Closes on outside pointer / Escape. Controlled or uncontrolled.\n */\nexport function MorphPopover({\n  children,\n  open: controlledOpen,\n  defaultOpen = false,\n  onOpenChange,\n  className,\n}: MorphPopoverProps) {\n  const baseId = useId();\n  const [root, setRoot] = useState<HTMLDivElement | null>(null);\n  const [trigger, setTrigger] = useState<HTMLElement | null>(null);\n  const contentRef = useRef<HTMLDivElement | null>(null);\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const controlled = controlledOpen !== undefined;\n  const open = controlled ? controlledOpen : internalOpen;\n\n  const setOpen = useCallback(\n    (next: boolean) => {\n      if (!controlled) setInternalOpen(next);\n      onOpenChange?.(next);\n    },\n    [controlled, onOpenChange],\n  );\n  const toggle = useCallback(() => setOpen(!open), [setOpen, open]);\n\n  // A trigger normally registers itself through MorphPopoverTrigger. It can't\n  // when something else already clones the element — a Tooltip wrapping the\n  // button, say — and an unregistered trigger leaves the panel with nothing to\n  // measure against, so it renders permanently invisible. The root boxes the\n  // trigger exactly (the content portals out of it), so it stands in until a\n  // real trigger registers, and stands in again if that one unmounts. Both are\n  // state, so a trigger arriving while the panel is open re-anchors it.\n  const anchorRef = useMemo<React.MutableRefObject<HTMLElement | null>>(\n    () => ({ current: trigger ?? root }),\n    [root, trigger],\n  );\n\n  // The panel is a `role=\"dialog\"` and goes inert the moment it closes, so\n  // focus cannot be left sitting inside it: a dismissal hands it back to the\n  // trigger, the way the ARIA dialog pattern asks. A pointer dismissal takes\n  // the focus onward itself when it lands on something focusable — this only\n  // catches the case where it would otherwise be stranded. When no trigger has\n  // registered, the root anchor stands in only if it can actually hold focus;\n  // there is nowhere better than where the keyboard already is, so leave it.\n  const close = useCallback(() => {\n    setOpen(false);\n    const focused = document.activeElement;\n    const inPanel =\n      focused instanceof HTMLElement && contentRef.current?.contains(focused);\n    if (!inPanel) return;\n    const restore = trigger ?? (root && root.tabIndex >= 0 ? root : null);\n    restore?.focus();\n  }, [root, setOpen, trigger]);\n\n  useEffect(() => {\n    if (!open) return;\n    const onKey = (e: KeyboardEvent) => e.key === \"Escape\" && close();\n    const onPointer = (e: PointerEvent) => {\n      const target = e.target as Node;\n      if (\n        root &&\n        !root.contains(target) &&\n        !contentRef.current?.contains(target)\n      )\n        close();\n    };\n    window.addEventListener(\"keydown\", onKey);\n    window.addEventListener(\"pointerdown\", onPointer);\n    return () => {\n      window.removeEventListener(\"keydown\", onKey);\n      window.removeEventListener(\"pointerdown\", onPointer);\n    };\n  }, [open, root, close]);\n\n  const ctx = useMemo<MorphContextValue>(\n    () => ({\n      open,\n      setOpen,\n      toggle,\n      triggerId: `${baseId}-trigger`,\n      contentId: `${baseId}-content`,\n      triggerRef: anchorRef,\n      registerTrigger: setTrigger,\n      contentRef,\n    }),\n    [open, setOpen, toggle, baseId, anchorRef],\n  );\n\n  return (\n    <MorphContext.Provider value={ctx}>\n      <div ref={setRoot} className={cn(\"relative inline-flex\", className)}>\n        {children}\n      </div>\n    </MorphContext.Provider>\n  );\n}\n\nexport interface MorphPopoverTriggerProps {\n  children: ReactElement;\n}\n\nfunction mergeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n  return (node: T | null) => {\n    for (const ref of refs) {\n      if (typeof ref === \"function\") ref(node);\n      else if (ref && typeof ref === \"object\")\n        (ref as React.MutableRefObject<T | null>).current = node;\n    }\n  };\n}\n\n/** Wraps a single element, toggling the popover on click. */\nexport function MorphPopoverTrigger({ children }: MorphPopoverTriggerProps) {\n  const ctx = useMorphContext(\"MorphPopoverTrigger\");\n  if (!isValidElement(children)) return children;\n\n  const child = children as ReactElement<Record<string, unknown>>;\n  const childOnClick = child.props.onClick as\n    | ((e: unknown) => void)\n    | undefined;\n  const childRef = (child.props as { ref?: Ref<HTMLElement> }).ref;\n\n  return cloneElement(child, {\n    id: ctx.triggerId,\n    ref: mergeRefs(childRef, ctx.registerTrigger),\n    onClick: (e: unknown) => {\n      childOnClick?.(e);\n      ctx.toggle();\n    },\n    \"aria-haspopup\": \"dialog\",\n    \"aria-expanded\": ctx.open,\n    \"aria-controls\": ctx.open ? ctx.contentId : undefined,\n  });\n}\n\nconst originFor = (side: Side, align: Align) =>\n  `${side === \"bottom\" ? \"top\" : \"bottom\"} ${align === \"end\" ? \"right\" : \"left\"}`;\n\n// A clip that hides everything but the corner nearest the trigger, so the\n// panel appears to grow out of it. inset(top right bottom left).\nfunction clipHidden(side: Side, align: Align, radius: number) {\n  const top = side === \"bottom\" ? \"0%\" : \"92%\";\n  const bottom = side === \"bottom\" ? \"92%\" : \"0%\";\n  const right = align === \"end\" ? \"0%\" : \"92%\";\n  const left = align === \"end\" ? \"92%\" : \"0%\";\n  return `inset(${top} ${right} ${bottom} ${left} round ${radius}px)`;\n}\nconst clipShown = (radius: number) => `inset(0% 0% 0% 0% round ${radius}px)`;\n\n// Preserve the original spring character on the wrapper, but tween the complex\n// clip-path so it cannot snap when the spring resolves its final distance.\nconst MORPH_CLIP_TRANSITION = { duration: 0.32, ease: EASE_OUT } as const;\n\nexport interface MorphPopoverContentProps {\n  children: ReactNode;\n  side?: Side;\n  align?: Align;\n  /** Gap between trigger and panel, in px. Default 8. */\n  sideOffset?: number;\n  /** Panel corner radius, in px. Default 16. */\n  radius?: number;\n  className?: string;\n}\n\nexport function MorphPopoverContent({\n  children,\n  side = \"bottom\",\n  align = \"end\",\n  sideOffset = 8,\n  radius = 16,\n  className,\n}: MorphPopoverContentProps) {\n  const ctx = useMorphContext(\"MorphPopoverContent\");\n  const reduce = useReducedMotion() ?? false;\n  const [portalReady, setPortalReady] = useState(false);\n  const layout = usePopoverPortalPosition(\n    ctx.triggerRef,\n    ctx.contentRef,\n    portalReady && ctx.open,\n  );\n\n  useEffect(() => setPortalReady(true), []);\n  const left = layout\n    ? align === \"end\"\n      ? layout.trigger.left + layout.trigger.width - layout.content.width\n      : layout.trigger.left\n    : 0;\n  const top = layout\n    ? side === \"bottom\"\n      ? layout.trigger.top + layout.trigger.height + sideOffset\n      : layout.trigger.top - layout.content.height - sideOffset\n    : 0;\n\n  // Both directions travel between the exact same hidden/show states. Exit\n  // targets \"hidden\" directly instead of introducing separate choreography.\n  const wrap = reduce\n    ? undefined\n    : {\n        hidden: { opacity: 0, scale: 0.96, transition: SPRING_PANEL },\n        show: { opacity: 1, scale: 1, transition: SPRING_PANEL },\n      };\n  const clip = reduce\n    ? undefined\n    : {\n        hidden: {\n          clipPath: clipHidden(side, align, radius),\n          transition: MORPH_CLIP_TRANSITION,\n        },\n        show: {\n          clipPath: clipShown(radius),\n          transition: MORPH_CLIP_TRANSITION,\n        },\n      };\n\n  // Keep the server and first client render identical, then mount the portal.\n  if (!portalReady) return null;\n\n  return createPortal(\n    <AnimatePresence>\n      {ctx.open ? (\n        <motion.div\n          data-morph-popover-portal=\"\"\n          // Wrapper carries the shadow as a drop-shadow filter, which hugs the\n          // clipped shape below (box-shadow would just get clipped away).\n          variants={wrap}\n          initial={reduce ? { opacity: 0 } : \"hidden\"}\n          animate={reduce ? { opacity: 1 } : \"show\"}\n          exit={reduce ? { opacity: 0 } : \"hidden\"}\n          transition={reduce ? { duration: 0.12 } : undefined}\n          style={{\n            left,\n            top,\n            visibility: layout ? \"visible\" : \"hidden\",\n            transformOrigin: originFor(side, align),\n          }}\n          className=\"fixed z-[9999] [filter:drop-shadow(0_10px_18px_rgba(0,0,0,0.14))]\"\n        >\n          <motion.div\n            ref={ctx.contentRef}\n            id={ctx.contentId}\n            role=\"dialog\"\n            aria-labelledby={ctx.triggerId}\n            variants={clip}\n            style={{ borderRadius: radius }}\n            className={cn(\n              \"overflow-hidden border border-border bg-background\",\n              className,\n            )}\n          >\n            {children}\n          </motion.div>\n        </motion.div>\n      ) : null}\n    </AnimatePresence>,\n    document.body,\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/popover-position.ts",
          "target": "@components/beui/components/motion/popover-position.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport {\n  type MutableRefObject,\n  useCallback,\n  useLayoutEffect,\n  useState,\n} from \"react\";\n\nexport type PortalLayout = {\n  trigger: {\n    left: number;\n    top: number;\n    width: number;\n    height: number;\n  };\n  content: {\n    width: number;\n    height: number;\n  };\n};\n\nfunction sameLayout(a: PortalLayout | null, b: PortalLayout) {\n  return (\n    a?.trigger.left === b.trigger.left &&\n    a.trigger.top === b.trigger.top &&\n    a.trigger.width === b.trigger.width &&\n    a.trigger.height === b.trigger.height &&\n    a.content.width === b.content.width &&\n    a.content.height === b.content.height\n  );\n}\n\n/** Measures a trigger and portalled panel in viewport coordinates. */\nexport function usePopoverPortalPosition<\n  TriggerElement extends HTMLElement,\n  ContentElement extends HTMLElement,\n>(\n  triggerRef: MutableRefObject<TriggerElement | null>,\n  contentRef: MutableRefObject<ContentElement | null>,\n  active: boolean,\n) {\n  const [layout, setLayout] = useState<PortalLayout | null>(null);\n\n  const update = useCallback(() => {\n    const trigger = triggerRef.current;\n    const content = contentRef.current;\n    if (!trigger || !content) return;\n\n    const rect = trigger.getBoundingClientRect();\n    const next: PortalLayout = {\n      trigger: {\n        left: rect.left,\n        top: rect.top,\n        width: rect.width,\n        height: rect.height,\n      },\n      content: {\n        width: content.offsetWidth,\n        height: content.offsetHeight,\n      },\n    };\n    setLayout((current) => (sameLayout(current, next) ? current : next));\n  }, [contentRef, triggerRef]);\n\n  useLayoutEffect(() => {\n    update();\n    if (!active) return;\n\n    const trigger = triggerRef.current;\n    const content = contentRef.current;\n    const observer = new ResizeObserver(update);\n    if (trigger) observer.observe(trigger);\n    if (content) observer.observe(content);\n\n    window.addEventListener(\"scroll\", update, true);\n    window.addEventListener(\"resize\", update);\n    return () => {\n      observer.disconnect();\n      window.removeEventListener(\"scroll\", update, true);\n      window.removeEventListener(\"resize\", update);\n    };\n  }, [active, contentRef, triggerRef, update]);\n\n  return layout;\n}\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "components/beui/lib/hooks/use-touch-capable.ts",
          "target": "@components/beui/lib/hooks/use-touch-capable.ts",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\n/**\n * Returns true on devices that can be touched, whatever else they claim.\n *\n * This is not the inverse of `useHoverCapable`: iPadOS Safari browses\n * desktop-class and answers `(hover: hover) and (pointer: fine)` with true\n * while a finger is the only input there is, so anything that treats\n * hover-capable as \"no touch here\" strands every iPad. Gate the *touch path*\n * of an interaction on this hook and leave hover-only polish on\n * `useHoverCapable`, so a component that opens on hover also opens on tap.\n */\nexport function useTouchCapable() {\n  const [canTouch, setCanTouch] = useState(false);\n\n  useEffect(() => {\n    if (typeof window === \"undefined\") return;\n    const mq = window.matchMedia?.(\"(any-pointer: coarse)\");\n    // iPadOS disguises its pointer media queries; maxTouchPoints it reports\n    // honestly, which is what makes it the standard iPad tell.\n    const update = () =>\n      setCanTouch(Boolean(mq?.matches) || navigator.maxTouchPoints > 0);\n    update();\n    mq?.addEventListener?.(\"change\", update);\n    return () => mq?.removeEventListener?.(\"change\", update);\n  }, []);\n\n  return canTouch;\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    },
    {
      "$schema": "https://ui.shadcn.com/schema/registry-item.json",
      "name": "beui-chat-app",
      "type": "registry:block",
      "title": "Beui Chat App",
      "description": "Chat App",
      "dependencies": [
        "clsx@^2.1.1",
        "lucide-react@0.577.0",
        "motion@12.26.2",
        "tailwind-merge@^3.0.1",
        "tailwindcss@^4.1.7",
        "tw-animate-css@1.3.6"
      ],
      "registryDependencies": [],
      "files": [
        {
          "path": "components/beui/components/agents/chat-app.tsx",
          "target": "@components/beui/components/agents/chat-app.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useEffect, useRef } from \"react\";\nimport {\n  AnimatedSidebarProvider,\n  type AnimatedSidebarProviderProps,\n  useAnimatedSidebar,\n} from \"@/components/beui/components/motion/animated-sidebar\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\n/**\n * Shell width below which a docked sidebar leaves too little room for the\n * conversation: the default sidebar is 17rem, so under 600px the conversation\n * pane is left with barely 330px — narrower than a phone.\n *\n * Deliberately not AnimatedSidebar's own 767px mobile query: that one asks\n * whether the *viewport* is a phone (and swaps the sidebar for an off-canvas\n * sheet), this one asks whether the *shell's own box* — which may be a column,\n * a split view or a panel inside a much wider page — still fits both panes.\n */\nconst MIN_DOCKED_WIDTH = 600;\n\nexport interface ChatAppProps extends AnimatedSidebarProviderProps {\n  /** Docked sidebar width as a CSS length. Default `17rem`. */\n  sidebarWidth?: string;\n  /**\n   * Shell width in px under which the sidebar folds off-canvas. Ignored while\n   * `open` is controlled — the consumer owns the state then.\n   */\n  collapseSidebarBelow?: number;\n}\n\n/**\n * Folds the sidebar away while the shell is too narrow to carry both panes,\n * and brings it back when it isn't. Only crossings are acted on, so a manual\n * toggle at either size stays put until the shell actually changes shape.\n *\n * Mount is not a crossing in the opening direction: a shell that merely has\n * room says nothing about whether the caller wanted the sidebar open, so the\n * first measurement leaves `defaultOpen` alone. Too narrow at mount *is* the\n * fold condition itself, so that half applies immediately.\n */\nfunction ShellFit({ minWidth }: { minWidth: number }) {\n  const { open, setOpen } = useAnimatedSidebar();\n  const markerRef = useRef<HTMLDivElement>(null);\n  const narrowRef = useRef<boolean | null>(null);\n  const openRef = useRef(open);\n  openRef.current = open;\n\n  useEffect(() => {\n    const shell = markerRef.current?.parentElement;\n    if (!shell) return;\n    const observer = new ResizeObserver(([entry]) => {\n      const narrow = entry.contentRect.width < minWidth;\n      if (narrowRef.current === narrow) return;\n      const first = narrowRef.current === null;\n      narrowRef.current = narrow;\n      if (first && !narrow) return;\n      const wanted = !narrow;\n      // Already where the shell wants it — saying so again would only be an\n      // onOpenChange the caller never asked for.\n      if (openRef.current === wanted) return;\n      setOpen(wanted);\n    });\n    observer.observe(shell);\n    return () => observer.disconnect();\n  }, [minWidth, setOpen]);\n\n  return <div ref={markerRef} className=\"hidden\" />;\n}\n\nexport function ChatApp({\n  children,\n  className,\n  sidebarWidth = \"17rem\",\n  collapseSidebarBelow = MIN_DOCKED_WIDTH,\n  style,\n  ...props\n}: ChatAppProps) {\n  return (\n    <AnimatedSidebarProvider\n      {...props}\n      style={{ ...style, \"--sidebar-width\": sidebarWidth }}\n      className={cn(\n        \"min-h-0 w-full overflow-hidden rounded-xl border border-border bg-background\",\n        className,\n      )}\n    >\n      {/* A controlled `open` is the consumer's to change; fitting the shell\n          would fire an onOpenChange they never asked for. */}\n      {props.open === undefined ? (\n        <ShellFit minWidth={collapseSidebarBelow} />\n      ) : null}\n      {children}\n    </AnimatedSidebarProvider>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/animated-sidebar.tsx",
          "target": "@components/beui/components/motion/animated-sidebar.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { ChevronRight } from \"lucide-react\";\nimport {\n  AnimatePresence,\n  type HTMLMotionProps,\n  motion,\n  useReducedMotion,\n  type Variants,\n} from \"motion/react\";\nimport {\n  type ButtonHTMLAttributes,\n  type CSSProperties,\n  createContext,\n  forwardRef,\n  type HTMLAttributes,\n  type ReactNode,\n  useCallback,\n  useContext,\n  useEffect,\n  useId,\n  useRef,\n  useState,\n  useSyncExternalStore,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { SharedLayoutBg } from \"@/components/beui/components/motion/shared-layout-bg\";\nimport {\n  EASE_DRAWER,\n  EASE_OUT,\n  SPRING_LAYOUT,\n  SPRING_PRESS,\n} from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\ntype SidebarState = \"expanded\" | \"collapsed\";\ntype SidebarSide = \"left\" | \"right\";\ntype SidebarVariant = \"sidebar\" | \"floating\" | \"inset\";\ntype SidebarCollapsible = \"offcanvas\" | \"icon\" | \"none\";\n\nconst MOBILE_QUERY = \"(max-width: 767px)\";\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\";\n\nconst PANEL_TRANSITION = {\n  duration: 0.36,\n  ease: EASE_DRAWER,\n} as const;\n\n// The desktop rail settles at a hard zero-width boundary. Keep the spring\n// critically damped so it cannot overshoot, pause against that boundary, and\n// then snap back during the final frame.\nconst SIDEBAR_MORPH_TRANSITION = {\n  type: \"spring\",\n  stiffness: 380,\n  damping: 35,\n  mass: 0.75,\n} as const;\n\nconst LABEL_ENTER_TRANSITION = {\n  duration: 0.2,\n  delay: 0.08,\n  ease: EASE_OUT,\n} as const;\n\nconst LABEL_EXIT_TRANSITION = {\n  duration: 0.12,\n  ease: EASE_OUT,\n} as const;\n\nconst SUBMENU_TRANSITION = {\n  duration: 0.18,\n  ease: EASE_OUT,\n} as const;\n\nconst SUBMENU_VARIANTS: Variants = {\n  closed: {\n    opacity: 0,\n    clipPath: \"inset(0 0 100% 0 round 8px)\",\n    transition: {\n      duration: 0.14,\n      ease: EASE_OUT,\n      staggerChildren: 0.025,\n      staggerDirection: -1,\n    },\n  },\n  open: {\n    opacity: 1,\n    clipPath: \"inset(0 0 0% 0 round 8px)\",\n    transition: {\n      duration: 0.2,\n      delayChildren: 0.035,\n      ease: EASE_OUT,\n      staggerChildren: 0.045,\n    },\n  },\n};\n\nconst SUBMENU_ITEM_VARIANTS: Variants = {\n  closed: {\n    opacity: 0,\n    y: -6,\n    filter: \"blur(3px)\",\n  },\n  open: {\n    opacity: 1,\n    y: 0,\n    filter: \"blur(0px)\",\n    transition: SUBMENU_TRANSITION,\n  },\n};\n\nconst REDUCED_TRANSITION = {\n  duration: 0.16,\n  ease: EASE_OUT,\n} as const;\n\nconst FOCUSABLE_SELECTOR = [\n  \"a[href]\",\n  \"button:not([disabled])\",\n  \"input:not([disabled])\",\n  \"select:not([disabled])\",\n  \"textarea:not([disabled])\",\n  \"[tabindex]:not([tabindex='-1'])\",\n].join(\",\");\n\nfunction subscribeToMobileQuery(callback: () => void) {\n  const query = window.matchMedia(MOBILE_QUERY);\n  query.addEventListener(\"change\", callback);\n  return () => query.removeEventListener(\"change\", callback);\n}\n\nfunction getMobileSnapshot() {\n  return window.matchMedia(MOBILE_QUERY).matches;\n}\n\nfunction getServerMobileSnapshot() {\n  return false;\n}\n\nfunction useIsMobile() {\n  return useSyncExternalStore(\n    subscribeToMobileQuery,\n    getMobileSnapshot,\n    getServerMobileSnapshot,\n  );\n}\n\ninterface AnimatedSidebarContextValue {\n  isMobile: boolean;\n  layoutId: string;\n  open: boolean;\n  openMobile: boolean;\n  reduce: boolean;\n  setOpen: (open: boolean) => void;\n  setOpenMobile: (open: boolean) => void;\n  state: SidebarState;\n  toggleSidebar: () => void;\n  triggerRef: React.RefObject<HTMLButtonElement | null>;\n}\n\nconst AnimatedSidebarContext =\n  createContext<AnimatedSidebarContextValue | null>(null);\n\ninterface AnimatedSidebarPanelContextValue {\n  collapsed: boolean;\n  collapsible: SidebarCollapsible;\n  side: SidebarSide;\n}\n\nconst AnimatedSidebarPanelContext =\n  createContext<AnimatedSidebarPanelContextValue | null>(null);\n\nexport function useAnimatedSidebar() {\n  const context = useContext(AnimatedSidebarContext);\n  if (!context) {\n    throw new Error(\n      \"useAnimatedSidebar must be used inside AnimatedSidebarProvider.\",\n    );\n  }\n  return context;\n}\n\nfunction useAnimatedSidebarPanel() {\n  const context = useContext(AnimatedSidebarPanelContext);\n  if (!context) {\n    throw new Error(\n      \"Animated Sidebar parts must be used inside AnimatedSidebar.\",\n    );\n  }\n  return context;\n}\n\ntype SidebarProviderStyle = CSSProperties & {\n  \"--sidebar-width\"?: string;\n  \"--sidebar-width-icon\"?: string;\n  \"--sidebar-width-mobile\"?: string;\n};\n\nexport interface AnimatedSidebarProviderProps\n  extends HTMLAttributes<HTMLDivElement> {\n  open?: boolean;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  openMobile?: boolean;\n  defaultOpenMobile?: boolean;\n  onOpenMobileChange?: (open: boolean) => void;\n  style?: SidebarProviderStyle;\n}\n\nexport function AnimatedSidebarProvider({\n  children,\n  open,\n  defaultOpen = true,\n  onOpenChange,\n  openMobile,\n  defaultOpenMobile = false,\n  onOpenMobileChange,\n  className,\n  style,\n  ...props\n}: AnimatedSidebarProviderProps) {\n  const [internalOpen, setInternalOpen] = useState(defaultOpen);\n  const [internalOpenMobile, setInternalOpenMobile] =\n    useState(defaultOpenMobile);\n  const isMobile = useIsMobile();\n  const reduce = useReducedMotion() ?? false;\n  const generatedId = useId();\n  const triggerRef = useRef<HTMLButtonElement>(null);\n  const desktopOpen = open ?? internalOpen;\n  const mobileOpen = openMobile ?? internalOpenMobile;\n\n  const setOpen = useCallback(\n    (nextOpen: boolean) => {\n      if (open === undefined) setInternalOpen(nextOpen);\n      onOpenChange?.(nextOpen);\n    },\n    [onOpenChange, open],\n  );\n\n  const setOpenMobile = useCallback(\n    (nextOpen: boolean) => {\n      if (openMobile === undefined) setInternalOpenMobile(nextOpen);\n      onOpenMobileChange?.(nextOpen);\n    },\n    [onOpenMobileChange, openMobile],\n  );\n\n  const toggleSidebar = useCallback(() => {\n    if (isMobile) setOpenMobile(!mobileOpen);\n    else setOpen(!desktopOpen);\n  }, [desktopOpen, isMobile, mobileOpen, setOpen, setOpenMobile]);\n\n  useEffect(() => {\n    const handleShortcut = (event: KeyboardEvent) => {\n      if (\n        event.key.toLowerCase() === SIDEBAR_KEYBOARD_SHORTCUT &&\n        (event.metaKey || event.ctrlKey)\n      ) {\n        event.preventDefault();\n        toggleSidebar();\n      }\n    };\n\n    window.addEventListener(\"keydown\", handleShortcut);\n    return () => window.removeEventListener(\"keydown\", handleShortcut);\n  }, [toggleSidebar]);\n\n  return (\n    <AnimatedSidebarContext.Provider\n      value={{\n        isMobile,\n        layoutId: `${generatedId}-active`,\n        open: desktopOpen,\n        openMobile: mobileOpen,\n        reduce,\n        setOpen,\n        setOpenMobile,\n        state: desktopOpen ? \"expanded\" : \"collapsed\",\n        toggleSidebar,\n        triggerRef,\n      }}\n    >\n      <div\n        {...props}\n        data-slot=\"sidebar-wrapper\"\n        data-state={desktopOpen ? \"expanded\" : \"collapsed\"}\n        style={{\n          \"--sidebar-width\": \"16rem\",\n          \"--sidebar-width-icon\": \"4.25rem\",\n          \"--sidebar-width-mobile\": \"18rem\",\n          ...style,\n        }}\n        className={cn(\n          \"group/sidebar-wrapper flex min-h-svh w-full min-w-0\",\n          className,\n        )}\n      >\n        {children}\n      </div>\n    </AnimatedSidebarContext.Provider>\n  );\n}\n\nfunction MobileSidebar({\n  ariaLabel,\n  children,\n  className,\n  side,\n}: {\n  ariaLabel: string;\n  children: ReactNode;\n  className?: string;\n  side: SidebarSide;\n}) {\n  const context = useAnimatedSidebar();\n  const panelRef = useRef<HTMLDivElement>(null);\n  const [mounted, setMounted] = useState(false);\n  // The sheet is mounted for as long as the viewport is mobile, so it hides\n  // itself while closed rather than sitting there transparent and interactive.\n  // Opening shows it in the same commit that starts the slide — a delayed show\n  // would run the focus effect below against a still-hidden panel, and focus()\n  // on a hidden element is ignored. Closing waits for the slide to finish, and\n  // the panel's own exit tells us when that is: no duration to keep in sync.\n  const [hidden, setHidden] = useState(!context.openMobile);\n  // The completion callback fires for the open slide too, and it reads state\n  // from whenever motion settles: a ref keeps it on the current one.\n  const openMobileRef = useRef(context.openMobile);\n\n  useEffect(() => setMounted(true), []);\n\n  useEffect(() => {\n    openMobileRef.current = context.openMobile;\n    if (context.openMobile) setHidden(false);\n  }, [context.openMobile]);\n\n  useEffect(() => {\n    if (!context.openMobile) return;\n\n    const body = document.body;\n    const scrollY = window.scrollY;\n    const previousBodyStyles = {\n      left: body.style.left,\n      overflow: body.style.overflow,\n      position: body.style.position,\n      right: body.style.right,\n      top: body.style.top,\n    };\n\n    body.style.position = \"fixed\";\n    body.style.top = `-${scrollY}px`;\n    body.style.left = \"0\";\n    body.style.right = \"0\";\n    body.style.overflow = \"hidden\";\n\n    const focusFrame = requestAnimationFrame(() => {\n      const firstFocusable =\n        panelRef.current?.querySelector<HTMLElement>(FOCUSABLE_SELECTOR);\n      (firstFocusable ?? panelRef.current)?.focus({ preventScroll: true });\n    });\n\n    return () => {\n      cancelAnimationFrame(focusFrame);\n      body.style.position = previousBodyStyles.position;\n      body.style.top = previousBodyStyles.top;\n      body.style.left = previousBodyStyles.left;\n      body.style.right = previousBodyStyles.right;\n      body.style.overflow = previousBodyStyles.overflow;\n      window.scrollTo(0, scrollY);\n      context.triggerRef.current?.focus({ preventScroll: true });\n    };\n  }, [context.openMobile, context.triggerRef]);\n\n  if (!mounted) return null;\n\n  // This container groups the sheet for hiding and the z-index and carries no\n  // box: both children are `fixed` and resolve against the viewport themselves.\n  // The scrim spans the viewport edges but paints a colour, and the panel is\n  // inset off one side and paints its own surface, so no layer here is a\n  // transparent edge-spanning one. See tests/fixed-overlay-edge-sampling.test.tsx.\n  return createPortal(\n    <div\n      className={cn(\n        \"pointer-events-none fixed left-0 top-0 z-50 size-0 md:hidden\",\n        hidden && !context.openMobile ? \"invisible\" : \"visible\",\n      )}\n    >\n      <motion.button\n        type=\"button\"\n        aria-label=\"Close sidebar\"\n        tabIndex={context.openMobile ? 0 : -1}\n        initial={false}\n        animate={{ opacity: context.openMobile ? 1 : 0 }}\n        transition={\n          context.reduce ? REDUCED_TRANSITION : PANEL_TRANSITION\n        }\n        onClick={() => context.setOpenMobile(false)}\n        className={cn(\n          \"fixed inset-0 bg-black/40\",\n          context.openMobile\n            ? \"pointer-events-auto\"\n            : \"pointer-events-none\",\n        )}\n      />\n\n      <motion.div\n        ref={panelRef}\n        role=\"dialog\"\n        aria-modal=\"true\"\n        aria-label={ariaLabel}\n        aria-hidden={!context.openMobile}\n        inert={!context.openMobile}\n        tabIndex={-1}\n        data-mobile=\"true\"\n        data-state={context.openMobile ? \"expanded\" : \"collapsed\"}\n        data-side={side}\n        initial={false}\n        animate={{\n          opacity: context.reduce\n            ? context.openMobile\n              ? 1\n              : 0\n            : 1,\n          x: context.reduce\n            ? 0\n            : context.openMobile\n              ? \"0%\"\n              : side === \"left\"\n                ? \"-100%\"\n                : \"100%\",\n        }}\n        transition={\n          context.reduce ? REDUCED_TRANSITION : PANEL_TRANSITION\n        }\n        onAnimationComplete={() => {\n          if (!openMobileRef.current) setHidden(true);\n        }}\n        onKeyDown={(event) => {\n          if (event.key === \"Escape\") {\n            event.preventDefault();\n            context.setOpenMobile(false);\n            return;\n          }\n\n          if (event.key !== \"Tab\") return;\n          const focusable = panelRef.current\n            ? Array.from(\n                panelRef.current.querySelectorAll<HTMLElement>(\n                  FOCUSABLE_SELECTOR,\n                ),\n              )\n            : [];\n\n          if (focusable.length === 0) {\n            event.preventDefault();\n            panelRef.current?.focus();\n            return;\n          }\n\n          const first = focusable[0];\n          const last = focusable[focusable.length - 1];\n          if (event.shiftKey && document.activeElement === first) {\n            event.preventDefault();\n            last.focus();\n          } else if (!event.shiftKey && document.activeElement === last) {\n            event.preventDefault();\n            first.focus();\n          }\n        }}\n        className={cn(\n          \"pointer-events-auto fixed inset-y-0 flex h-dvh w-(--sidebar-width-mobile) max-w-[88vw] flex-col overflow-hidden\",\n          \"border-border bg-background shadow-2xl will-change-transform\",\n          side === \"left\" ? \"left-0 border-r\" : \"right-0 border-l\",\n          !context.openMobile && \"pointer-events-none\",\n          className,\n        )}\n      >\n        <AnimatedSidebarPanelContext.Provider\n          value={{ collapsed: false, collapsible: \"none\", side }}\n        >\n          {children}\n        </AnimatedSidebarPanelContext.Provider>\n      </motion.div>\n    </div>,\n    document.body,\n  );\n}\n\nexport interface AnimatedSidebarProps\n  extends Omit<HTMLMotionProps<\"aside\">, \"children\"> {\n  children?: ReactNode;\n  side?: SidebarSide;\n  variant?: SidebarVariant;\n  collapsible?: SidebarCollapsible;\n  ariaLabel?: string;\n  panelClassName?: string;\n}\n\nexport const AnimatedSidebar = forwardRef<HTMLElement, AnimatedSidebarProps>(\n  function AnimatedSidebar(\n    {\n      side = \"left\",\n      variant = \"sidebar\",\n      collapsible = \"icon\",\n      ariaLabel = \"Sidebar\",\n      children,\n      className,\n      panelClassName,\n      style,\n      ...props\n    },\n    forwardedRef,\n  ) {\n    const context = useAnimatedSidebar();\n    const collapsed = collapsible !== \"none\" && !context.open;\n    const offcanvas = collapsed && collapsible === \"offcanvas\";\n    const width = offcanvas\n      ? \"0px\"\n      : collapsed\n        ? \"var(--sidebar-width-icon)\"\n        : \"var(--sidebar-width)\";\n\n    if (context.isMobile) {\n      return (\n        <MobileSidebar\n          ariaLabel={ariaLabel}\n          className={className}\n          side={side}\n        >\n          {children}\n        </MobileSidebar>\n      );\n    }\n\n    return (\n      <motion.aside\n        {...props}\n        ref={forwardedRef}\n        initial={false}\n        aria-label={ariaLabel}\n        data-slot=\"sidebar\"\n        data-state={collapsed ? \"collapsed\" : \"expanded\"}\n        data-collapsible={collapsible}\n        data-variant={variant}\n        data-side={side}\n        animate={{ width }}\n        transition={\n          context.reduce ? { duration: 0 } : SIDEBAR_MORPH_TRANSITION\n        }\n        style={style}\n        className={cn(\n          \"group/sidebar relative hidden h-auto shrink-0 md:block will-change-[width]\",\n          \"peer\",\n          side === \"right\" && \"order-last\",\n          className,\n        )}\n      >\n        <motion.div\n          initial={false}\n          animate={{\n            opacity: offcanvas ? 0 : 1,\n            x: offcanvas ? (side === \"left\" ? \"-100%\" : \"100%\") : \"0%\",\n          }}\n          transition={\n            context.reduce ? REDUCED_TRANSITION : PANEL_TRANSITION\n          }\n          className={cn(\n            \"sticky top-0 flex h-svh w-full flex-col overflow-hidden bg-background\",\n            collapsible === \"offcanvas\" && \"w-[var(--sidebar-width)]\",\n            variant === \"sidebar\" &&\n              (side === \"left\" ? \"border-border border-r\" : \"border-border border-l\"),\n            variant === \"floating\" &&\n              \"m-2 h-[calc(100svh-1rem)] rounded-2xl border border-border shadow-sm\",\n            variant === \"inset\" && \"m-2 h-[calc(100svh-1rem)] rounded-2xl\",\n            panelClassName,\n          )}\n        >\n          <AnimatedSidebarPanelContext.Provider\n            value={{ collapsed, collapsible, side }}\n          >\n            {children}\n          </AnimatedSidebarPanelContext.Provider>\n        </motion.div>\n      </motion.aside>\n    );\n  },\n);\n\nexport type AnimatedSidebarTriggerProps = ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport const AnimatedSidebarTrigger = forwardRef<\n  HTMLButtonElement,\n  AnimatedSidebarTriggerProps\n>(function AnimatedSidebarTrigger(\n  { className, onClick, type = \"button\", ...props },\n  forwardedRef,\n) {\n  const context = useAnimatedSidebar();\n  const expanded = context.isMobile ? context.openMobile : context.open;\n\n  return (\n    <button\n      {...props}\n      ref={(node) => {\n        context.triggerRef.current = node;\n        if (typeof forwardedRef === \"function\") forwardedRef(node);\n        else if (forwardedRef) forwardedRef.current = node;\n      }}\n      type={type}\n      aria-label={props[\"aria-label\"] ?? \"Toggle sidebar\"}\n      aria-expanded={expanded}\n      data-slot=\"sidebar-trigger\"\n      data-state={expanded ? \"expanded\" : \"collapsed\"}\n      onClick={(event) => {\n        onClick?.(event);\n        if (!event.defaultPrevented) context.toggleSidebar();\n      }}\n      className={cn(\n        \"inline-flex size-10 shrink-0 items-center justify-center rounded-xl outline-none\",\n        \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n        className,\n      )}\n    />\n  );\n});\n\nexport type AnimatedSidebarCloseProps = ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport const AnimatedSidebarClose = forwardRef<\n  HTMLButtonElement,\n  AnimatedSidebarCloseProps\n>(function AnimatedSidebarClose(\n  { className, onClick, type = \"button\", ...props },\n  forwardedRef,\n) {\n  const context = useAnimatedSidebar();\n\n  return (\n    <button\n      {...props}\n      ref={forwardedRef}\n      type={type}\n      aria-label={props[\"aria-label\"] ?? \"Close sidebar\"}\n      onClick={(event) => {\n        onClick?.(event);\n        if (event.defaultPrevented) return;\n        if (context.isMobile) context.setOpenMobile(false);\n        else context.setOpen(false);\n      }}\n      className={cn(\n        \"inline-flex size-10 shrink-0 items-center justify-center rounded-xl outline-none\",\n        \"focus-visible:ring-2 focus-visible:ring-ring\",\n        className,\n      )}\n    />\n  );\n});\n\nexport type AnimatedSidebarRailProps = ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport const AnimatedSidebarRail = forwardRef<\n  HTMLButtonElement,\n  AnimatedSidebarRailProps\n>(function AnimatedSidebarRail(\n  { className, onClick, type = \"button\", ...props },\n  forwardedRef,\n) {\n  const context = useAnimatedSidebar();\n  const panel = useAnimatedSidebarPanel();\n\n  return (\n    <button\n      {...props}\n      ref={forwardedRef}\n      type={type}\n      data-side={panel.side}\n      aria-label={props[\"aria-label\"] ?? \"Toggle sidebar\"}\n      title=\"Toggle sidebar\"\n      tabIndex={-1}\n      onClick={(event) => {\n        onClick?.(event);\n        if (!event.defaultPrevented) context.toggleSidebar();\n      }}\n      className={cn(\n        \"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 outline-none md:block\",\n        \"after:absolute after:inset-y-0 after:left-1/2 after:w-px after:bg-transparent after:transition-colors hover:after:bg-border\",\n        \"data-[side=right]:right-0 data-[side=right]:translate-x-1/2 data-[side=left]:left-full\",\n        className,\n      )}\n    />\n  );\n});\n\nexport type AnimatedSidebarInsetProps = HTMLMotionProps<\"main\">;\n\nexport const AnimatedSidebarInset = forwardRef<\n  HTMLElement,\n  AnimatedSidebarInsetProps\n>(function AnimatedSidebarInset({ className, ...props }, forwardedRef) {\n  return (\n    <motion.main\n      {...props}\n      ref={forwardedRef}\n      data-slot=\"sidebar-inset\"\n      className={cn(\n        \"relative flex min-h-svh min-w-0 flex-1 flex-col bg-background\",\n        \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-2xl md:peer-data-[variant=inset]:shadow-sm\",\n        className,\n      )}\n    />\n  );\n});\n\nexport const AnimatedSidebarHeader = forwardRef<\n  HTMLDivElement,\n  HTMLAttributes<HTMLDivElement>\n>(function AnimatedSidebarHeader({ className, ...props }, forwardedRef) {\n  return (\n    <div\n      {...props}\n      ref={forwardedRef}\n      data-slot=\"sidebar-header\"\n      className={cn(\"flex shrink-0 flex-col gap-2 p-3\", className)}\n    />\n  );\n});\n\nexport const AnimatedSidebarContent = forwardRef<\n  HTMLDivElement,\n  HTMLAttributes<HTMLDivElement>\n>(function AnimatedSidebarContent({ className, ...props }, forwardedRef) {\n  return (\n    <div\n      {...props}\n      ref={forwardedRef}\n      data-slot=\"sidebar-content\"\n      className={cn(\n        \"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto overflow-x-hidden overscroll-contain px-2 py-2\",\n        className,\n      )}\n    />\n  );\n});\n\nexport const AnimatedSidebarFooter = forwardRef<\n  HTMLDivElement,\n  HTMLAttributes<HTMLDivElement>\n>(function AnimatedSidebarFooter({ className, ...props }, forwardedRef) {\n  return (\n    <div\n      {...props}\n      ref={forwardedRef}\n      data-slot=\"sidebar-footer\"\n      className={cn(\n        \"flex shrink-0 flex-col gap-2 border-border border-t p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]\",\n        className,\n      )}\n    />\n  );\n});\n\nexport const AnimatedSidebarGroup = forwardRef<\n  HTMLDivElement,\n  HTMLAttributes<HTMLDivElement>\n>(function AnimatedSidebarGroup({ className, ...props }, forwardedRef) {\n  return (\n    <div\n      {...props}\n      ref={forwardedRef}\n      data-slot=\"sidebar-group\"\n      className={cn(\"flex w-full min-w-0 flex-col px-1 py-1.5\", className)}\n    />\n  );\n});\n\nexport const AnimatedSidebarGroupLabel = forwardRef<\n  HTMLDivElement,\n  HTMLAttributes<HTMLDivElement>\n>(function AnimatedSidebarGroupLabel(\n  { children, className, ...props },\n  forwardedRef,\n) {\n  const { collapsed } = useAnimatedSidebarPanel();\n\n  return (\n    <div\n      {...props}\n      ref={forwardedRef}\n      aria-hidden={collapsed}\n      data-slot=\"sidebar-group-label\"\n      className={cn(\n        \"mb-1 h-7 overflow-hidden px-2 text-[10px] font-medium uppercase tracking-[0.14em] text-muted-foreground transition-opacity\",\n        collapsed ? \"opacity-0\" : \"opacity-100\",\n        className,\n      )}\n    >\n      {children}\n    </div>\n  );\n});\n\nexport const AnimatedSidebarGroupContent = forwardRef<\n  HTMLDivElement,\n  HTMLAttributes<HTMLDivElement>\n>(function AnimatedSidebarGroupContent(\n  { className, ...props },\n  forwardedRef,\n) {\n  return (\n    <div\n      {...props}\n      ref={forwardedRef}\n      data-slot=\"sidebar-group-content\"\n      className={cn(\"w-full min-w-0\", className)}\n    />\n  );\n});\n\nexport const AnimatedSidebarMenu = forwardRef<\n  HTMLUListElement,\n  HTMLAttributes<HTMLUListElement>\n>(function AnimatedSidebarMenu(\n  { children, className, ...props },\n  forwardedRef,\n) {\n  return (\n    <SharedLayoutBg\n      {...props}\n      ref={forwardedRef as React.Ref<HTMLElement>}\n      as=\"ul\"\n      inset={0}\n      pillClassName=\"rounded-xl bg-muted/70\"\n      pillContainerClassName=\"inset-y-auto top-0 h-9\"\n      data-slot=\"sidebar-menu\"\n      className={cn(\"flex w-full min-w-0 list-none flex-col gap-0.5\", className)}\n    >\n      {children}\n    </SharedLayoutBg>\n  );\n});\n\nexport const AnimatedSidebarMenuItem = forwardRef<\n  HTMLLIElement,\n  HTMLMotionProps<\"li\">\n>(function AnimatedSidebarMenuItem({ className, ...props }, forwardedRef) {\n  return (\n    <motion.li\n      {...props}\n      ref={forwardedRef}\n      layout=\"position\"\n      transition={SPRING_LAYOUT}\n      data-slot=\"sidebar-menu-item\"\n      className={cn(\"relative\", className)}\n    />\n  );\n});\n\nexport interface AnimatedSidebarMenuSubProps\n  extends Omit<HTMLMotionProps<\"ul\">, \"children\"> {\n  open: boolean;\n  children?: ReactNode;\n}\n\nexport const AnimatedSidebarMenuSub = forwardRef<\n  HTMLUListElement,\n  AnimatedSidebarMenuSubProps\n>(function AnimatedSidebarMenuSub(\n  { open, children, className, ...props },\n  forwardedRef,\n) {\n  const context = useAnimatedSidebar();\n  const panel = useAnimatedSidebarPanel();\n\n  return (\n    <AnimatePresence initial={false} mode=\"popLayout\">\n      {open && !panel.collapsed ? (\n        <motion.ul\n          {...props}\n          ref={forwardedRef}\n          key=\"sidebar-submenu\"\n          variants={context.reduce ? undefined : SUBMENU_VARIANTS}\n          initial={context.reduce ? false : \"closed\"}\n          animate={context.reduce ? { opacity: 1 } : \"open\"}\n          exit={context.reduce ? { opacity: 0 } : \"closed\"}\n          transition={context.reduce ? { duration: 0.12 } : undefined}\n          data-slot=\"sidebar-menu-sub\"\n          className={cn(\n            \"relative mt-1 ml-5 flex min-w-0 flex-col gap-0.5 border-border border-l pl-3\",\n            className,\n          )}\n        >\n          {children}\n        </motion.ul>\n      ) : null}\n    </AnimatePresence>\n  );\n});\n\nexport const AnimatedSidebarMenuSubItem = forwardRef<\n  HTMLLIElement,\n  HTMLMotionProps<\"li\">\n>(function AnimatedSidebarMenuSubItem(\n  { className, ...props },\n  forwardedRef,\n) {\n  return (\n    <motion.li\n      {...props}\n      ref={forwardedRef}\n      variants={SUBMENU_ITEM_VARIANTS}\n      data-slot=\"sidebar-menu-sub-item\"\n      className={cn(\"relative min-w-0\", className)}\n    />\n  );\n});\n\nexport interface AnimatedSidebarMenuSubButtonProps {\n  children: ReactNode;\n  icon?: ReactNode;\n  href?: string;\n  isActive?: boolean;\n  disabled?: boolean;\n  closeOnSelect?: boolean;\n  target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\";\n  rel?: string;\n  onSelect?: () => void;\n  className?: string;\n}\n\nexport function AnimatedSidebarMenuSubButton({\n  children,\n  icon,\n  href,\n  isActive = false,\n  disabled = false,\n  closeOnSelect = true,\n  target,\n  rel,\n  onSelect,\n  className,\n}: AnimatedSidebarMenuSubButtonProps) {\n  const context = useAnimatedSidebar();\n\n  const select = (\n    event: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>,\n  ) => {\n    if (disabled) {\n      event.preventDefault();\n      return;\n    }\n    onSelect?.();\n    if (context.isMobile && closeOnSelect) context.setOpenMobile(false);\n  };\n\n  const content = (\n    <>\n      <span\n        aria-hidden=\"true\"\n        className=\"grid size-4 shrink-0 place-items-center\"\n      >\n        {icon ?? <span className=\"size-1 rounded-full bg-current\" />}\n      </span>\n      <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n    </>\n  );\n\n  const interactiveClassName = cn(\n    \"flex min-h-8 w-full min-w-0 items-center gap-2 rounded-lg px-2 text-left text-xs outline-none\",\n    \"text-muted-foreground transition-colors hover:bg-muted/60 hover:text-foreground\",\n    \"focus-visible:bg-muted/70 focus-visible:ring-2 focus-visible:ring-ring\",\n    isActive && \"bg-muted/70 text-foreground\",\n    disabled && \"cursor-not-allowed opacity-40\",\n    className,\n  );\n\n  return href ? (\n    <motion.a\n      href={href}\n      target={target}\n      rel={\n        rel ??\n        (target === \"_blank\" ? \"noreferrer noopener\" : undefined)\n      }\n      aria-current={isActive ? \"page\" : undefined}\n      aria-disabled={disabled || undefined}\n      tabIndex={disabled ? -1 : undefined}\n      onClick={select}\n      whileTap={context.reduce || disabled ? undefined : { scale: 0.98 }}\n      transition={SPRING_PRESS}\n      className={interactiveClassName}\n    >\n      {content}\n    </motion.a>\n  ) : (\n    <motion.button\n      type=\"button\"\n      disabled={disabled}\n      aria-current={isActive ? \"page\" : undefined}\n      onClick={select}\n      whileTap={context.reduce || disabled ? undefined : { scale: 0.98 }}\n      transition={SPRING_PRESS}\n      className={interactiveClassName}\n    >\n      {content}\n    </motion.button>\n  );\n}\n\nexport interface AnimatedSidebarMenuButtonProps {\n  children: ReactNode;\n  icon?: ReactNode;\n  badge?: ReactNode;\n  href?: string;\n  isActive?: boolean;\n  ariaExpanded?: boolean;\n  disabled?: boolean;\n  closeOnSelect?: boolean;\n  target?: \"_blank\" | \"_self\" | \"_parent\" | \"_top\";\n  rel?: string;\n  onSelect?: () => void;\n  className?: string;\n}\n\nexport function AnimatedSidebarMenuButton({\n  children,\n  icon,\n  badge,\n  href,\n  isActive = false,\n  ariaExpanded,\n  disabled = false,\n  closeOnSelect,\n  target,\n  rel,\n  onSelect,\n  className,\n}: AnimatedSidebarMenuButtonProps) {\n  const context = useAnimatedSidebar();\n  const panel = useAnimatedSidebarPanel();\n  const textLabel = typeof children === \"string\" ? children : undefined;\n\n  const select = (\n    event: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement>,\n  ) => {\n    if (disabled) {\n      event.preventDefault();\n      return;\n    }\n    onSelect?.();\n    const shouldCloseOnSelect =\n      closeOnSelect ?? ariaExpanded === undefined;\n    if (context.isMobile && shouldCloseOnSelect) {\n      context.setOpenMobile(false);\n    }\n    // A submenu cannot render in the icon rail, so opening one from there\n    // leaves its children unreachable — a pointer can still fall back to the\n    // rail or the shortcut, a finger has nothing. Selecting a group unfolds\n    // the panel that is about to hold it.\n    if (ariaExpanded !== undefined && panel.collapsed && !context.isMobile) {\n      context.setOpen(true);\n    }\n  };\n\n  const content = (\n    <>\n      {isActive ? (\n        <motion.span\n          layoutId={context.layoutId}\n          transition={context.reduce ? { duration: 0 } : SPRING_LAYOUT}\n          className=\"absolute inset-0 rounded-xl bg-muted\"\n        />\n      ) : null}\n      {icon ? (\n        <span\n          aria-hidden=\"true\"\n          className=\"relative z-10 grid size-5 shrink-0 place-items-center\"\n        >\n          {icon}\n        </span>\n      ) : null}\n      <motion.span\n        initial={false}\n        animate={{\n          opacity: panel.collapsed ? 0 : 1,\n          x: panel.collapsed ? -4 : 0,\n        }}\n        transition={\n          context.reduce\n            ? REDUCED_TRANSITION\n            : panel.collapsed\n              ? LABEL_EXIT_TRANSITION\n              : LABEL_ENTER_TRANSITION\n        }\n        aria-hidden={panel.collapsed}\n        className={cn(\n          \"relative z-10 min-w-0 flex-1 truncate\",\n          panel.collapsed && \"pointer-events-none\",\n        )}\n      >\n        {children}\n      </motion.span>\n      {badge && !panel.collapsed ? (\n        <span className=\"relative z-10 shrink-0 text-xs text-muted-foreground\">\n          {badge}\n        </span>\n      ) : null}\n      {ariaExpanded !== undefined ? (\n        <motion.span\n          aria-hidden=\"true\"\n          initial={false}\n          animate={{\n            opacity: panel.collapsed ? 0 : 1,\n            rotate: ariaExpanded ? 90 : 0,\n            x: panel.collapsed ? 4 : 0,\n          }}\n          transition={context.reduce ? { duration: 0 } : SPRING_LAYOUT}\n          className=\"relative z-10 grid size-4 shrink-0 place-items-center text-muted-foreground\"\n        >\n          <ChevronRight className=\"size-3.5\" />\n        </motion.span>\n      ) : null}\n    </>\n  );\n\n  const interactiveClassName = cn(\n    \"relative flex min-h-9 w-full min-w-0 items-center gap-2.5 overflow-hidden rounded-xl px-3 text-left text-sm font-medium outline-none\",\n    \"text-muted-foreground transition-colors hover:text-foreground\",\n    \"focus-visible:bg-muted/70 focus-visible:ring-2 focus-visible:ring-ring\",\n    isActive && \"text-foreground\",\n    disabled && \"cursor-not-allowed opacity-40\",\n    className,\n  );\n\n  return href ? (\n    <motion.a\n      href={href}\n      target={target}\n      rel={\n        rel ??\n        (target === \"_blank\" ? \"noreferrer noopener\" : undefined)\n      }\n      aria-current={isActive ? \"page\" : undefined}\n      aria-expanded={ariaExpanded}\n      aria-disabled={disabled || undefined}\n      aria-label={panel.collapsed ? textLabel : undefined}\n      title={panel.collapsed ? textLabel : undefined}\n      tabIndex={disabled ? -1 : undefined}\n      onClick={select}\n      whileTap={context.reduce || disabled ? undefined : { scale: 0.98 }}\n      transition={SPRING_PRESS}\n      className={interactiveClassName}\n    >\n      {content}\n    </motion.a>\n  ) : (\n    <motion.button\n      type=\"button\"\n      disabled={disabled}\n      aria-current={isActive ? \"page\" : undefined}\n      aria-expanded={ariaExpanded}\n      aria-label={panel.collapsed ? textLabel : undefined}\n      title={panel.collapsed ? textLabel : undefined}\n      onClick={select}\n      whileTap={context.reduce || disabled ? undefined : { scale: 0.98 }}\n      transition={SPRING_PRESS}\n      className={interactiveClassName}\n    >\n      {content}\n    </motion.button>\n  );\n}\n"
        },
        {
          "path": "components/beui/components/motion/shared-layout-bg.tsx",
          "target": "@components/beui/components/motion/shared-layout-bg.tsx",
          "type": "registry:component",
          "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  AnimatePresence,\n  type HTMLMotionProps,\n  motion,\n  useReducedMotion,\n  type Variants,\n} from \"motion/react\";\nimport {\n  Children,\n  cloneElement,\n  forwardRef,\n  type HTMLAttributes,\n  isValidElement,\n  type MouseEvent,\n  type ReactElement,\n  type ReactNode,\n  type Ref,\n  useId,\n  useState,\n} from \"react\";\nimport { SPRING_LAYOUT } from \"@/components/beui/lib/ease\";\nimport { cn } from \"@/components/beui/lib/utils\";\n\nexport interface SharedLayoutBgProps\n  extends Omit<HTMLAttributes<HTMLElement>, \"children\"> {\n  children: ReactNode;\n  /** Semantic container used for the children. */\n  as?: \"div\" | \"ul\";\n  /** Tailwind class applied to the moving pill. Defaults to a subtle foreground tint. */\n  pillClassName?: string;\n  /** Horizontal inset of the pill relative to each row (px). Default 20. */\n  inset?: number;\n  /** Optional positioning override for the pill wrapper inside each item. */\n  pillContainerClassName?: string;\n}\n\nconst variants: Variants = {\n  initial: { opacity: 0, filter: \"blur(6px)\" },\n  animate: { opacity: 1, filter: \"blur(0px)\" },\n  exit: (isActive: boolean) =>\n    !isActive ? { opacity: 0, filter: \"blur(6px)\" } : {},\n};\n\nconst reducedVariants: Variants = {\n  initial: { opacity: 0 },\n  animate: { opacity: 1 },\n  exit: (isActive: boolean) => (!isActive ? { opacity: 0 } : {}),\n};\n\nexport const SharedLayoutBg = forwardRef<HTMLElement, SharedLayoutBgProps>(\n  function SharedLayoutBg(\n    {\n      children,\n      as = \"div\",\n      className,\n      onMouseLeave,\n      pillClassName,\n      pillContainerClassName,\n      inset = 20,\n      ...props\n    },\n    forwardedRef,\n  ) {\n  const [activeId, setActiveId] = useState<string | null>(null);\n  const uid = useId();\n  const reduce = useReducedMotion();\n\n    const renderedChildren = Children.toArray(children)\n      .filter(isValidElement)\n      .map((child, index) => {\n        const el = child as ReactElement<{\n          className?: string;\n          onMouseEnter?: () => void;\n          children?: ReactNode;\n        }>;\n        const childKey = el.key ? String(el.key) : `item-${index}`;\n        return cloneElement(\n          el,\n          {\n            key: childKey,\n            className: cn(\"relative\", el.props.className),\n            onMouseEnter: () => {\n              el.props.onMouseEnter?.();\n              setActiveId(childKey);\n            },\n          },\n          <>\n            <AnimatePresence custom={activeId !== null}>\n              {activeId !== null ? (\n                <motion.div\n                  variants={reduce ? reducedVariants : variants}\n                  initial=\"initial\"\n                  animate=\"animate\"\n                  exit=\"exit\"\n                  custom={activeId !== null}\n                  className={cn(\n                    \"pointer-events-none absolute inset-y-0\",\n                    pillContainerClassName,\n                  )}\n                  style={{ left: -inset, right: -inset }}\n                >\n                  {activeId === childKey ? (\n                    <motion.div\n                      layoutId={`shared-bg-${uid}`}\n                      transition={reduce ? { duration: 0 } : SPRING_LAYOUT}\n                      className={cn(\n                        \"pointer-events-none h-full w-full rounded-2xl bg-primary/[0.06]\",\n                        pillClassName,\n                      )}\n                    />\n                  ) : null}\n                </motion.div>\n              ) : null}\n            </AnimatePresence>\n            <div className=\"relative z-10\">{el.props.children}</div>\n          </>,\n        );\n      });\n\n    const handleMouseLeave = (event: MouseEvent<HTMLElement>) => {\n      setActiveId(null);\n      onMouseLeave?.(event);\n    };\n\n    // layoutRoot scopes the pill's layout projection to this list, so fixed or\n    // scrolled ancestors can't smear scroll offsets into its movement.\n    return as === \"ul\" ? (\n      <motion.ul\n        {...(props as HTMLMotionProps<\"ul\">)}\n        ref={forwardedRef as Ref<HTMLUListElement>}\n        layoutRoot\n        onMouseLeave={handleMouseLeave}\n        className={cn(\"flex w-full flex-col\", className)}\n      >\n        {renderedChildren}\n      </motion.ul>\n    ) : (\n      <motion.div\n        {...(props as HTMLMotionProps<\"div\">)}\n        ref={forwardedRef as Ref<HTMLDivElement>}\n        layoutRoot\n        onMouseLeave={handleMouseLeave}\n        className={cn(\"flex w-full flex-col\", className)}\n      >\n        {renderedChildren}\n      </motion.div>\n    );\n  },\n);\n"
        },
        {
          "path": "components/beui/lib/ease.ts",
          "target": "@components/beui/lib/ease.ts",
          "type": "registry:component",
          "content": "// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"
        },
        {
          "path": "components/beui/lib/utils.ts",
          "target": "@components/beui/lib/utils.ts",
          "type": "registry:component",
          "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"
        },
        {
          "path": "styles/agents.css",
          "target": "~/styles/agents.css",
          "type": "registry:file",
          "content": "@theme inline {\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-jetbrains-mono), ui-monospace, \"SF Mono\", monospace;\n  --radius-chip: 6px;\n  --radius-control: 8px;\n  --radius-card: 10px;\n  --radius-window: 14px;\n}\n\nhtml:root {\n  --color-background-full: oklch(0.985 0.001 286.376);\n  --color-background-primary-default: oklch(1 0 0);\n  --color-background-secondary-default: oklch(0.961 0.002 247.84);\n  --color-background-primary-hover: oklch(0.97 0.002 247.839);\n  --color-text-primary: oklch(0.247 0.006 258.361);\n  --color-text-secondary: oklch(0.506 0.01 264.477);\n  --color-text-tertiary: oklch(0.54 0.01 264.484);\n  --color-border-button-default: oklch(0.912 0.005 258.326);\n  --color-separator-border: oklch(0.946 0.003 264.542);\n  --font-mono-source: var(--font-jetbrains-mono);\n}\n\nhtml.dark {\n  --color-background-full: oklch(0.209 0.004 264.477);\n  --color-background-primary-default: oklch(0.26 0.006 271.191);\n  --color-background-secondary-default: oklch(0.231 0.004 264.487);\n  --color-background-primary-hover: oklch(0.289 0.006 271.22);\n  --color-text-primary: oklch(0.964 0.002 247.839);\n  --color-text-secondary: oklch(0.731 0.008 260.731);\n  --color-text-tertiary: oklch(0.7 0.008 260.731);\n  --color-border-button-default: oklch(0.356 0.007 264.474);\n  --color-separator-border: oklch(0.308 0.006 258.354);\n}\n\nhtml:root,\nhtml.dark {\n  --color-border-focus-ring: var(--color-text-primary);\n  --color-tab-count-selected-background: var(--color-background-secondary-default);\n  --background: var(--color-background-full);\n  --foreground: var(--color-text-primary);\n  --card: var(--color-background-primary-default);\n  --card-foreground: var(--color-text-primary);\n  --popover: var(--color-background-primary-default);\n  --popover-foreground: var(--color-text-primary);\n  --primary: var(--color-text-primary);\n  --primary-foreground: var(--color-background-primary-default);\n  --secondary: var(--color-background-secondary-default);\n  --secondary-foreground: var(--color-text-primary);\n  --muted: var(--color-background-secondary-default);\n  --muted-foreground: var(--color-text-secondary);\n  --accent: var(--color-background-primary-hover);\n  --accent-foreground: var(--color-text-primary);\n  --border: var(--color-separator-border);\n  --input: var(--color-border-button-default);\n  --sidebar: var(--color-background-full);\n  --sidebar-foreground: var(--color-text-primary);\n  --sidebar-accent: var(--color-background-secondary-default);\n  --sidebar-border: var(--color-separator-border);\n  --radius: 10px;\n}\n\nbody {\n  font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif;\n  font-size: 14px;\n  line-height: 1.5;\n  letter-spacing: -0.01em;\n  font-feature-settings: \"cv11\", \"ss01\";\n  text-rendering: optimizeLegibility;\n}\n\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  *,\n  *::before,\n  *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n/* Result layouts respond to the card, including compact grid and expanded views. */\n.generated-result {\n  container-type: inline-size;\n  container-name: result;\n}\n@container result (min-width: 440px) {\n  .result-comparison-grid {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n}\n"
        },
        {
          "path": "components/beautiful-ui/LICENSE",
          "target": "@components/beautiful-ui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Shane Levine\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/LICENSE",
          "target": "@components/boardui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/boardui/styles/globals.css",
          "target": "@components/boardui/styles/globals.css",
          "type": "registry:file",
          "content": "@import \"tailwindcss\";\n@import \"./theme.css\";\n@import \"./typography.css\";\n\n/* ---------------------------------------------------------------------------\n * Dark mode strategy\n *\n * We use a class-based dark variant. Toggle dark mode by adding the `.dark`\n * class to <html> (a theme provider like `next-themes` can do this later).\n *\n *   <html class=\"dark\">  →  every `dark:*` utility activates\n *\n * Components should NOT use `dark:` prefixes directly. Instead they reference\n * semantic color tokens (e.g. `bg-bg-primary`, `text-text-primary`) that flip\n * under `.dark` in styles/theme.css.\n * --------------------------------------------------------------------------- */\n@custom-variant dark (&:where(.dark, .dark *));\n\n/* The next theme is revealed by ThemeToggle from the exact interaction point.\n * Native view-transition crossfades are disabled so only the soft circular\n * clip-path animation runs; unsupported browsers simply ignore these rules. */\n::view-transition-old(root),\n::view-transition-new(root) {\n  animation: none;\n  mix-blend-mode: normal;\n}\n\n@keyframes ai-chat-text-shimmer {\n  from {\n    background-position: 200% center;\n  }\n\n  to {\n    background-position: -100% center;\n  }\n}\n\n.agent-progress-loading-text {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    var(--color-text-secondary) 16%,\n    var(--color-text-secondary) 38%,\n    var(--color-text-primary) 50%,\n    var(--color-text-secondary) 62%,\n    var(--color-text-secondary) 84%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 3.4s linear infinite;\n  will-change: background-position;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .agent-progress-loading-text {\n    color: var(--color-text-secondary);\n    background-image: none;\n    animation: none;\n  }\n}\n\n::view-transition-old(root) {\n  z-index: 1;\n}\n\n::view-transition-new(root) {\n  z-index: 2;\n}\n\n/* Components often have their own hover/focus color transitions. Freeze them\n * while the browser captures the next theme so the expanding circle contains\n * the fully resolved new palette instead of a frame that is still fading from\n * the old one. This is what makes the click-origin reveal read clearly. */\n.theme-transitioning,\n.theme-transitioning * {\n  transition: none !important;\n}\n\n/* Reset + base */\nhtml,\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  font-variant-ligatures: contextual;\n  font-kerning: normal;\n}\n\nhtml {\n  color-scheme: light;\n  background-color: var(--color-background-full);\n}\nhtml.dark {\n  color-scheme: dark;\n}\nbody {\n  background-color: var(--color-background-full);\n  color: var(--color-text-primary);\n}\n\n/* Theme-aware monochrome BoardUI mark. Both images keep their intrinsic\n * dimensions while the root theme class decides which one participates in\n * layout, avoiding a light-logo flash during hydration. */\n.theme-logo-dark,\n.theme-asset-dark {\n  display: none;\n}\n.dark .theme-logo-light,\n.dark .theme-asset-light {\n  display: none;\n}\n.dark .theme-logo-dark,\n.dark .theme-asset-dark {\n  display: block;\n}\n\n/* Tailwind expands shadow utilities into `--tw-shadow` at build time. Point\n * those generated utilities back to the live dark elevation tokens so the\n * class-based theme can adjust opacity without component-level overrides. */\n.dark .shadow-2xs {\n  --tw-shadow: var(--shadow-2xs);\n}\n.dark .shadow-xs {\n  --tw-shadow: var(--shadow-xs);\n}\n.dark .shadow-sm {\n  --tw-shadow: var(--shadow-sm);\n}\n.dark .shadow-md {\n  --tw-shadow: var(--shadow-md);\n}\n.dark .shadow-lg {\n  --tw-shadow: var(--shadow-lg);\n}\n.dark .shadow-xl {\n  --tw-shadow: var(--shadow-xl);\n}\n.dark .shadow-card {\n  --tw-shadow: var(--shadow-card);\n}\n.dark .shadow-dropdown {\n  --tw-shadow: var(--shadow-dropdown);\n}\n.dark .shadow-sidebar {\n  --tw-shadow: var(--shadow-sidebar);\n}\n.dark .shadow-waitlist {\n  --tw-shadow: var(--shadow-waitlist);\n}\n\n/* Hide default expand arrow on Safari */\ndetails summary::-webkit-details-marker {\n  display: none;\n}\n\n/* Hide default number-input spinners */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\ninput[type=\"number\"] {\n  -moz-appearance: textfield;\n}\n\n/* Hide default search clear button */\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\n/* iOS Safari auto-zooms the page when a focused form field's font-size is\n * under 16px — our text-body-regular/medium tokens are 14px by design, so\n * bump just the font-size (not the whole token) on small screens instead of\n * changing the design system's type scale. */\n@media (max-width: 639px) {\n  input,\n  select,\n  textarea {\n    font-size: 16px;\n  }\n}\n\n/* Soft fade applied to an animated number each time its target changes */\n@keyframes number-fade {\n  from {\n    opacity: 0.35;\n  }\n  to {\n    opacity: 1;\n  }\n}\n.animate-number-fade {\n  animation: number-fade 220ms ease-out;\n}\n\n/* Recharts' accessibility layer makes the chart surface and its shapes\n * (bars, sectors, dots) keyboard-focusable, and Chrome paints the UA focus\n * outline around whichever one you click - a blue box around a ring segment\n * or a bar. Every chart card drives its own focus feedback (hover darkening,\n * headline swap), so the outline is noise: hide it across every Recharts\n * chart. Keyboard users still get the cards' own active states. */\n.recharts-wrapper:focus,\n.recharts-wrapper:focus-visible,\n.recharts-wrapper :focus,\n.recharts-wrapper :focus-visible {\n  outline: none;\n}\n\n/* Liquid glass (landing nav + hero) — the rim light.\n *\n * A fixed conic gradient standing in for a bevel lit from a single direction:\n * bright along the top edge where the light source is, dark down both sides\n * where the glass turns away, and a weaker bounce along the bottom. It does\n * not rotate — a travelling highlight reads as an animation playing on the\n * control, where a real edge just sits there catching the room.\n *\n * Achromatic on purpose: highlights are white, shading is black, nothing in\n * between carries a hue.\n *\n * The two-layer mask (padding-box XOR full box) keeps only the 1.5px ring,\n * letting the gradient paint the stroke without covering the glass. */\n\n.landing-glass-stroke {\n  pointer-events: none;\n  position: absolute;\n  inset: 0;\n  border-radius: inherit;\n  /* Every value here is set inline by `LiquidGlassSurface` from the shared\n   * glass config; the fallbacks are only for a bare use of the class. */\n  padding: var(--lg-rim-width, 1.5px);\n  background: conic-gradient(\n    from var(--lg-rim-angle, 0deg),\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 0deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 70deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 140deg,\n    var(--lg-rim-bounce, rgb(255 255 255 / 0.55)) 180deg,\n    var(--lg-rim-dim, rgb(255 255 255 / 0.1)) 220deg,\n    var(--lg-rim-sh, rgb(0 0 0 / 0.14)) 290deg,\n    var(--lg-rim-hi, rgb(255 255 255 / 0.9)) 360deg\n  );\n  /* Shorthands first, composites last: `-webkit-mask` aliases `mask` in\n   * Chromium, so a shorthand placed after a composite silently resets it to\n   * `add` — and an un-composited mask paints the full conic wash over the\n   * button instead of a ring. */\n  -webkit-mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  mask:\n    linear-gradient(#000 0 0) content-box,\n    linear-gradient(#000 0 0);\n  -webkit-mask-composite: xor;\n  mask-composite: exclude;\n  opacity: var(--lg-rim-o, 1);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n/* Liquid glass hover.\n *\n * Resting and hover values arrive together as inline custom properties, and\n * the swap happens here in CSS rather than in React state — hover then costs\n * a style recalculation instead of a re-render of everything inside the glass.\n * `.lg-hover` is the opt-in: a surface without it keeps its resting value. */\n.lg-tint {\n  background-color: var(--lg-tint, transparent);\n  transition: background-color var(--lg-ms, 200ms) ease;\n}\n\n.lg-sheen {\n  opacity: var(--lg-sheen, 0.5);\n  transition: opacity var(--lg-ms, 200ms) ease;\n}\n\n.lg-host {\n  box-shadow: var(--lg-shadow, none);\n  transition:\n    box-shadow var(--lg-ms, 200ms) ease,\n    transform var(--lg-ms, 200ms) ease;\n}\n\n.lg-host:hover {\n  box-shadow: var(--lg-shadow-hover, var(--lg-shadow, none));\n  transform: translateY(var(--lg-lift, 0px)) scale(var(--lg-scale, 1));\n}\n\n.group:hover .lg-tint.lg-hover {\n  background-color: var(--lg-tint-hover, var(--lg-tint, transparent));\n}\n\n.group:hover .lg-sheen.lg-hover {\n  opacity: var(--lg-sheen-hover, var(--lg-sheen, 0.5));\n}\n\n.group:hover .landing-glass-stroke.lg-hover {\n  opacity: var(--lg-rim-o-hover, var(--lg-rim-o, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .lg-tint,\n  .lg-sheen,\n  .lg-host,\n  .landing-glass-stroke {\n    transition: none;\n  }\n\n  .lg-host:hover {\n    transform: none;\n  }\n}\n\n/* Split-flap (\"Solari\" board) digit, used by the image-generation countdown.\n * Two leaves hinged on the card's centre seam:\n *   flap-fall  the outgoing digit's TOP half swings down over the incoming\n *              bottom half. Eased IN, because a real flap is falling under\n *              gravity — it accelerates — and it darkens as it tips away\n *              from the light.\n *   flap-rise  the incoming digit's BOTTOM half swings up from edge-on,\n *              starting exactly when the fall lands (delay = fall duration,\n *              `both` so it waits at 90deg instead of flashing flat). The\n *              small overshoot past 0deg is the slap against the stop —\n *              that bounce is what makes it read mechanical rather than\n *              like a plain rotation. */\n@keyframes flap-fall {\n  from {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n  to {\n    transform: rotateX(-90deg);\n    filter: brightness(0.86);\n  }\n}\n@keyframes flap-rise {\n  0% {\n    transform: rotateX(90deg);\n    filter: brightness(0.86);\n  }\n  70% {\n    transform: rotateX(-9deg);\n  }\n  86% {\n    transform: rotateX(4deg);\n  }\n  100% {\n    transform: rotateX(0deg);\n    filter: brightness(1);\n  }\n}\n.animate-flap-fall {\n  transform-origin: bottom center;\n  backface-visibility: hidden;\n  animation: flap-fall 150ms cubic-bezier(0.55, 0, 0.9, 0.35) forwards;\n}\n.animate-flap-rise {\n  transform-origin: top center;\n  backface-visibility: hidden;\n  animation: flap-rise 230ms cubic-bezier(0.25, 0.7, 0.35, 1) 150ms both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-flap-fall,\n  .animate-flap-rise {\n    animation-duration: 1ms;\n    animation-delay: 0ms;\n  }\n}\n\n/* New-row entrance for the Storage settings table. Three coordinated\n * pieces (wrapper pairs with `grid grid-rows-[1fr]` + an overflow-hidden\n * middle layer, content carries the slide):\n *   row-grow-in   wrapper's grid track 0fr → 1fr — pushes the rows below\n *                 down smoothly.\n *   row-slide-in  content translates -100% → 0 with the SAME duration and\n *                 easing, so it stays glued to the growing wrapper's bottom\n *                 edge — visually the row slides out from underneath the\n *                 header row above it.\n *   row-fade-in   opacity/blur on a SHORTER clock than the movement — the\n *                 row is fully visible before it finishes settling (fades\n *                 must complete before movement ends). */\n@keyframes row-grow-in {\n  from {\n    grid-template-rows: 0fr;\n  }\n  to {\n    grid-template-rows: 1fr;\n  }\n}\n@keyframes row-slide-in {\n  from {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-in {\n  from {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-grow-in {\n  animation: row-grow-in 400ms ease-out;\n}\n.animate-row-slide-in {\n  animation:\n    row-slide-in 400ms ease-out,\n    row-fade-in 240ms ease-out;\n}\n\n/* Reverse of the Storage row entrance. The content rises into the clipped\n * top edge while its grid track collapses, so the following rows move upward\n * continuously and the deleted row disappears beneath the header surface. */\n@keyframes row-collapse-out {\n  from {\n    grid-template-rows: 1fr;\n  }\n  to {\n    grid-template-rows: 0fr;\n  }\n}\n@keyframes row-slide-out {\n  to {\n    translate: 0 -100%;\n  }\n}\n@keyframes row-fade-out {\n  to {\n    opacity: 0;\n    filter: blur(2px);\n  }\n}\n.animate-row-collapse-out {\n  animation: row-collapse-out 225ms ease-in forwards;\n}\n.animate-row-slide-out {\n  animation:\n    row-slide-out 225ms ease-in forwards,\n    row-fade-out 160ms ease-in forwards;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-row-grow-in,\n  .animate-row-slide-in,\n  .animate-row-collapse-out,\n  .animate-row-slide-out {\n    animation-duration: 1ms;\n  }\n}\n\n/* Transitions.dev — \"Texts reveal\", used by the Storage dropzone's content\n * swaps (idle copy ↔ file name + status line).\n *\n * Entrance (`.is-shown` on the parent): lines rise 12px from below while\n * un-blurring, 500ms on a soft-landing bezier, staggered 40ms per line so\n * the eye lands on the first line first.\n * Exit (`.is-hiding`): a single quiet 200ms opacity fade in place — no Y\n * return, no blur, no stagger — so the disappearance never reads as a\n * reverse reveal.\n *\n * Deviations from the original snippet: custom props are scoped to\n * `.t-stagger` instead of :root, and `.t-stagger-line` doesn't force\n * `display: block` so flex-based lines (the icon disc) keep their layout. */\n.t-stagger {\n  --stagger-dur: 500ms;\n  --stagger-distance: 12px;\n  --stagger-stagger: 40ms;\n  --stagger-blur: 3px;\n  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);\n}\n.t-stagger-line {\n  opacity: 0;\n  transform: translateY(var(--stagger-distance));\n  filter: blur(var(--stagger-blur));\n  transition:\n    opacity var(--stagger-dur) var(--stagger-ease),\n    transform var(--stagger-dur) var(--stagger-ease),\n    filter var(--stagger-dur) var(--stagger-ease);\n  will-change: transform, opacity, filter;\n}\n.t-stagger-line--2 {\n  transition-delay: var(--stagger-stagger);\n}\n.t-stagger-line--3 {\n  transition-delay: calc(var(--stagger-stagger) * 2);\n}\n.t-stagger.is-shown .t-stagger-line {\n  opacity: 1;\n  transform: translateY(0);\n  filter: blur(0);\n}\n.t-stagger.is-hiding .t-stagger-line {\n  opacity: 0;\n  transform: translateY(0);\n  filter: blur(0);\n  transition:\n    opacity 200ms ease,\n    transform 0s linear,\n    filter 0s linear;\n  transition-delay: 0s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .t-stagger-line {\n    transition: none !important;\n  }\n}\n\n/* Rolling-counter label swap: the old value lifts 5px and fades out while the\n * new one rises in from 5px below and fades in. */\n@keyframes label-out {\n  from {\n    transform: translateY(0);\n    opacity: 1;\n  }\n  to {\n    transform: translateY(-10px);\n    opacity: 0;\n  }\n}\n@keyframes label-in {\n  from {\n    transform: translateY(10px);\n    opacity: 0;\n  }\n  to {\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n.animate-label-out {\n  animation: label-out 220ms ease-out forwards;\n}\n.animate-label-in {\n  animation: label-in 220ms ease-out;\n}\n\n/* Checkbox tick: draws the stroke on like it's being ticked by hand.\n * The path sets pathLength=1 so the dash math is resolution-independent. */\n@keyframes check-draw {\n  from {\n    stroke-dashoffset: 1;\n  }\n  to {\n    stroke-dashoffset: 0;\n  }\n}\n.animate-check-draw {\n  stroke-dasharray: 1;\n  stroke-dashoffset: 1;\n  animation: check-draw 200ms cubic-bezier(0.65, 0, 0.35, 1) forwards;\n}\n@media (prefers-reduced-motion: reduce) {\n  .animate-check-draw {\n    animation: none;\n    stroke-dashoffset: 0;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Chart entrance animations (AI profile template & contributions heatmap)\n * ------------------------------------------------------------------------- */\n\n/* Heatmap cells pop in softly — each cell gets a random-looking per-cell\n * animation-delay so the grid fills in a scattered order. */\n.contributions-grid {\n  --contribution-tier-0: var(--color-chart-neutral);\n}\n.contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-200); --contribution-tier-2: var(--color-emerald-400); --contribution-tier-3: var(--color-emerald-500); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-700);\n}\n.contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-200); --contribution-tier-2: var(--color-green-400); --contribution-tier-3: var(--color-green-500); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-700);\n}\n.contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-200); --contribution-tier-2: var(--color-teal-400); --contribution-tier-3: var(--color-teal-500); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-700);\n}\n.contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-200); --contribution-tier-2: var(--color-cyan-400); --contribution-tier-3: var(--color-cyan-500); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-700);\n}\n.contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-200); --contribution-tier-2: var(--color-blue-400); --contribution-tier-3: var(--color-blue-500); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-700);\n}\n.contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-200); --contribution-tier-2: var(--color-indigo-400); --contribution-tier-3: var(--color-indigo-500); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-700);\n}\n.contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-200); --contribution-tier-2: var(--color-violet-400); --contribution-tier-3: var(--color-violet-500); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-700);\n}\n.contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-200); --contribution-tier-2: var(--color-rose-400); --contribution-tier-3: var(--color-rose-500); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-700);\n}\n.contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-200); --contribution-tier-2: var(--color-amber-400); --contribution-tier-3: var(--color-amber-500); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-700);\n}\n\n.dark .contributions-grid[data-accent=\"emerald\"] {\n  --contribution-tier-1: var(--color-emerald-950); --contribution-tier-2: var(--color-emerald-800); --contribution-tier-3: var(--color-emerald-700); --contribution-tier-4: var(--color-emerald-600); --contribution-tier-5: var(--color-emerald-500);\n}\n.dark .contributions-grid[data-accent=\"green\"] {\n  --contribution-tier-1: var(--color-green-950); --contribution-tier-2: var(--color-green-800); --contribution-tier-3: var(--color-green-700); --contribution-tier-4: var(--color-green-600); --contribution-tier-5: var(--color-green-500);\n}\n.dark .contributions-grid[data-accent=\"teal\"] {\n  --contribution-tier-1: var(--color-teal-950); --contribution-tier-2: var(--color-teal-800); --contribution-tier-3: var(--color-teal-700); --contribution-tier-4: var(--color-teal-600); --contribution-tier-5: var(--color-teal-500);\n}\n.dark .contributions-grid[data-accent=\"cyan\"] {\n  --contribution-tier-1: var(--color-cyan-950); --contribution-tier-2: var(--color-cyan-800); --contribution-tier-3: var(--color-cyan-700); --contribution-tier-4: var(--color-cyan-600); --contribution-tier-5: var(--color-cyan-500);\n}\n.dark .contributions-grid[data-accent=\"blue\"] {\n  --contribution-tier-1: var(--color-blue-950); --contribution-tier-2: var(--color-blue-800); --contribution-tier-3: var(--color-blue-700); --contribution-tier-4: var(--color-blue-600); --contribution-tier-5: var(--color-blue-500);\n}\n.dark .contributions-grid[data-accent=\"indigo\"] {\n  --contribution-tier-1: var(--color-indigo-950); --contribution-tier-2: var(--color-indigo-800); --contribution-tier-3: var(--color-indigo-700); --contribution-tier-4: var(--color-indigo-600); --contribution-tier-5: var(--color-indigo-500);\n}\n.dark .contributions-grid[data-accent=\"violet\"] {\n  --contribution-tier-1: var(--color-violet-950); --contribution-tier-2: var(--color-violet-800); --contribution-tier-3: var(--color-violet-700); --contribution-tier-4: var(--color-violet-600); --contribution-tier-5: var(--color-violet-500);\n}\n.dark .contributions-grid[data-accent=\"rose\"] {\n  --contribution-tier-1: var(--color-rose-950); --contribution-tier-2: var(--color-rose-800); --contribution-tier-3: var(--color-rose-700); --contribution-tier-4: var(--color-rose-600); --contribution-tier-5: var(--color-rose-500);\n}\n.dark .contributions-grid[data-accent=\"amber\"] {\n  --contribution-tier-1: var(--color-amber-950); --contribution-tier-2: var(--color-amber-800); --contribution-tier-3: var(--color-amber-700); --contribution-tier-4: var(--color-amber-600); --contribution-tier-5: var(--color-amber-500);\n}\n\n.contribution-cell[data-tier=\"0\"] { background-color: var(--contribution-tier-0); }\n.contribution-cell[data-tier=\"1\"] { background-color: var(--contribution-tier-1); }\n.contribution-cell[data-tier=\"2\"] { background-color: var(--contribution-tier-2); }\n.contribution-cell[data-tier=\"3\"] { background-color: var(--contribution-tier-3); }\n.contribution-cell[data-tier=\"4\"] { background-color: var(--contribution-tier-4); }\n.contribution-cell[data-tier=\"5\"] { background-color: var(--contribution-tier-5); }\n\n@keyframes cell-pop {\n  from {\n    opacity: 0;\n    transform: scale(0.5);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n.animate-cell-pop {\n  animation: cell-pop 380ms ease-out both;\n}\n\n/* Bars grow up from the baseline; a per-bar delay staggers them left→right. */\n@keyframes bar-rise {\n  from {\n    transform: scaleY(0);\n  }\n  to {\n    transform: scaleY(1);\n  }\n}\n.animate-bar-rise {\n  transform-origin: bottom;\n  animation: bar-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n/* Line chart draws in left→right via a clip-path sweep over the whole plot\n * (line + gradient area together). */\n@keyframes chart-reveal {\n  from {\n    clip-path: inset(0 100% 0 0);\n  }\n  to {\n    clip-path: inset(0 0 0 0);\n  }\n}\n.animate-chart-reveal {\n  animation: chart-reveal 1800ms cubic-bezier(0.33, 0, 0.15, 1) both;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .animate-cell-pop,\n  .animate-bar-rise,\n  .animate-chart-reveal {\n    animation: none;\n  }\n}\n\n/* ---------------------------------------------------------------------------\n * Table primitive (components/base/table)\n *\n * React Aria's collection components (Column/Row/Cell/…) can't be wrapped in\n * custom components without losing collection behaviour, so the primitive\n * re-exports them untouched and styling lives here, scoped to `.bui-table`.\n * React Aria renders real <table>/<thead>/<th>/<tr>/<td> elements.\n * --------------------------------------------------------------------------- */\n.bui-table {\n  @apply w-full border-collapse text-left;\n}\n/* Header background + border-y live on the cells: with border-collapse the\n * browser doesn't paint backgrounds/borders set on the <thead> row group.\n * Backgrounds/borders are set with explicit CSS (theme vars) rather than\n * @apply, which drops border-width/bg on these row-group cells. */\n.bui-table th {\n  @apply px-3 py-2.5 text-left align-middle text-body-medium text-text-tertiary whitespace-nowrap outline-none;\n  background-color: var(--color-background-secondary-default);\n  border-top: 1px solid var(--color-separator-border);\n  border-bottom: 1px solid var(--color-separator-border);\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table td {\n  @apply px-3 py-2.5 align-middle text-body-medium text-text-primary outline-none;\n  transition: padding 200ms ease, font-size 200ms ease;\n}\n.bui-table tbody tr {\n  @apply transition-colors duration-150;\n  border-bottom: 1px solid var(--color-separator-border);\n}\n.bui-table tbody tr[data-focus-visible] {\n  @apply ring-2 ring-inset ring-border-focus-ring;\n}\n.bui-table.bui-table-sm th,\n.bui-table.bui-table-sm td {\n  @apply px-2.5 py-1.5 text-body-2-medium;\n}\n\n/* Agent Thinking (components/application/agent-thinking): the agent thinking state\n * above a chat composer. The label reuses the ai-chat-text-shimmer travel;\n * its base/highlight both derive from the tone the component sets via\n * --bui-agent-thinking-tone, so every tone shimmers consistently. */\n.bui-agent-thinking-label {\n  color: transparent;\n  background-image: linear-gradient(\n    100deg,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 30%,\n    var(--bui-agent-thinking-tone) 50%,\n    color-mix(in oklab, var(--bui-agent-thinking-tone) 55%, transparent) 70%\n  );\n  background-position: 200% center;\n  background-size: 300% 100%;\n  background-clip: text;\n  -webkit-background-clip: text;\n  animation: ai-chat-text-shimmer 2.6s linear infinite;\n  will-change: background-position;\n}\n\n/* Star sparkle: scale + fade in, settle, and vanish; per-star duration and\n * stagger come in via inline animation-duration/-delay. */\n@keyframes bui-agent-thinking-star {\n  0%,\n  100% {\n    transform: scale(0);\n    opacity: 0;\n  }\n  40% {\n    transform: scale(1);\n    opacity: 1;\n  }\n  60% {\n    transform: scale(0.8);\n    opacity: 0.9;\n  }\n}\n\n.bui-agent-thinking-star {\n  transform: scale(0);\n  animation-name: bui-agent-thinking-star;\n  animation-timing-function: ease-in-out;\n  animation-iteration-count: infinite;\n}\n\n/* Infinity comet: the dash segment laps the normalized (pathLength=100)\n * figure-eight once per animation-duration. */\n@keyframes bui-agent-thinking-dash {\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n.bui-agent-thinking-comet {\n  animation-name: bui-agent-thinking-dash;\n  animation-timing-function: linear;\n  animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-agent-thinking-label {\n    color: var(--bui-agent-thinking-tone);\n    background-image: none;\n    animation: none;\n  }\n\n  /* Stars rest visible instead of frozen at scale(0). */\n  .bui-agent-thinking-star {\n    animation: none;\n    transform: none;\n    opacity: 0.7;\n  }\n\n  .bui-agent-thinking-comet {\n    animation: none;\n  }\n}\n\n/* Star glyphs read a touch heavier than the dot grids on light backgrounds;\n * soften only them (not the label) there. Dark mode keeps the full tone. */\n.bui-agent-thinking-stars {\n  color: color-mix(in oklab, currentColor 75%, transparent);\n}\n\n.dark .bui-agent-thinking-stars {\n  color: inherit;\n}\n\n/* Composer Loader (components/application/composer-loader): the light band\n * orbiting the composer while the agent works. Dash segments on a\n * pathLength-normalized SVG stroke — the offset laps once per duration. */\n@keyframes bui-composer-loader-dash {\n  from {\n    stroke-dashoffset: 0;\n  }\n\n  to {\n    stroke-dashoffset: -100;\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-loader-rect {\n    animation: none !important;\n  }\n}\n\n/* Composer mic listening state (components/application/ai-chat): equalizer\n * bars dancing while voice input is active. Per-bar duration/delay come in\n * inline so the bars drift out of phase like real audio. */\n@keyframes bui-composer-mic-bars {\n  0%,\n  100% {\n    transform: scaleY(0.4);\n  }\n\n  50% {\n    transform: scaleY(1);\n  }\n}\n\n.bui-composer-mic-bar {\n  animation: bui-composer-mic-bars 0.9s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-composer-mic-bar {\n    animation: none;\n    transform: scaleY(0.7);\n  }\n}\n\n/* Shimmer sweep on a primary call to action (the Pro prompt card). */\n@keyframes bui-badge-shimmer {\n  0% {\n    transform: translateX(0) skewX(-12deg);\n  }\n  40%,\n  100% {\n    transform: translateX(350%) skewX(-12deg);\n  }\n}\n\n.bui-badge-shimmer {\n  animation: bui-badge-shimmer 2.5s ease-in-out infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .bui-badge-shimmer {\n      animation: none;\n      opacity: 0;\n    }\n}\n\n/* Showcase card (docs index, landing, the starter's catalogue). */\n.landing-showcase-card {\n  transition: box-shadow 280ms ease;\n}\n\n.landing-showcase-card::after {\n  content: \"\";\n  position: absolute;\n  inset: 0;\n  z-index: 60;\n  pointer-events: none;\n  border: 1px solid var(--color-border-button-default);\n  border-radius: inherit;\n  transition:\n    border-color 280ms ease,\n    box-shadow 280ms ease;\n}\n\n.dark .landing-showcase-card::after {\n  border-color: rgb(255 255 255 / 0.08);\n}\n\n@media (min-width: 640px) and (hover: hover) {\n  .landing-showcase-card:hover::after,\n  .landing-showcase-card:focus-within::after {\n    border-color: var(--color-border-button-hover);\n    box-shadow: inset 0 0 0 2px var(--color-border-button-hover);\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/theme.css",
          "target": "@components/boardui/styles/theme.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI theme tokens\n *\n * Layered as Tailwind v4 expects:\n *   @theme { ... }     primitives + ramp overrides → Tailwind utilities\n *   :root { ... }      semantic tokens (light mode) — reference primitives\n *   .dark { ... }      semantic overrides (dark mode) — landed when designed\n *   @theme inline {..} re-export of semantic tokens so they become utilities\n *\n * See docs/FIGMA_WORKFLOW.md for how tokens get added (Figma is source of truth).\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ----- Color primitives ----------------------------------------------------\n   * Almost the entire palette matches Tailwind v4's OKLCH defaults. The four\n   * overrides below are the only intentional deviations (see Figma → variables\n   * → color/...).\n   * --------------------------------------------------------------------------*/\n  --color-slate-200:   #ebeff5;\n  --color-neutral-100: #f7f7f7;\n  --color-neutral-200: #ebebeb;\n  --color-neutral-925: #121212;\n  --color-blue-400:    #3392ff;\n\n  /* ----- Accent ramp ---------------------------------------------------------\n   * The CTA hue. Interactive/selection surfaces (primary button gradient,\n   * ghost + link buttons, checkbox, radio, switch, slider, tabs, sidebar\n   * selected, focus ring, date-range selection) reference accent-* instead of\n   * a raw hue, so the whole system re-tints by overriding these eleven\n   * variables at runtime (see components/application/theme/accent.ts) or in\n   * a customer project after importing this file. Defaults to the blue\n   * primitives above. Content/data blues (charts, status chips, calendar\n   * events, info notifications) deliberately keep referencing blue-*.\n   * --------------------------------------------------------------------------*/\n  --color-accent-50:  var(--color-blue-50);\n  --color-accent-100: var(--color-blue-100);\n  --color-accent-200: var(--color-blue-200);\n  --color-accent-300: var(--color-blue-300);\n  --color-accent-400: var(--color-blue-400);\n  --color-accent-500: var(--color-blue-500);\n  --color-accent-600: var(--color-blue-600);\n  --color-accent-700: var(--color-blue-700);\n  --color-accent-800: var(--color-blue-800);\n  --color-accent-900: var(--color-blue-900);\n  --color-accent-950: var(--color-blue-950);\n\n  /* ----- Typography ----------------------------------------------------------\n   * Font sizes, weights, line-heights, and tracking all match Tailwind v4\n   * defaults. The only override is the family: Inter, loaded via next/font\n   * in app/layout.tsx, which exposes --font-inter to the document.\n   * --------------------------------------------------------------------------*/\n  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif,\n               \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\",\n               \"Noto Color Emoji\";\n\n  /* Monospace ramp for code blocks. Loaded via next/font in app/layout.tsx\n   * (--font-mono-source → JetBrains Mono). Figma's spec uses IBM Plex Mono;\n   * JetBrains Mono is the closest already-bundled face. */\n  --font-mono: var(--font-mono-source), ui-monospace, \"SFMono-Regular\", Menlo,\n               Consolas, \"Liberation Mono\", monospace;\n\n  /* ----- Radii ---------------------------------------------------------------\n   * Extra step between lg (8) and xl (12). Used by medium-size buttons.\n   * Figma name: radius/2lg.\n   * --------------------------------------------------------------------------*/\n  --radius-2lg: 10px;\n  --radius-notification-card: 10px;\n\n  /* ----- Shadows -------------------------------------------------------------\n   * 2xs, xs, 2xl and the inner shadows already match Tailwind v4. Sizes sm, md,\n   * lg, xl follow the Figma 6%/10% recipe (slightly softer than Tailwind v4's\n   * 10%/10% default).\n   * --------------------------------------------------------------------------*/\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.06), 0 1px 3px 0 rgb(0 0 0 / 0.10);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 4px 6px -1px rgb(0 0 0 / 0.10);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.05), 0 10px 15px -3px rgb(0 0 0 / 0.10);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.04), 0 20px 25px -5px rgb(0 0 0 / 0.10);\n\n  /* Figma effect style \"Background/Sidebar Elevation\" — copied 1:1:\n   *   DROP_SHADOW #00000005 offset(0,1) radius 0  spread 0  → 0 1px 0px  0 / 0.0196\n   *   DROP_SHADOW #0000000F offset(0,1) radius 12 spread 0  → 0 1px 12px 0 / 0.0588\n   *   DROP_SHADOW #00000052 offset(0,0) radius 1  spread 0  → 0 0   1px  0 / 0.3216\n   * (alpha = hex byte / 255: 05→0.0196, 0F→0.0588, 52→0.3216). */\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.0196),\n    0 1px 12px 0 rgb(0 0 0 / 0.0588),\n    0 0 1px 0 rgb(0 0 0 / 0.3216);\n\n  /* Figma effect style \"Sidebar selected\" — copied 1:1:\n   *   DROP_SHADOW  color/blue/500 offset(0,0) radius 0 spread 1 → 0 0 0 1px blue-500\n   *   INNER_SHADOW #FFFFFF40       offset(0,1) radius 0 spread 0 → inset 0 1px 0 0 / 0.251\n   * (#FFFFFF40 alpha = 0x40/255 = 0.251). */\n  --shadow-nav-selected:\n    0 0 0 1px var(--color-accent-500),\n    inset 0 1px 0 0 rgb(255 255 255 / 0.251);\n\n  /* Checkbox checked/indeterminate surface (from the Figma Checkbox component):\n   * inner top highlight + 1px inner blue edge over the primary gradient. */\n  --shadow-checkbox-selected:\n    inset 0 2px 0 0 rgb(255 255 255 / 0.25),\n    inset 0 0 0 1px var(--color-accent-500);\n\n  /* 1px contact shadow used on white cards/dropdown triggers sitting on the\n   * secondary background (Figma drop shadow 0 1 1 5%). */\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.05);\n\n  /* Floating menu/dropdown panel (Figma → sidebar profile menu node 3823:3699):\n   *   DROP_SHADOW #0000000A offset(0,1) radius 1 → 0 1px 1px 0 / 0.04\n   *   DROP_SHADOW #00000005 offset(0,4) radius 4 → 0 4px 4px 0 / 0.02 */\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.04),\n    0 4px 4px 0 rgb(0 0 0 / 0.02);\n\n  /* Floating template waitlist (Figma node 4117:32737). This extends the\n   * sidebar elevation recipe with the two broad ambient layers used by the\n   * signup surface. */\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.06),\n    0 0 64px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.32),\n    0 1px 12px 0 rgb(0 0 0 / 0.06),\n    0 1px 0 0 rgb(0 0 0 / 0.02);\n\n  /* Inner shadows (Figma names inner-shadow/*; Tailwind utility prefix is\n   * inset-shadow-*).\n   */\n  --inset-shadow-2xs: inset 0 1px 0 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-xs:  inset 0 1px 1px 0 rgb(0 0 0 / 0.05);\n  --inset-shadow-sm:  inset 0 2px 4px 0 rgb(0 0 0 / 0.05);\n}\n\n/* ---------------------------------------------------------------------------\n * Semantic tokens — light mode.\n *\n * All values reference primitives via var(--color-{family}-{shade}). Edit the\n * primitives in @theme above and these update automatically.\n *\n * Figma name on the left, var name on the right:\n *   foreground/full                  → --color-foreground-full\n *   foreground/icon/primary          → --color-foreground-icon-primary\n *   foreground/disabled              → --color-foreground-disabled\n *   foreground/disabled-danger       → --color-foreground-disabled-danger\n *   text/primary                     → --color-text-primary\n *   text/tertiary                    → --color-text-tertiary\n *   text/disabled-danger             → --color-text-disabled-danger\n *   background/primary/default       → --color-background-primary-default\n *   background/primary/hover         → --color-background-primary-hover\n *   background/primary/active        → --color-background-primary-active\n *   background/primary/disabled      → --color-background-primary-disabled\n *   background/secondary/default     → --color-background-secondary-default\n *   border/button/default            → --color-border-button-default\n *   border/button/hover              → --color-border-button-hover\n *   border/button/active             → --color-border-button-active\n *\n * Button gradients (linear, 180°, light stop → dark stop) sourced from the\n * blue/red primitives that each Button/{type}/{state} style references in\n * Figma. Direction inferred — confirm visually against Figma.\n * --------------------------------------------------------------------------- */\n:root {\n  /* Foreground (icons + on-fill content) */\n  --color-foreground-full:               var(--color-white);\n  --color-foreground-icon-primary:       var(--color-neutral-950);\n  --color-foreground-icon-hover:         var(--color-black);\n  --color-foreground-icon-secondary:     var(--color-neutral-500);\n  --color-foreground-icon-tertiary:      var(--color-neutral-400);\n  --color-foreground-icon-quaternary:    var(--color-neutral-300);\n  --color-foreground-icon-error:         var(--color-red-600);\n  --color-foreground-icon-disabled:      var(--color-neutral-300);\n  --color-foreground-disabled:           var(--color-neutral-400);\n  --color-foreground-disabled-danger:    var(--color-red-300);\n  --color-input-disabled-foreground:     var(--color-neutral-300);\n  --color-icon-button-disabled-foreground: var(--color-neutral-300);\n  --color-button-primary-disabled-foreground: var(--color-neutral-400);\n\n  /* Text */\n  --color-text-primary:         var(--color-neutral-950);\n  --color-text-secondary:       var(--color-neutral-600);\n  --color-text-tertiary:        #737373;\n  --color-text-disabled:        var(--color-neutral-300);\n  --color-text-disabled-danger: var(--color-red-300);\n  --color-text-placeholder:     var(--color-neutral-400);\n  --color-text-error-primary:   var(--color-red-500);\n  --color-input-disabled-text:  var(--color-neutral-300);\n  --color-text-white:           var(--color-white);\n\n  /* Background */\n  --color-background-full:              var(--color-white);\n  --color-background-primary-default:   var(--color-white);\n  --color-background-inner-default:     var(--color-white);\n  --color-background-primary-hover:     var(--color-neutral-100);\n  --color-background-primary-active:    var(--color-neutral-200);\n  --color-background-primary-disabled:  var(--color-neutral-100);\n  --color-input-disabled-background:    var(--color-neutral-100);\n  --color-background-secondary-default: var(--color-neutral-100);\n  --color-background-secondary-hover:   var(--color-neutral-200);\n  --color-background-tertiary-default:  var(--color-neutral-200);\n  --color-background-tertiary-hover:    var(--color-neutral-300);\n  --color-background-tertiary-error:    var(--color-red-100);\n  --color-background-recent-hire-role:  var(--color-neutral-100);\n  --color-avatar-neutral-background:    var(--color-neutral-300);\n  /* Figma background/quaternary/default — first used by the Storage\n   * dropzone's upload-icon disc (node 4106:26587). */\n  --color-background-quaternary-default: var(--color-neutral-300);\n  --color-background-quaternary-hover:   var(--color-neutral-400);\n  --color-background-quaternary-error:   var(--color-red-200);\n  --color-file-upload-icon-background:   var(--color-neutral-300);\n  --color-file-upload-icon-foreground:   var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-500);\n\n  /* Border */\n  --color-border-button-default:   var(--color-neutral-200);\n  --color-border-button-hover:     var(--color-neutral-300);\n  --color-border-button-active:    var(--color-neutral-400);\n  --color-border-button-white:     var(--color-white);\n  /* The system had no red border. Matches text/error/primary so an invalid\n     field's edge and its message are the same red. */\n  --color-border-error-default:    var(--color-red-500);\n  --color-border-checkbox-default: var(--color-neutral-300);\n  --color-border-checkbox-hover:   var(--color-neutral-400);\n  --color-border-checkbox-active:  var(--color-neutral-400);\n  --color-border-checkbox-white:   var(--color-white);\n  --color-border-component-detail-container: var(--color-neutral-200);\n  --color-border-ai-profile-card:             var(--color-neutral-200);\n  --color-border-table:            var(--color-neutral-200);\n  --color-border-button-group:     var(--color-neutral-200);\n  --color-border-sidebar-profile-hover: var(--color-neutral-300);\n  --color-separator-border:        var(--color-neutral-200);\n  --color-separator-border-strong: var(--color-neutral-200);\n  --color-border-focus-ring:       var(--color-accent-500);\n\n  /* State */\n  --color-state-success-text: var(--color-lime-800);\n  --color-state-success-base: var(--color-lime-200);\n\n  /* Selected control interiors remain light on colored tracks in both themes. */\n  --color-control-indicator-background:        var(--color-white);\n  --color-control-indicator-background-subtle: var(--color-neutral-100);\n  --color-switch-off-chip-start:                var(--color-white);\n  --color-switch-off-chip-end:                  var(--color-neutral-100);\n  /* Selected switch chip: the Figma comps use hexes a touch deeper than the\n   * plain 500→600 ramp (#2473fe → #0450e2 for blue). Expressed as oklab mixes\n   * of neighbouring accent stops so the recipe survives a re-tint. */\n  --color-switch-on-chip-start:                 color-mix(in oklab, var(--color-accent-500) 63%, var(--color-accent-600));\n  --color-switch-on-chip-end:                   color-mix(in oklab, var(--color-accent-600) 16%, var(--color-accent-700));\n  --color-stat-card-icon-background:            var(--color-white);\n  --color-segmented-control-background:          var(--color-neutral-100);\n  --color-segmented-control-selected-background: var(--color-white);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-200);\n  --color-theme-toggle-sidebar-selected-background: var(--color-white);\n  /* Stepped against the composer: the pill is white and the add button is the\n   * subtle grey sitting on it, so the control separates from the surface it\n   * shares an edge with. Dark mode keeps its own pair, where the pill is the\n   * lighter of the two and the button steps the other way. */\n  --color-ai-chat-composer-add-background:       var(--color-neutral-100);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-200);\n  --color-agent-progress-ring:                     var(--color-neutral-700);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-neutral-100);\n  --color-kbd-background:                        var(--color-neutral-300);\n  --color-kbd-foreground:                        var(--color-neutral-500);\n  --color-docs-file-chip-background:             var(--color-purple-50);\n  --color-docs-file-chip-border:                 var(--color-purple-100);\n  --color-docs-file-chip-foreground:             var(--color-purple-500);\n  --color-docs-command-accent:                    var(--color-purple-400);\n  --color-docs-code-background:                   var(--color-background-primary-default);\n  --color-docs-install-rail:                      var(--color-border-button-default);\n\n  /* Recently shipped component badge. Kept semantic so its compact blue\n   * surface can retain the same hierarchy in both themes. */\n  --color-badge-neutral-background: var(--color-neutral-200);\n  --color-team-menu-count-background: var(--color-neutral-200);\n  --color-team-menu-count-foreground: var(--color-neutral-500);\n  --color-badge-new-background: var(--color-accent-100);\n  --color-badge-new-text:       var(--color-accent-600);\n  --color-tab-count-selected-background: var(--color-accent-100);\n  --color-pill-tab-blue-selected-background: var(--color-accent-50);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-100);\n\n  /* Notification status-icon surfaces. */\n  --color-notification-information-background: var(--color-blue-100);\n  --color-notification-information-foreground: var(--color-blue-600);\n  --color-notification-success-background:     var(--color-lime-100);\n  --color-notification-success-foreground:     var(--color-lime-600);\n  --color-notification-error-background:       var(--color-rose-100);\n  --color-notification-error-foreground:       var(--color-rose-600);\n  --color-notification-center-background:      var(--color-white);\n\n  /* Table status chips. Dark mappings come from the medical dashboard table\n   * in Figma (4139:7202, 4139:7240, 4139:7278, 4139:7315). */\n  --color-status-lime-background:   var(--color-lime-200);\n  --color-status-lime-text:         var(--color-lime-800);\n  --color-status-yellow-background: var(--color-yellow-200);\n  --color-status-yellow-text:       var(--color-yellow-800);\n  --color-status-rose-background:   var(--color-rose-200);\n  --color-status-rose-text:         var(--color-rose-800);\n  --color-status-cyan-background:   var(--color-cyan-200);\n  --color-status-cyan-text:         var(--color-cyan-800);\n  --color-status-blue-background:   var(--color-blue-200);\n  --color-status-blue-text:         var(--color-blue-800);\n  --color-status-purple-background: var(--color-purple-100);\n  --color-status-purple-text:       var(--color-purple-600);\n  --color-status-dot-green-halo:    var(--color-green-100);\n  --color-status-dot-yellow-halo:   var(--color-yellow-200);\n  --color-status-dot-indigo-halo:   var(--color-indigo-100);\n\n  /* Date range selection: the connecting band and its start/end caps. */\n  --color-date-range-background:      var(--color-accent-100);\n  --color-date-range-edge-background: var(--color-accent-300);\n\n  /* Calendar event chips. Title/time stay separate so the original light\n   * hierarchy remains intact while dark mode can normalize both to /300. */\n  --color-calendar-event-blue-background:    var(--color-blue-100);\n  --color-calendar-event-blue-title:         var(--color-blue-700);\n  --color-calendar-event-blue-time:          var(--color-blue-700);\n  --color-calendar-event-pink-background:    var(--color-pink-100);\n  --color-calendar-event-pink-title:         var(--color-pink-700);\n  --color-calendar-event-pink-time:          var(--color-pink-700);\n  --color-calendar-event-purple-background:  var(--color-purple-100);\n  --color-calendar-event-purple-title:       var(--color-purple-700);\n  --color-calendar-event-purple-time:        var(--color-purple-700);\n  --color-calendar-event-lime-background:    var(--color-lime-100);\n  --color-calendar-event-lime-title:         var(--color-lime-800);\n  --color-calendar-event-lime-time:          var(--color-lime-700);\n  --color-calendar-event-emerald-background: var(--color-emerald-100);\n  --color-calendar-event-emerald-title:      var(--color-emerald-800);\n  --color-calendar-event-emerald-time:       var(--color-emerald-700);\n\n  /* Placeholder colors that don't map cleanly to existing text tokens */\n  --color-text-error-placeholder: var(--color-red-400);\n\n  /* Charts (graphs) — shared neutrals + a categorical accent ramp.\n   * `track` is the background bar/ring behind a series; `cursor` the hover\n   * outline / dashed reference line; `neutral` a data color for \"other\"-style\n   * slices. Each numbered accent pairs a base fill with a one-tone-darker\n   * `-active` used for hover emphasis (the 400 → 500 recipe every chart\n   * follows). Numbered (not hue-named) so the palette can be retuned without\n   * renaming, mirroring the chart-1…n convention common to chart systems. */\n  --color-chart-track:    var(--color-neutral-200);\n  --color-chart-cursor:   var(--color-neutral-300);\n  --color-chart-neutral:  var(--color-neutral-300);\n  --color-chart-1:        var(--color-teal-400);\n  --color-chart-1-active: var(--color-teal-500);\n  --color-chart-2:        var(--color-lime-400);\n  --color-chart-2-active: var(--color-lime-500);\n  --color-chart-3:        var(--color-pink-400);\n  --color-chart-3-active: var(--color-pink-500);\n  --color-chart-4:        var(--color-sky-400);\n  --color-chart-4-active: var(--color-sky-500);\n  --color-chart-5:        var(--color-purple-400);\n  --color-chart-5-active: var(--color-purple-500);\n  --color-chart-6:        var(--color-blue-400);\n  --color-chart-6-active: var(--color-blue-500);\n  --color-chart-7:        var(--color-emerald-400);\n  --color-chart-7-active: var(--color-emerald-500);\n  --color-chart-8:        var(--color-yellow-400);\n  --color-chart-8-active: var(--color-yellow-500);\n  --color-chart-9:        var(--color-indigo-400);\n  --color-chart-9-active: var(--color-indigo-500);\n  --color-chart-agents-bar:        var(--color-purple-300);\n  --color-chart-agents-bar-active: var(--color-purple-400);\n\n  /* Button gradients */\n  --gradient-button-primary-default:  linear-gradient(180deg, var(--color-accent-500)    0%, var(--color-accent-600)    100%);\n  --gradient-button-primary-hover:    linear-gradient(180deg, var(--color-accent-400)    0%, var(--color-accent-500)    100%);\n  --gradient-button-primary-active:   linear-gradient(180deg, var(--color-accent-600)    0%, var(--color-accent-700)    100%);\n  --gradient-button-primary-disabled: linear-gradient(180deg, var(--color-neutral-200) 0%, var(--color-neutral-300) 100%);\n\n  --gradient-button-danger-default:   linear-gradient(180deg, var(--color-red-500) 0%, var(--color-red-600) 100%);\n  --gradient-button-danger-hover:     linear-gradient(180deg, var(--color-red-400) 0%, var(--color-red-500) 100%);\n  --gradient-button-danger-active:    linear-gradient(180deg, var(--color-red-600) 0%, var(--color-red-700) 100%);\n  --gradient-button-danger-disabled:  linear-gradient(180deg, var(--color-red-100) 0%, var(--color-red-200) 100%);\n}\n\n.dark {\n  /* Foreground */\n  --color-foreground-full:            var(--color-neutral-700);\n  --color-foreground-icon-primary:    var(--color-neutral-50);\n  --color-foreground-icon-hover:      var(--color-white);\n  --color-foreground-icon-error:      var(--color-red-400);\n  --color-foreground-icon-tertiary:   var(--color-neutral-600);\n  --color-foreground-icon-quaternary: var(--color-neutral-700);\n  --color-foreground-icon-disabled:   var(--color-neutral-800);\n  --color-foreground-disabled:        var(--color-neutral-700);\n  --color-foreground-disabled-danger: var(--color-red-400);\n  --color-input-disabled-foreground:  var(--color-neutral-600);\n  --color-icon-button-disabled-foreground: var(--color-neutral-500);\n  --color-button-primary-disabled-foreground: var(--color-neutral-500);\n\n  /* Text */\n  --color-text-primary:  var(--color-neutral-50);\n  --color-text-tertiary: var(--color-neutral-600);\n  --color-text-disabled: var(--color-neutral-800);\n  --color-text-error-primary: var(--color-red-400);\n  --color-input-disabled-text: color-mix(in srgb, var(--color-neutral-500) 40%, transparent);\n\n  /* Background */\n  --color-background-full:              var(--color-neutral-925);\n  --color-background-primary-default:   #1c1c1c;\n  --color-background-inner-default:     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n  --color-background-primary-hover:     color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-background-primary-active:    var(--color-neutral-800);\n  --color-background-primary-disabled:  var(--color-neutral-800);\n  --color-input-disabled-background:    color-mix(in srgb, var(--color-neutral-800) 30%, transparent);\n  --color-switch-off-chip-start:        var(--color-background-tertiary-default);\n  --color-switch-off-chip-end:          var(--color-background-tertiary-default);\n  --color-background-secondary-default: #171717;\n  --color-background-secondary-hover:   var(--color-neutral-800);\n  --color-background-tertiary-default:  var(--color-neutral-800);\n  --color-background-tertiary-hover:    var(--color-neutral-700);\n  --color-background-tertiary-error:    color-mix(in srgb, var(--color-red-950) 60%, transparent);\n  --color-background-quaternary-default: var(--color-neutral-700);\n  --color-background-quaternary-hover:   var(--color-neutral-600);\n  --color-background-recent-hire-role:  color-mix(in srgb, var(--color-neutral-900) 60%, transparent);\n  --color-avatar-neutral-background:    var(--color-background-primary-default);\n  --color-file-upload-icon-background:  var(--color-neutral-600);\n  --color-file-upload-icon-foreground:  var(--color-neutral-400);\n  --color-file-upload-icon-foreground-hover: var(--color-neutral-300);\n  --color-stat-card-icon-background:    var(--color-neutral-800);\n  --color-segmented-control-background:          var(--color-neutral-925);\n  --color-segmented-control-selected-background: var(--color-neutral-800);\n  --color-theme-toggle-sidebar-background:       var(--color-neutral-800);\n  --color-theme-toggle-sidebar-selected-background: var(--color-neutral-700);\n  --color-ai-chat-composer-add-background:       var(--color-neutral-700);\n  --color-ai-chat-composer-add-hover-background: var(--color-neutral-600);\n  --color-agent-progress-ring:                     color-mix(in srgb, var(--color-white) 50%, transparent);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n  --color-kbd-background:                        var(--color-neutral-700);\n  --color-kbd-foreground:                        var(--color-neutral-400);\n  --color-docs-file-chip-background:             color-mix(in srgb, var(--color-purple-950) 50%, transparent);\n  --color-docs-file-chip-border:                 var(--color-purple-800);\n  --color-docs-file-chip-foreground:             var(--color-purple-400);\n  --color-docs-code-background:                  var(--color-background-full);\n  --color-docs-install-rail:                     color-mix(in srgb, var(--color-neutral-800) 60%, transparent);\n\n  /* Dark surfaces absorb low-alpha shadows more readily than white ones.\n   * Preserve the light-mode geometry and raise only the black alpha: tighter\n   * contact shadows stay crisp, while higher elevations receive a restrained\n   * ambient layer without introducing a grey glow. */\n  --shadow-2xs: 0 1px rgb(0 0 0 / 0.16);\n  --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.18);\n  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.12), 0 1px 3px 0 rgb(0 0 0 / 0.16);\n  --shadow-md: 0 2px 4px -1px rgb(0 0 0 / 0.12), 0 4px 6px -1px rgb(0 0 0 / 0.18);\n  --shadow-lg: 0 4px 6px -2px rgb(0 0 0 / 0.10), 0 10px 15px -3px rgb(0 0 0 / 0.18);\n  --shadow-xl: 0 10px 10px -5px rgb(0 0 0 / 0.08), 0 20px 25px -5px rgb(0 0 0 / 0.20);\n  --shadow-card: 0 1px 1px 0 rgb(0 0 0 / 0.14);\n  --shadow-dropdown:\n    0 1px 1px 0 rgb(0 0 0 / 0.14),\n    0 4px 4px 0 rgb(0 0 0 / 0.10);\n  --shadow-sidebar:\n    0 1px 0 0 rgb(0 0 0 / 0.10),\n    0 1px 12px 0 rgb(0 0 0 / 0.16),\n    0 0 1px 0 rgb(0 0 0 / 0.42);\n  --shadow-waitlist:\n    0 0 6px 0 rgb(0 0 0 / 0.12),\n    0 0 64px 0 rgb(0 0 0 / 0.22),\n    0 0 1px 0 rgb(0 0 0 / 0.42),\n    0 1px 12px 0 rgb(0 0 0 / 0.14),\n    0 1px 0 0 rgb(0 0 0 / 0.08);\n\n  /* Badges */\n  --color-badge-neutral-background: var(--color-neutral-800);\n  --color-team-menu-count-background: var(--color-neutral-700);\n  --color-team-menu-count-foreground: var(--color-neutral-400);\n  --color-badge-new-background: var(--color-accent-950);\n  --color-badge-new-text:       var(--color-accent-400);\n  --color-tab-count-selected-background: color-mix(in srgb, var(--color-accent-800) 60%, transparent);\n\n  /* Dark status discs use /800 surfaces with /300 foregrounds so the icon\n   * remains crisp without reverting to a bright pastel circle. */\n  --color-notification-information-background: color-mix(in srgb, var(--color-blue-800) 50%, transparent);\n  --color-notification-information-foreground: var(--color-blue-300);\n  --color-notification-success-background:     color-mix(in srgb, var(--color-lime-800) 50%, transparent);\n  --color-notification-success-foreground:     var(--color-lime-300);\n  --color-notification-error-background:       color-mix(in srgb, var(--color-rose-800) 50%, transparent);\n  --color-notification-error-foreground:       var(--color-rose-300);\n  --color-notification-center-background:      var(--color-neutral-900);\n\n  /* Borders and separators */\n  --color-border-button-default:   var(--color-neutral-700);\n  --color-border-button-hover:     var(--color-neutral-500);\n  --color-border-button-active:    var(--color-neutral-600);\n  --color-border-button-white:     var(--color-zinc-800);\n  --color-border-error-default:    var(--color-red-400);\n  --color-border-checkbox-default: var(--color-neutral-700);\n  --color-border-checkbox-hover:   var(--color-neutral-500);\n  --color-border-checkbox-active:  var(--color-neutral-500);\n  --color-border-component-detail-container: var(--color-neutral-800);\n  --color-border-ai-profile-card:             var(--color-neutral-800);\n  --color-border-table:            var(--color-neutral-800);\n  --color-border-button-group:     color-mix(in srgb, var(--color-neutral-600) 60%, transparent);\n  --color-border-sidebar-profile-hover: var(--color-neutral-600);\n  --color-separator-border:        var(--color-neutral-800);\n  --color-separator-border-strong: color-mix(in srgb, var(--color-neutral-700) 60%, transparent);\n\n  /* Figma's dark table status pairs. */\n  --color-status-lime-background:   color-mix(in srgb, var(--color-lime-950) 60%, transparent);\n  --color-status-lime-text:         var(--color-lime-500);\n  --color-status-yellow-background: color-mix(in srgb, var(--color-yellow-950) 60%, transparent);\n  --color-status-yellow-text:       var(--color-yellow-500);\n  --color-status-rose-background:   color-mix(in srgb, var(--color-rose-950) 60%, transparent);\n  --color-status-rose-text:         var(--color-rose-500);\n  --color-status-cyan-background:   color-mix(in srgb, var(--color-cyan-950) 60%, transparent);\n  --color-status-cyan-text:         var(--color-cyan-400);\n  --color-status-blue-background:   color-mix(in srgb, var(--color-blue-950) 60%, transparent);\n  --color-status-blue-text:         var(--color-blue-300);\n  --color-status-purple-background: color-mix(in srgb, var(--color-purple-900) 50%, transparent);\n  --color-status-purple-text:       var(--color-purple-300);\n  --color-status-dot-green-halo:    color-mix(in srgb, var(--color-green-800) 40%, transparent);\n  --color-status-dot-yellow-halo:   color-mix(in srgb, var(--color-yellow-800) 40%, transparent);\n  --color-status-dot-indigo-halo:   color-mix(in srgb, var(--color-indigo-800) 40%, transparent);\n\n  --color-date-range-background:      var(--color-accent-950);\n  --color-date-range-edge-background: var(--color-accent-800);\n\n  --color-pill-tab-blue-selected-background: color-mix(in srgb, var(--color-accent-950) 60%, transparent);\n  --color-pill-tab-blue-hover-background: var(--color-neutral-800);\n\n  /* Calendar event families share the same dark-mode depth/contrast recipe. */\n  --color-calendar-event-blue-background:    var(--color-blue-950);\n  --color-calendar-event-blue-title:         var(--color-blue-300);\n  --color-calendar-event-blue-time:          var(--color-blue-300);\n  --color-calendar-event-pink-background:    var(--color-pink-950);\n  --color-calendar-event-pink-title:         var(--color-pink-300);\n  --color-calendar-event-pink-time:          var(--color-pink-300);\n  --color-calendar-event-purple-background:  var(--color-purple-950);\n  --color-calendar-event-purple-title:       var(--color-purple-300);\n  --color-calendar-event-purple-time:        var(--color-purple-300);\n  --color-calendar-event-lime-background:    var(--color-lime-950);\n  --color-calendar-event-lime-title:         var(--color-lime-300);\n  --color-calendar-event-lime-time:          var(--color-lime-300);\n  --color-calendar-event-emerald-background: var(--color-emerald-950);\n  --color-calendar-event-emerald-title:      var(--color-emerald-300);\n  --color-calendar-event-emerald-time:       var(--color-emerald-300);\n\n  /* Disabled primary CTA: dark, low-emphasis fill with readable muted text. */\n  --gradient-button-primary-disabled: linear-gradient(\n    180deg,\n    var(--color-neutral-700) 0%,\n    var(--color-neutral-800) 100%\n  );\n  --gradient-button-danger-disabled: linear-gradient(\n    180deg,\n    var(--color-red-900) 0%,\n    var(--color-red-950) 100%\n  );\n\n  /* Neutral graph structure; categorical and status colors stay unchanged. */\n  --color-chart-track:   var(--color-neutral-800);\n  --color-chart-cursor:  var(--color-neutral-700);\n  --color-chart-neutral: var(--color-neutral-800);\n  --color-chart-agents-bar:        var(--color-purple-500);\n  --color-chart-agents-bar-active: var(--color-purple-600);\n}\n\n/* Non-default accents (data-accent set by the accent engine) can land on a\n * /950 that glows too loudly against the dark sidebar; halve the NEW badge\n * fill there. Light mode keeps the solid /100 surface. */\n.dark[data-accent] {\n  --color-badge-new-background: color-mix(in srgb, var(--color-accent-950) 50%, transparent);\n}\n\n/* Re-export semantic tokens as Tailwind utilities. The `inline` form means\n * Tailwind reads the *current* computed value of the variable, so light↔dark\n * flips work without rebuild. */\n@theme inline {\n  --color-foreground-full:            var(--color-foreground-full);\n  --color-foreground-icon-primary:    var(--color-foreground-icon-primary);\n  --color-foreground-icon-hover:      var(--color-foreground-icon-hover);\n  --color-foreground-icon-secondary:  var(--color-foreground-icon-secondary);\n  --color-foreground-icon-tertiary:   var(--color-foreground-icon-tertiary);\n  --color-foreground-icon-quaternary: var(--color-foreground-icon-quaternary);\n  --color-foreground-icon-error:      var(--color-foreground-icon-error);\n  --color-foreground-icon-disabled:   var(--color-foreground-icon-disabled);\n  --color-foreground-disabled:        var(--color-foreground-disabled);\n  --color-foreground-disabled-danger: var(--color-foreground-disabled-danger);\n  --color-input-disabled-foreground:  var(--color-input-disabled-foreground);\n  --color-icon-button-disabled-foreground: var(--color-icon-button-disabled-foreground);\n  --color-button-primary-disabled-foreground: var(--color-button-primary-disabled-foreground);\n\n  --color-text-primary:         var(--color-text-primary);\n  --color-text-secondary:       var(--color-text-secondary);\n  --color-text-tertiary:        var(--color-text-tertiary);\n  --color-text-disabled:        var(--color-text-disabled);\n  --color-text-disabled-danger: var(--color-text-disabled-danger);\n  --color-text-placeholder:     var(--color-text-placeholder);\n  --color-text-error-primary:   var(--color-text-error-primary);\n  --color-input-disabled-text:  var(--color-input-disabled-text);\n  --color-text-white:           var(--color-text-white);\n\n  --color-background-full:              var(--color-background-full);\n  --color-background-primary-default:   var(--color-background-primary-default);\n  --color-background-inner-default:     var(--color-background-inner-default);\n  --color-background-primary-hover:     var(--color-background-primary-hover);\n  --color-background-primary-active:    var(--color-background-primary-active);\n  --color-background-primary-disabled:  var(--color-background-primary-disabled);\n  --color-input-disabled-background:    var(--color-input-disabled-background);\n  --color-background-secondary-default: var(--color-background-secondary-default);\n  --color-background-secondary-hover:   var(--color-background-secondary-hover);\n  --color-background-tertiary-default:  var(--color-background-tertiary-default);\n  --color-background-tertiary-hover:    var(--color-background-tertiary-hover);\n  --color-background-tertiary-error:    var(--color-background-tertiary-error);\n  --color-background-recent-hire-role:  var(--color-background-recent-hire-role);\n  --color-avatar-neutral-background:    var(--color-avatar-neutral-background);\n  --color-background-quaternary-default: var(--color-background-quaternary-default);\n  --color-background-quaternary-hover:   var(--color-background-quaternary-hover);\n  --color-background-quaternary-error:   var(--color-background-quaternary-error);\n  --color-file-upload-icon-background:   var(--color-file-upload-icon-background);\n  --color-file-upload-icon-foreground:   var(--color-file-upload-icon-foreground);\n  --color-file-upload-icon-foreground-hover: var(--color-file-upload-icon-foreground-hover);\n\n  --color-border-button-default:   var(--color-border-button-default);\n  --color-border-button-hover:     var(--color-border-button-hover);\n  --color-border-button-active:    var(--color-border-button-active);\n  --color-border-button-white:     var(--color-border-button-white);\n  --color-border-error-default:    var(--color-border-error-default);\n  --color-border-checkbox-default: var(--color-border-checkbox-default);\n  --color-border-checkbox-hover:   var(--color-border-checkbox-hover);\n  --color-border-checkbox-active:  var(--color-border-checkbox-active);\n  --color-border-checkbox-white:   var(--color-border-checkbox-white);\n  --color-border-component-detail-container: var(--color-border-component-detail-container);\n  --color-border-ai-profile-card:             var(--color-border-ai-profile-card);\n  --color-border-table:            var(--color-border-table);\n  --color-border-button-group:     var(--color-border-button-group);\n  --color-border-sidebar-profile-hover: var(--color-border-sidebar-profile-hover);\n  --color-separator-border:        var(--color-separator-border);\n  --color-separator-border-strong: var(--color-separator-border-strong);\n  --color-border-focus-ring:       var(--color-border-focus-ring);\n\n  --color-state-success-text: var(--color-state-success-text);\n  --color-state-success-base: var(--color-state-success-base);\n  --color-control-indicator-background:        var(--color-control-indicator-background);\n  --color-control-indicator-background-subtle: var(--color-control-indicator-background-subtle);\n  --color-switch-off-chip-start:                var(--color-switch-off-chip-start);\n  --color-switch-off-chip-end:                  var(--color-switch-off-chip-end);\n  --color-switch-on-chip-start:                 var(--color-switch-on-chip-start);\n  --color-switch-on-chip-end:                   var(--color-switch-on-chip-end);\n  --color-stat-card-icon-background:            var(--color-stat-card-icon-background);\n  --color-segmented-control-background:          var(--color-segmented-control-background);\n  --color-segmented-control-selected-background: var(--color-segmented-control-selected-background);\n  --color-theme-toggle-sidebar-background:       var(--color-theme-toggle-sidebar-background);\n  --color-theme-toggle-sidebar-selected-background: var(--color-theme-toggle-sidebar-selected-background);\n  --color-ai-chat-composer-add-background:       var(--color-ai-chat-composer-add-background);\n  --color-ai-chat-composer-add-hover-background: var(--color-ai-chat-composer-add-hover-background);\n  --color-agent-progress-ring:                     var(--color-agent-progress-ring);\n  --color-button-ghost-background: transparent;\n  --color-button-ghost-hover: var(--color-background-primary-hover);\n  --color-button-ghost-active: var(--color-background-primary-active);\n  --color-button-ghost-disabled: transparent;\n  --color-button-ghost-foreground: var(--color-text-primary);\n  --color-button-ghost-disabled-foreground: var(--color-text-tertiary);\n  --color-dropdown-item-hover-background:        var(--color-dropdown-item-hover-background);\n  --color-kbd-background:                        var(--color-kbd-background);\n  --color-kbd-foreground:                        var(--color-kbd-foreground);\n  --color-docs-file-chip-background:             var(--color-docs-file-chip-background);\n  --color-docs-file-chip-border:                 var(--color-docs-file-chip-border);\n  --color-docs-file-chip-foreground:             var(--color-docs-file-chip-foreground);\n  --color-docs-command-accent:                    var(--color-docs-command-accent);\n  --color-docs-code-background:                   var(--color-docs-code-background);\n  --color-docs-install-rail:                      var(--color-docs-install-rail);\n  --color-badge-neutral-background: var(--color-badge-neutral-background);\n  --color-team-menu-count-background: var(--color-team-menu-count-background);\n  --color-team-menu-count-foreground: var(--color-team-menu-count-foreground);\n  --color-badge-new-background: var(--color-badge-new-background);\n  --color-badge-new-text:       var(--color-badge-new-text);\n  --color-tab-count-selected-background: var(--color-tab-count-selected-background);\n  --color-pill-tab-blue-selected-background: var(--color-pill-tab-blue-selected-background);\n  --color-pill-tab-blue-hover-background: var(--color-pill-tab-blue-hover-background);\n  --color-notification-information-background: var(--color-notification-information-background);\n  --color-notification-information-foreground: var(--color-notification-information-foreground);\n  --color-notification-success-background:     var(--color-notification-success-background);\n  --color-notification-success-foreground:     var(--color-notification-success-foreground);\n  --color-notification-error-background:       var(--color-notification-error-background);\n  --color-notification-error-foreground:       var(--color-notification-error-foreground);\n  --color-notification-center-background:      var(--color-notification-center-background);\n  --color-status-lime-background:   var(--color-status-lime-background);\n  --color-status-lime-text:         var(--color-status-lime-text);\n  --color-status-yellow-background: var(--color-status-yellow-background);\n  --color-status-yellow-text:       var(--color-status-yellow-text);\n  --color-status-rose-background:   var(--color-status-rose-background);\n  --color-status-rose-text:         var(--color-status-rose-text);\n  --color-status-cyan-background:   var(--color-status-cyan-background);\n  --color-status-cyan-text:         var(--color-status-cyan-text);\n  --color-status-blue-background:   var(--color-status-blue-background);\n  --color-status-blue-text:         var(--color-status-blue-text);\n  --color-status-purple-background: var(--color-status-purple-background);\n  --color-status-purple-text:       var(--color-status-purple-text);\n  --color-status-dot-green-halo:    var(--color-status-dot-green-halo);\n  --color-status-dot-yellow-halo:   var(--color-status-dot-yellow-halo);\n  --color-status-dot-indigo-halo:   var(--color-status-dot-indigo-halo);\n  --color-date-range-background:      var(--color-date-range-background);\n  --color-date-range-edge-background: var(--color-date-range-edge-background);\n  --color-calendar-event-blue-background:    var(--color-calendar-event-blue-background);\n  --color-calendar-event-blue-title:         var(--color-calendar-event-blue-title);\n  --color-calendar-event-blue-time:          var(--color-calendar-event-blue-time);\n  --color-calendar-event-pink-background:    var(--color-calendar-event-pink-background);\n  --color-calendar-event-pink-title:         var(--color-calendar-event-pink-title);\n  --color-calendar-event-pink-time:          var(--color-calendar-event-pink-time);\n  --color-calendar-event-purple-background:  var(--color-calendar-event-purple-background);\n  --color-calendar-event-purple-title:       var(--color-calendar-event-purple-title);\n  --color-calendar-event-purple-time:        var(--color-calendar-event-purple-time);\n  --color-calendar-event-lime-background:    var(--color-calendar-event-lime-background);\n  --color-calendar-event-lime-title:         var(--color-calendar-event-lime-title);\n  --color-calendar-event-lime-time:          var(--color-calendar-event-lime-time);\n  --color-calendar-event-emerald-background: var(--color-calendar-event-emerald-background);\n  --color-calendar-event-emerald-title:      var(--color-calendar-event-emerald-title);\n  --color-calendar-event-emerald-time:       var(--color-calendar-event-emerald-time);\n\n  --color-text-error-placeholder: var(--color-text-error-placeholder);\n\n  --color-chart-track:    var(--color-chart-track);\n  --color-chart-cursor:   var(--color-chart-cursor);\n  --color-chart-neutral:  var(--color-chart-neutral);\n  --color-chart-1:        var(--color-chart-1);\n  --color-chart-1-active: var(--color-chart-1-active);\n  --color-chart-2:        var(--color-chart-2);\n  --color-chart-2-active: var(--color-chart-2-active);\n  --color-chart-3:        var(--color-chart-3);\n  --color-chart-3-active: var(--color-chart-3-active);\n  --color-chart-4:        var(--color-chart-4);\n  --color-chart-4-active: var(--color-chart-4-active);\n  --color-chart-5:        var(--color-chart-5);\n  --color-chart-5-active: var(--color-chart-5-active);\n  --color-chart-6:        var(--color-chart-6);\n  --color-chart-6-active: var(--color-chart-6-active);\n  --color-chart-7:        var(--color-chart-7);\n  --color-chart-7-active: var(--color-chart-7-active);\n  --color-chart-8:        var(--color-chart-8);\n  --color-chart-8-active: var(--color-chart-8-active);\n  --color-chart-9:        var(--color-chart-9);\n  --color-chart-9-active: var(--color-chart-9-active);\n  --color-chart-agents-bar:        var(--color-chart-agents-bar);\n  --color-chart-agents-bar-active: var(--color-chart-agents-bar-active);\n}\n\n/* ---------------------------------------------------------------------------\n * Component utilities — Buttons\n *\n * Each variant collapses the four interactive states (default / hover / active\n * / disabled) into a single class. Use them on the component:\n *\n *   <button class=\"bg-button-primary\">…</button>\n *   <button class=\"bg-button-danger\">…</button>\n *\n * Smooth default→hover transition trick:\n *   CSS can't interpolate `background-image`, so swapping gradients on :hover\n *   would snap. Instead we keep the *default* gradient on the element and\n *   layer the *hover* gradient on a `::before` pseudo-element whose opacity\n *   fades 0→1 over `--button-transition-ms`. Active/disabled gradients still\n *   swap instantly (we hide the pseudo to reveal them).\n *\n * Stacking: `isolation: isolate` keeps the pseudo behind the button's text\n * and icons (z-index -1) while staying above the element's own background.\n * `border-radius: inherit` + `overflow: hidden` keeps it within the rounded\n * corners.\n * --------------------------------------------------------------------------- */\n@theme {\n  --button-transition-ms: 150ms;\n  --input-transition-ms:  150ms;\n}\n\n/* Keep color feedback quick while the physical press motion remains soft.\n * The transform uses a shorter duration on press and the slower duration only\n * when returning to rest, so hover styles never inherit the 700ms timing. */\n@utility button-press-motion {\n  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, opacity 150ms ease;\n  @media (prefers-reduced-motion: reduce) { transition: none; }\n}\n\n@utility bg-button-primary {\n  background: var(--color-text-primary);\n  color: var(--color-background-primary-default);\n  &:hover:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .88; }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) { opacity: .78; }\n  &:disabled, &[aria-disabled=\"true\"] { background: var(--color-background-primary-disabled); color: var(--color-text-tertiary); }\n}\n\n@utility bg-button-danger {\n  position: relative;\n  isolation: isolate;\n  background-image: var(--gradient-button-danger-default);\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    border-radius: inherit;\n    background-image: var(--gradient-button-danger-hover);\n    opacity: 0;\n    transition: opacity var(--button-transition-ms) ease;\n  }\n  &:hover:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 1;\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"]) {\n    background-image: var(--gradient-button-danger-active);\n  }\n  &:active:not(:disabled):not([aria-disabled=\"true\"])::before {\n    opacity: 0;\n  }\n  &:disabled,\n  &[aria-disabled=\"true\"] {\n    background-image: var(--gradient-button-danger-disabled);\n  }\n  &:disabled::before,\n  &[aria-disabled=\"true\"]::before {\n    display: none;\n  }\n}\n"
        },
        {
          "path": "components/boardui/styles/typography.css",
          "target": "@components/boardui/styles/typography.css",
          "type": "registry:file",
          "content": "/* ---------------------------------------------------------------------------\n * BoardUI typography\n *\n * Type ramp from Figma → text styles. Each style registers a Tailwind v4\n * text utility — `text-{name}` applies font-size + line-height + letter-spacing\n * + font-weight in one go.\n *\n * Family: Inter for the whole ramp. (The Figma export marks Large Title /\n * Regular as \"Inter Display\"; we map everything to Inter for consistency since\n * Inter ships a variable optical-size axis. Flag if a true Inter Display load\n * is needed.)\n *\n * Weight mapping (mirrors Figma variables — font/weight/*):\n *   Regular   = 400\n *   Medium    = 500\n *   Semibold  = 600  (Figma variable font/weight/semibold = 600)\n *   Bold      = 700\n *\n * Naming: `<family>-<weight>` in lowercase kebab — e.g. `text-body-medium`,\n * `text-title-1-semibold`, `text-caption-2-bold`.\n * --------------------------------------------------------------------------- */\n\n@theme {\n  /* ===== Large Title — 64 / 80 ============================================= */\n  --text-large-title-regular: 4rem;\n  --text-large-title-regular--line-height: 5rem;\n  --text-large-title-regular--letter-spacing: 0;\n  --text-large-title-regular--font-weight: 400;\n  --text-large-title-medium: 4rem;\n  --text-large-title-medium--line-height: 5rem;\n  --text-large-title-medium--letter-spacing: 0;\n  --text-large-title-medium--font-weight: 500;\n  --text-large-title-semibold: 4rem;\n  --text-large-title-semibold--line-height: 5rem;\n  --text-large-title-semibold--letter-spacing: 0;\n  --text-large-title-semibold--font-weight: 600;\n  --text-large-title-bold: 4rem;\n  --text-large-title-bold--line-height: 5rem;\n  --text-large-title-bold--letter-spacing: 0;\n  --text-large-title-bold--font-weight: 700;\n\n  /* ===== Display 1 — 56 / 72 =============================================== */\n  --text-display-1-regular: 3.5rem;\n  --text-display-1-regular--line-height: 4.5rem;\n  --text-display-1-regular--letter-spacing: 0;\n  --text-display-1-regular--font-weight: 400;\n  --text-display-1-medium: 3.5rem;\n  --text-display-1-medium--line-height: 4.5rem;\n  --text-display-1-medium--letter-spacing: 0;\n  --text-display-1-medium--font-weight: 500;\n  --text-display-1-semibold: 3.5rem;\n  --text-display-1-semibold--line-height: 4.5rem;\n  --text-display-1-semibold--letter-spacing: 0;\n  --text-display-1-semibold--font-weight: 600;\n  --text-display-1-bold: 3.5rem;\n  --text-display-1-bold--line-height: 4.5rem;\n  --text-display-1-bold--letter-spacing: 0;\n  --text-display-1-bold--font-weight: 700;\n\n  /* ===== Display 2 — 48 / 64 =============================================== */\n  --text-display-2-regular: 3rem;\n  --text-display-2-regular--line-height: 4rem;\n  --text-display-2-regular--letter-spacing: 0;\n  --text-display-2-regular--font-weight: 400;\n  --text-display-2-medium: 3rem;\n  --text-display-2-medium--line-height: 4rem;\n  --text-display-2-medium--letter-spacing: 0;\n  --text-display-2-medium--font-weight: 500;\n  --text-display-2-semibold: 3rem;\n  --text-display-2-semibold--line-height: 4rem;\n  --text-display-2-semibold--letter-spacing: 0;\n  --text-display-2-semibold--font-weight: 600;\n  --text-display-2-bold: 3rem;\n  --text-display-2-bold--line-height: 4rem;\n  --text-display-2-bold--letter-spacing: 0;\n  --text-display-2-bold--font-weight: 700;\n\n  /* ===== Display 3 — 40 / 54 =============================================== */\n  --text-display-3-regular: 2.5rem;\n  --text-display-3-regular--line-height: 3.375rem;\n  --text-display-3-regular--letter-spacing: 0;\n  --text-display-3-regular--font-weight: 400;\n  --text-display-3-medium: 2.5rem;\n  --text-display-3-medium--line-height: 3.375rem;\n  --text-display-3-medium--letter-spacing: 0;\n  --text-display-3-medium--font-weight: 500;\n  --text-display-3-semibold: 2.5rem;\n  --text-display-3-semibold--line-height: 3.375rem;\n  --text-display-3-semibold--letter-spacing: 0;\n  --text-display-3-semibold--font-weight: 600;\n  --text-display-3-bold: 2.5rem;\n  --text-display-3-bold--line-height: 3.375rem;\n  --text-display-3-bold--letter-spacing: 0;\n  --text-display-3-bold--font-weight: 700;\n\n  /* ===== Display 4 — 32 / 44 =============================================== */\n  --text-display-4-regular: 2rem;\n  --text-display-4-regular--line-height: 2.75rem;\n  --text-display-4-regular--letter-spacing: 0;\n  --text-display-4-regular--font-weight: 400;\n  --text-display-4-medium: 2rem;\n  --text-display-4-medium--line-height: 2.75rem;\n  --text-display-4-medium--letter-spacing: 0;\n  --text-display-4-medium--font-weight: 500;\n  --text-display-4-semibold: 2rem;\n  --text-display-4-semibold--line-height: 2.75rem;\n  --text-display-4-semibold--letter-spacing: 0;\n  --text-display-4-semibold--font-weight: 600;\n  --text-display-4-bold: 2rem;\n  --text-display-4-bold--line-height: 2.75rem;\n  --text-display-4-bold--letter-spacing: 0;\n  --text-display-4-bold--font-weight: 700;\n\n  /* ===== Title 1 — 24 / 34 ================================================= */\n  --text-title-1-regular: 1.5rem;\n  --text-title-1-regular--line-height: 2.125rem;\n  --text-title-1-regular--letter-spacing: 0;\n  --text-title-1-regular--font-weight: 400;\n  --text-title-1-medium: 1.5rem;\n  --text-title-1-medium--line-height: 2.125rem;\n  --text-title-1-medium--letter-spacing: 0;\n  --text-title-1-medium--font-weight: 500;\n  --text-title-1-semibold: 1.5rem;\n  --text-title-1-semibold--line-height: 2.125rem;\n  --text-title-1-semibold--letter-spacing: 0;\n  --text-title-1-semibold--font-weight: 600;\n  --text-title-1-bold: 1.5rem;\n  --text-title-1-bold--line-height: 2.125rem;\n  --text-title-1-bold--letter-spacing: 0;\n  --text-title-1-bold--font-weight: 700;\n\n  /* ===== Title 2 — 20 / 26 ================================================= */\n  --text-title-2-regular: 1.25rem;\n  --text-title-2-regular--line-height: 1.625rem;\n  --text-title-2-regular--letter-spacing: 0;\n  --text-title-2-regular--font-weight: 400;\n  --text-title-2-medium: 1.25rem;\n  --text-title-2-medium--line-height: 1.625rem;\n  --text-title-2-medium--letter-spacing: 0;\n  --text-title-2-medium--font-weight: 500;\n  --text-title-2-semibold: 1.25rem;\n  --text-title-2-semibold--line-height: 1.625rem;\n  --text-title-2-semibold--letter-spacing: 0;\n  --text-title-2-semibold--font-weight: 600;\n  --text-title-2-bold: 1.25rem;\n  --text-title-2-bold--line-height: 1.625rem;\n  --text-title-2-bold--letter-spacing: 0;\n  --text-title-2-bold--font-weight: 700;\n\n  /* ===== Title 3 — 18 / 24-26 ============================================== */\n  --text-title-3-regular: 1.125rem;\n  --text-title-3-regular--line-height: 1.5rem;     /* 24 per Figma */\n  --text-title-3-regular--letter-spacing: 0;\n  --text-title-3-regular--font-weight: 400;\n  --text-title-3-medium: 1.125rem;\n  --text-title-3-medium--line-height: 1.625rem;    /* 26 per Figma */\n  --text-title-3-medium--letter-spacing: 0;\n  --text-title-3-medium--font-weight: 500;\n  --text-title-3-semibold: 1.125rem;\n  --text-title-3-semibold--line-height: 1.625rem;\n  --text-title-3-semibold--letter-spacing: 0;\n  --text-title-3-semibold--font-weight: 600;\n  --text-title-3-bold: 1.125rem;\n  --text-title-3-bold--line-height: 1.625rem;\n  --text-title-3-bold--letter-spacing: 0;\n  --text-title-3-bold--font-weight: 700;\n\n  /* ===== Headline — 16 / 22 ================================================ */\n  --text-headline-regular: 1rem;\n  --text-headline-regular--line-height: 1.375rem;\n  --text-headline-regular--letter-spacing: 0;\n  --text-headline-regular--font-weight: 400;\n  --text-headline-medium: 1rem;\n  --text-headline-medium--line-height: 1.375rem;\n  --text-headline-medium--letter-spacing: 0;\n  --text-headline-medium--font-weight: 500;\n  --text-headline-semibold: 1rem;\n  --text-headline-semibold--line-height: 1.375rem;\n  --text-headline-semibold--letter-spacing: 0;\n  --text-headline-semibold--font-weight: 600;\n  --text-headline-bold: 1rem;\n  --text-headline-bold--line-height: 1.375rem;\n  --text-headline-bold--letter-spacing: 0;\n  --text-headline-bold--font-weight: 700;\n\n  /* ===== Body — 14 / 20 ==================================================== */\n  --text-body-regular: 0.875rem;\n  --text-body-regular--line-height: 1.25rem;\n  --text-body-regular--letter-spacing: 0;\n  --text-body-regular--font-weight: 400;\n  --text-body-medium: 0.875rem;\n  --text-body-medium--line-height: 1.25rem;\n  --text-body-medium--letter-spacing: 0;\n  --text-body-medium--font-weight: 500;\n  --text-body-semibold: 0.875rem;\n  --text-body-semibold--line-height: 1.25rem;\n  --text-body-semibold--letter-spacing: 0;\n  --text-body-semibold--font-weight: 600;\n  --text-body-bold: 0.875rem;\n  --text-body-bold--line-height: 1.25rem;\n  --text-body-bold--letter-spacing: 0;\n  --text-body-bold--font-weight: 700;\n\n  /* ===== Body 2 — 13 / 18 ================================================== */\n  --text-body-2-regular: 0.8125rem;\n  --text-body-2-regular--line-height: 1.125rem;\n  --text-body-2-regular--letter-spacing: 0;\n  --text-body-2-regular--font-weight: 400;\n  --text-body-2-medium: 0.8125rem;\n  --text-body-2-medium--line-height: 1.125rem;\n  --text-body-2-medium--letter-spacing: 0;\n  --text-body-2-medium--font-weight: 500;\n  --text-body-2-semibold: 0.8125rem;\n  --text-body-2-semibold--line-height: 1.125rem;\n  --text-body-2-semibold--letter-spacing: 0;\n  --text-body-2-semibold--font-weight: 600;\n  --text-body-2-bold: 0.8125rem;\n  --text-body-2-bold--line-height: 1.125rem;\n  --text-body-2-bold--letter-spacing: 0;\n  --text-body-2-bold--font-weight: 700;\n\n  /* ===== Caption 1 — 12 / 16 (tracking 0.15) =============================== */\n  --text-caption-1-regular: 0.75rem;\n  --text-caption-1-regular--line-height: 1rem;\n  --text-caption-1-regular--letter-spacing: 0.15px;\n  --text-caption-1-regular--font-weight: 400;\n  --text-caption-1-medium: 0.75rem;\n  --text-caption-1-medium--line-height: 1rem;\n  --text-caption-1-medium--letter-spacing: 0.15px;\n  --text-caption-1-medium--font-weight: 500;\n  --text-caption-1-semibold: 0.75rem;\n  --text-caption-1-semibold--line-height: 1rem;\n  --text-caption-1-semibold--letter-spacing: 0.15px;\n  --text-caption-1-semibold--font-weight: 600;\n  --text-caption-1-bold: 0.75rem;\n  --text-caption-1-bold--line-height: 1rem;\n  --text-caption-1-bold--letter-spacing: 0.15px;\n  --text-caption-1-bold--font-weight: 700;\n\n  /* ===== Caption 2 — 11 / 15 (tracking 0.2) ================================ */\n  --text-caption-2-regular: 0.6875rem;\n  --text-caption-2-regular--line-height: 0.9375rem;\n  --text-caption-2-regular--letter-spacing: 0.2px;\n  --text-caption-2-regular--font-weight: 400;\n  --text-caption-2-medium: 0.6875rem;\n  --text-caption-2-medium--line-height: 0.9375rem;\n  --text-caption-2-medium--letter-spacing: 0.2px;\n  --text-caption-2-medium--font-weight: 500;\n  --text-caption-2-semibold: 0.6875rem;\n  --text-caption-2-semibold--line-height: 0.9375rem;\n  --text-caption-2-semibold--letter-spacing: 0.2px;\n  --text-caption-2-semibold--font-weight: 600;\n  --text-caption-2-bold: 0.6875rem;\n  --text-caption-2-bold--line-height: 0.9375rem;\n  --text-caption-2-bold--letter-spacing: 0.2px;\n  --text-caption-2-bold--font-weight: 700;\n}\n"
        },
        {
          "path": "components/boardui/SOURCE.json",
          "target": "@components/boardui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"source\": \"https://github.com/BoardUI/boardui\",\n  \"revision\": \"3e76e282614b147a34b9b2a510e31b97d58a3909\",\n  \"license\": \"MIT\",\n  \"scope\": [\n    \"components/application/agent-chat\",\n    \"components/application/agent-thinking\",\n    \"components/application/composer-loader\",\n    \"components/base\",\n    \"components/foundations\",\n    \"styles\",\n    \"utils\"\n  ],\n  \"adaptations\": [\n    \"Repository import paths point to components/boardui\",\n    \"Neutral primary and ghost actions, restrained feedback, and readable agent surface tokens\",\n    \"Focusable native actions support React Aria tooltip composition\",\n    \"Icon-only child SVG fallback preserves explicit leadingIcon precedence\",\n    \"The Agent Chat starter always uses the bundled local demo transport; API probing, provider keys, dashboard navigation, and Pro promotion are omitted\",\n    \"Agent Chat imports resolve through components/boardui and its account logout action closes the local menu instead of navigating to a starter-only route\",\n    \"The gallery chat uses a responsive history drawer below xl; selecting a thread, clicking outside, or pressing Escape closes it\",\n    \"The prior pinned base components are unchanged at the current revision\"\n  ]\n}\n"
        },
        {
          "path": "styles/animations.css",
          "target": "~/styles/animations.css",
          "type": "registry:file",
          "content": "@import \"tw-animate-css\";\n"
        },
        {
          "path": "components/beautiful-ui/SOURCE.json",
          "target": "@components/beautiful-ui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"Beautiful UI\",\n  \"repository\": \"https://github.com/slev12397/beautiful-ui\",\n  \"revision\": \"ff0f74d62d8be9d89bcb735b3632e31a6ccf88dc\",\n  \"license\": \"MIT\",\n  \"copyright\": \"Copyright (c) 2026 Shane Levine\",\n  \"families\": 21,\n  \"adaptation\": \"Original primitives and internal building blocks retain their APIs and interactions. The gallery uses Agents Kit fixtures; Beautiful UI theme utilities compile through the main Tailwind stylesheet. Shared semantic colors, readable tertiary text, neutral focus, and Inter/JetBrains Mono typography follow the Agents Kit design contract. Proprietary Iconists icons use Lucide equivalents. Existing root adapters remain available. Selection Actions uses a contained two-row toolbar on narrow hosts, while retaining the desktop floating toolbar.\"\n}\n"
        },
        {
          "path": "components/beui/LICENSE",
          "target": "@components/beui/LICENSE",
          "type": "registry:file",
          "content": "MIT License\n\nCopyright (c) 2026 Saurabh Chauhan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
        },
        {
          "path": "components/beui/SOURCE.json",
          "target": "@components/beui/SOURCE.json",
          "type": "registry:file",
          "content": "{\n  \"name\": \"beUI AI Agents\",\n  \"upstream\": \"https://github.com/starc007/ui-components\",\n  \"revision\": \"b64c092b63b99c7340376b522325ea309156ba00\",\n  \"revisionUrl\": \"https://github.com/starc007/ui-components/tree/b64c092b63b99c7340376b522325ea309156ba00\",\n  \"license\": \"MIT\",\n  \"scope\": \"Exact public dependency closure for all 16 AI agent registry entries and all 28 documented demos at the pinned revision.\",\n  \"adaptation\": \"Import aliases point at the isolated components/beui tree so the public source remains portable in Agents Kit. Gallery fixtures preserve the upstream interactions and motion while using local Fieldwork copy. Class-only adaptations align ordinary cards, controls, and app windows with the shared Agents Kit radius scale while preserving component APIs, message bubbles, status pills, media, semantic colors, and motion.\"\n}\n"
        }
      ],
      "categories": [
        "beUI"
      ]
    }
  ]
}
